From a81c9d9258b1c5c1b3fa2bcedebff36d2f10ac2a Mon Sep 17 00:00:00 2001 From: gitlost Date: Tue, 23 Jun 2026 23:25:23 +0100 Subject: [PATCH] CLI: make `--mirror` available in standard non-batch mode via new routines `mirror_start()`, `mirror_outfile()` & limit substitutions on Unix to backslash (Windows remains the same); restrict "borderwidth", "textgap", "vwhitesp", "whitesp" < 100 CODEONE: fix `ceilf()` -> `C1_MULT_CEIL()` in FAST_MODE encodation (improves/changes some encodation) composite: preserve `gs1_verify()` warning using `warn_level` hack; fix wrong name `zint_dbar_omnstk_set_height()` -> `zint_dbar_stk_set_height()`; use new `zint_micropdf_variant()` & `zint_micropdf_expand()` routines (see below) MICROPDF417: move variant determination into new shareable routine `zint_micropdf_variant()` & expansion into `zint_micropdf_expand()` qzint: add helper methods `setbordertypevalue()`, `encodedinputmode()`, `encodedoutputoptions()`, `ecivaluetoeciindex()` and `eciindextoecivalue()` dbar: for performance pre-calculate `combins()` as array coverage: add `malloc()`-type failure testing to AZTEC, CONTENT_SEGS, MEMORY_FILE, raster, Reed-Solomon & vector; numerous changes to remove unused code and test more branches common: add `isxdigit()` general: various code fiddlings manual: add char names to sequence and batch format char tables; mention long options can be shortened (& use "--compliantheight" -> "--compliant"); expand mirror explanation & document substitutions in footnote; workaround xecjk putting space after double quote when quoting cjk chars & rejig input mode examples; workaround html alignment bug in table gs1-enabled symbologies by adding extra rh dashes to header cols; add "figure nn: " to txt image tags via sed: various other small fixes and rephrasings --- ChangeLog | 6 +- backend/aztec.c | 137 +- backend/aztec.h | 2 +- backend/aztec_trace.h | 12 +- backend/code.c | 6 +- backend/code1.c | 34 +- backend/common.c | 24 +- backend/common.h | 19 +- backend/composite.c | 465 ++---- backend/composite.h | 22 +- backend/dotcode.c | 22 +- backend/eci.c | 25 +- backend/filemem.c | 79 +- backend/filemem.h | 19 + backend/gif.c | 15 +- backend/gridmtx.c | 94 +- backend/gridmtx.h | 191 +-- backend/gs1.c | 120 +- backend/hanxin.c | 4 +- backend/library.c | 107 +- backend/output.c | 8 +- backend/output.h | 2 +- backend/pdf417.c | 399 +++-- backend/pdf417.h | 11 +- backend/pdf417_tabs.h | 26 +- backend/png.c | 59 +- backend/ps.c | 29 +- backend/qr.c | 6 +- backend/raster.c | 71 +- backend/reedsol.c | 18 +- backend/reedsol.h | 7 + backend/rss.c | 68 +- backend/svg.c | 25 +- backend/tests/data/gif/ultra_box.gif | Bin 0 -> 239 bytes .../png/telepen_compliant_dpmm_300dpi.png | Bin 0 -> 219 bytes backend/tests/data/tif/code32_dpmm_200dpi.tif | Bin 0 -> 698 bytes backend/tests/test_aztec.c | 135 +- backend/tests/test_bmp.c | 66 +- backend/tests/test_code1.c | 198 ++- backend/tests/test_code128.c | 69 +- backend/tests/test_code16k.c | 100 +- backend/tests/test_common.c | 68 +- backend/tests/test_composite.c | 309 ++-- backend/tests/test_eci.c | 8 + backend/tests/test_emf.c | 63 +- backend/tests/test_filemem.c | 164 +- backend/tests/test_gif.c | 67 +- backend/tests/test_gridmtx.c | 110 +- backend/tests/test_gs1.c | 547 +++---- backend/tests/test_library.c | 939 +++++++----- backend/tests/test_maxicode.c | 131 +- backend/tests/test_output.c | 184 ++- backend/tests/test_pcx.c | 62 +- backend/tests/test_pdf417.c | 28 +- backend/tests/test_png.c | 374 +++-- backend/tests/test_ps.c | 63 +- backend/tests/test_qr.c | 3 + backend/tests/test_random.c | 2 +- backend/tests/test_raster.c | 125 ++ backend/tests/test_reedsol.c | 51 +- backend/tests/test_rss.c | 478 +++--- backend/tests/test_svg.c | 103 +- backend/tests/test_telepen.c | 19 +- backend/tests/test_tif.c | 136 +- backend/tests/test_upcean.c | 4 +- backend/tests/test_vector.c | 86 ++ backend/tests/testcommon.c | 30 +- backend/tests/testcommon.h | 2 + backend/tests/tools/bwipp_dump.ps.tar.xz | Bin 162872 -> 162940 bytes backend/tests/tools/run_coverage.sh | 78 + backend/tif.c | 22 +- backend/ultra.c | 130 +- backend/upcean.c | 23 +- backend/vector.c | 69 +- backend/zint.h | 6 +- backend_qt/qzint.cpp | 195 ++- backend_qt/qzint.h | 11 +- backend_qt/tests/test_qzint.cpp | 366 ++++- docs/Makefile | 6 +- docs/images/datamatrix_big5.svg | 2 +- docs/images/gui_aztec.png | Bin 249701 -> 263104 bytes docs/images/qrcode_binary_utf8.svg | 2 +- docs/inc_header_pdf.tex | 4 + docs/manual.html | 1360 +++++++++-------- docs/manual.pmd | 406 ++--- docs/manual.txt | 490 +++--- docs/zint.1 | 5 +- docs/zint.1.pmd | 5 +- docs/zint_images.sh | 132 +- frontend/main.c | 534 +++++-- frontend/tests/test_args.c | 545 ++++--- 91 files changed, 6879 insertions(+), 4368 deletions(-) create mode 100644 backend/tests/data/gif/ultra_box.gif create mode 100644 backend/tests/data/png/telepen_compliant_dpmm_300dpi.png create mode 100644 backend/tests/data/tif/code32_dpmm_200dpi.tif create mode 100755 backend/tests/tools/run_coverage.sh diff --git a/ChangeLog b/ChangeLog index 2cd97934..f1b718df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -Version 2.16.0.9 (dev) not released yet (2026-05-26) +Version 2.16.0.9 (dev) not released yet (2026-06-23) ==================================================== **Incompatible changes** @@ -11,6 +11,8 @@ Version 2.16.0.9 (dev) not released yet (2026-05-26) - New Qt Backend method `save_as_memfile()` to save file to memory - New Qt Backend methods `gs1Raw()` and `setGS1Raw()` for new `GS1RAW_MODE` option for processing GS1 input +- New Qt Backend helper methods `setBorderTypeValue()`, `encodedInputMode()`, + `encodedOutputOptions()`, `ECIValueToECIIndex()` and `ECIIndexToECIValue()` - CLI now warns if both "--dmre" and "--square" are given (previously silently ignored "--dmre") - New escape sequences `\L` (DLE), `\F` (FS), `\N` (US) @@ -22,6 +24,7 @@ Changes creating temporary file - CLI: allow "tiff" as filetype (saved as ".tif"); make args for "--scalexdimdp" and "--scmvv" optional; + make "--mirror" available in standard non-batch mode; add `ZINT_TEST`-only "--test" option to do various internal tests - GS1SE: exclude GS1_128 from requisite AIs check as may be spread across more than one barcode (ticket #348, props Harald Oehlmann and Terry Burton) @@ -71,6 +74,7 @@ Bugs - ZBarcode_Encode_Segs: allow for multiple (stacked) rows when setting absolute minimum height - CLI: stop looping over data args when have error +- composite: preserve `gs1_verify()` warning (if any) Version 2.16.0 (2025-12-19) diff --git a/backend/aztec.c b/backend/aztec.c index 00df7ec1..8015691a 100644 --- a/backend/aztec.c +++ b/backend/aztec.c @@ -46,6 +46,29 @@ #define AZ_BIN_CAP_CWDS_S "1661" /* String version of (AZTEC_BIN_CAPACITY / 12) */ +#ifdef ZINT_TEST +/* For testing `malloc()`/`realloc()` failures */ +static int az_fail_id = 0; +static int az_fail_at = 0; + +INTERNAL void zint_test_az_set_fail(const int id, const int at) { + az_fail_id = id; + az_fail_at = at; +} + +/* TODO: put these in "aztec.h" (& rename existing "aztec.h" to "aztec_tabs.h" */ +#define AZ_FAIL_ID_LIST_INIT 1 +#define AZ_FAIL_ID_CPY 2 +#define AZ_FAIL_ID_ADD_CHK 3 +#define AZ_FAIL_ID_LIST_ADD_CHK 4 + +#define az_malloc(id, sz) (az_fail_at > 0 && az_fail_id == (id) && --az_fail_at == 0 ? NULL : malloc(sz)) +#define az_realloc(id, ptr, sz) (az_fail_at > 0 && az_fail_id == (id) && --az_fail_at == 0 ? NULL : realloc(ptr, sz)) +#else +#define az_malloc(id, sz) malloc(sz) +#define az_realloc(id, ptr, sz) realloc(ptr, sz) +#endif + /* Count number of consecutive (. SP) or (, SP) Punct mode doubles for comparison against Digit mode encoding */ static int az_count_doubles(const unsigned char source[], const int length, const int position) { int i; @@ -455,7 +478,7 @@ struct az_state_list { static int az_state_list_init(struct az_state_list *list, const unsigned short initial_size) { const unsigned short size = initial_size < AZ_MIN_STATES_SIZE ? AZ_MIN_STATES_SIZE : initial_size; - if (!(list->states = (struct az_state *) malloc(sizeof(struct az_state) * size))) { + if (!(list->states = (struct az_state *) az_malloc(AZ_FAIL_ID_LIST_INIT, sizeof(struct az_state) * size))) { list->used = list->size = 0; return 0; } @@ -469,7 +492,7 @@ static int az_state_cpy(const struct az_state *src, struct az_state *dst) { const unsigned short size = src->tokens.size < AZ_MIN_TOKENS_SIZE ? AZ_MIN_TOKENS_SIZE : src->tokens.size; *dst = *src; - if (!(dst->tokens.tokens = (struct az_token *) malloc(sizeof(struct az_token) * size))) { + if (!(dst->tokens.tokens = (struct az_token *) az_malloc(AZ_FAIL_ID_CPY, sizeof(struct az_token) * size))) { return 0; } if (src->tokens.used) { @@ -490,18 +513,13 @@ static void az_state_free(struct az_state *state) { /* Check that there's enough room for `extra` more tokens in `state` */ static int az_tokens_add_chk(struct az_state *state, const int extra) { assert(extra > 0 && extra < AZ_MIN_TOKENS_SIZE); - if (!state->tokens.tokens) { - const unsigned short size = AZ_MIN_TOKENS_SIZE; - if (!(state->tokens.tokens = (struct az_token *) malloc(sizeof(struct az_token) * size))) { - return 0; - } - state->tokens.size = size; - state->tokens.used = 0; - } else if (state->tokens.used >= state->tokens.size - extra) { /* Compare this way to avoid possible overflow */ + assert(state->tokens.tokens); /* Always called only after a successful `az_state_cpy()` */ + if (state->tokens.used >= state->tokens.size - extra) { /* Compare this way to avoid possible overflow */ struct az_token *tokens; const unsigned short size = state->tokens.size * 2; if (size <= state->tokens.size /* Overflow */ - || !(tokens = (struct az_token *) realloc(state->tokens.tokens, sizeof(struct az_token) * size))) { + || !(tokens = (struct az_token *) az_realloc(AZ_FAIL_ID_ADD_CHK, state->tokens.tokens, + sizeof(struct az_token) * size))) { return 0; } assert(size > state->tokens.used + extra); @@ -517,7 +535,8 @@ static int az_state_list_add_chk(struct az_state_list *list) { struct az_state *states; const unsigned short size = list->size * 2; if (size <= list->size /* Overflow */ - || !(states = (struct az_state *) realloc(list->states, sizeof(struct az_state) * size))) { + || !(states = (struct az_state *) az_realloc(AZ_FAIL_ID_LIST_ADD_CHK, list->states, + sizeof(struct az_state) * size))) { return 0; } list->states = states; @@ -526,8 +545,8 @@ static int az_state_list_add_chk(struct az_state_list *list) { return 1; } -/* Free all states (including their tokens) of state list `list` */ -static void az_state_list_free(struct az_state_list *list) { +/* Free all states (including their tokens) of state list `list` - returns 0 for convenience */ +static int az_state_list_free(struct az_state_list *list) { int i; if (list->states) { for (i = 0; i < list->used; i++) { @@ -539,6 +558,7 @@ static void az_state_list_free(struct az_state_list *list) { list->states = NULL; } list->used = list->size = 0; + return 0; } #define AZ_FNC1_VAL 32 /* Pseudo-value for FNC1 - converted to 0 on setting token value */ @@ -919,13 +939,12 @@ static int az_UpdateStateListForPair(struct az_state_list *list, const int from, } for (i = 0; i < list->used; i++) { if (!az_UpdateStateForPair(list->states + i, from, pairCode, ret_list)) { - az_state_list_free(ret_list); - return 0; + return az_state_list_free(ret_list); /* Returns 0 */ } } az_SimplifyStates(ret_list); - az_state_list_free(list); + (void) az_state_list_free(list); list->states = ret_list->states; list->size = ret_list->size; list->used = ret_list->used; @@ -945,15 +964,14 @@ static int az_UpdateStateListForChar(struct az_state_list *list, const unsigned } for (i = 0; i < list->used; i++) { if (!az_UpdateStateForChar(list->states + i, source, from, fnc1_if_gs, ret_list)) { - az_state_list_free(ret_list); - return 0; + return az_state_list_free(ret_list); /* Returns 0 */ } } if (ret_list->used > 1) { az_SimplifyStates(ret_list); } - az_state_list_free(list); + (void) az_state_list_free(list); list->states = ret_list->states; list->size = ret_list->size; list->used = ret_list->used; @@ -995,14 +1013,12 @@ static int az_binary_string(const unsigned char source[], const int length, int /* (CR LF) -> 2, (. SP) -> 3, (, SP) -> 4, (: SP) -> 5 */ const int pairCode = source[i] == '\r' ? 2 : 3 + 7 - ((source[i] & 0x0F) >> 1); if (!az_UpdateStateListForPair(list, i, pairCode)) { - az_state_list_free(list); - return 0; + return az_state_list_free(list); /* Returns 0 */ } i++; } else { if (!az_UpdateStateListForChar(list, source, i, fncs[i])) { - az_state_list_free(list); - return 0; + return az_state_list_free(list); /* Returns 0 */ } } } @@ -1018,13 +1034,12 @@ static int az_binary_string(const unsigned char source[], const int length, int if (!az_EndByteShift(list->states + minStateIdx, &stateEnd, length)) { az_state_free(&stateEnd); - az_state_list_free(list); - return 0; + return az_state_list_free(list); /* Returns 0 */ } if (stateEnd.bitCount > AZTEC_BIN_CAPACITY) { az_state_free(&stateEnd); - az_state_list_free(list); + (void) az_state_list_free(list); return stateEnd.bitCount; } @@ -1055,7 +1070,7 @@ static int az_binary_string(const unsigned char source[], const int length, int *p_current_mode = stateEnd.mode; az_state_free(&stateEnd); - az_state_list_free(list); + (void) az_state_list_free(list); return bp; } @@ -1586,7 +1601,7 @@ static int az_codeword_size(const int layers) { /* Encodes Aztec Code as specified in ISO/IEC 24778:2008 */ INTERNAL int zint_aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { - int x, y, i, p, data_blocks, ecc_blocks, layers, total_bits; + int x, y, i, p, num_data_cws, num_ecc_cws, layers, total_bits; char bit_pattern[AZTEC_MAP_POSN_MAX + 1]; /* Note AZTEC_MAP_POSN_MAX > AZTEC_BIN_CAPACITY */ /* To lessen stack usage, share binary_string buffer with bit_pattern, as accessed separately */ char *binary_string = bit_pattern; @@ -1693,7 +1708,7 @@ INTERNAL int zint_aztec(struct zint_symbol *symbol, struct zint_seg segs[], cons if (symbol->option_1 < -1 || symbol->option_1 > 4) { z_errtxtf(0, symbol, 503, "Error correction level '%d' out of range (1 to 4)", symbol->option_1); - if (symbol->warn_level == WARN_FAIL_ALL) { + if ((symbol->warn_level & 0xFF) == WARN_FAIL_ALL) { return ZINT_ERROR_INVALID_OPTION; } error_number = z_errtxt_adj(ZINT_WARN_INVALID_OPTION, symbol, "%1$s%2$s", ", ignoring"); @@ -1839,26 +1854,26 @@ INTERNAL int zint_aztec(struct zint_symbol *symbol, struct zint_seg segs[], cons "Input too long for Reader Initialisation, requires %d layers (maximum 22)", layers); } - data_blocks = adjusted_length / codeword_size; + num_data_cws = adjusted_length / codeword_size; if (compact) { - ecc_blocks = AztecCompactSizes[layers - 1] - data_blocks; - if (layers == 4) { /* Can use spare blocks for ECC (76 available - 64 max data blocks) */ - ecc_blocks += 12; + num_ecc_cws = AztecCompactSizes[layers - 1] - num_data_cws; + if (layers == 4) { /* Can use spare codewords for ECC (76 available - 64 max data codewords) */ + num_ecc_cws += 12; } } else { - ecc_blocks = AztecSizes[layers - 1] - data_blocks; + num_ecc_cws = AztecSizes[layers - 1] - num_data_cws; } - if (ecc_blocks == 3) { + if (num_ecc_cws == 3) { ecc_ratio = 0.0f; error_number = z_errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 706, "Number of ECC codewords 3 at minimum"); symbol->option_1 = -1; /* Feedback options: indicate minimum 3 with -1 */ } else { - ecc_ratio = z_stripf((float) (ecc_blocks - 3) / (data_blocks + ecc_blocks)); + ecc_ratio = z_stripf((float) (num_ecc_cws - 3) / (num_data_cws + num_ecc_cws)); if (ecc_ratio < 0.05f) { error_number = ZEXT z_errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 708, "Number of ECC codewords %1$d less than 5%% + 3 of data codewords %2$d", - ecc_blocks, data_blocks); + num_ecc_cws, num_data_cws); symbol->option_1 = 0; /* Feedback options: indicate < 5% + 3 with 0 */ } else { /* Feedback options: 0.165 = (.1 + .23) / 2 etc */ @@ -1868,15 +1883,15 @@ INTERNAL int zint_aztec(struct zint_symbol *symbol, struct zint_seg segs[], cons symbol->option_1 |= ((int) z_stripf(ecc_ratio * 100.0f)) << 8; } - data_part = (unsigned int *) z_alloca(sizeof(unsigned int) * data_blocks); - ecc_part = (unsigned int *) z_alloca(sizeof(unsigned int) * ecc_blocks); + data_part = (unsigned int *) z_alloca(sizeof(unsigned int) * num_data_cws); + ecc_part = (unsigned int *) z_alloca(sizeof(unsigned int) * num_ecc_cws); /* Copy across data into separate integers */ - memset(data_part, 0, sizeof(unsigned int) * data_blocks); - memset(ecc_part, 0, sizeof(unsigned int) * ecc_blocks); + memset(data_part, 0, sizeof(unsigned int) * num_data_cws); + memset(ecc_part, 0, sizeof(unsigned int) * num_ecc_cws); /* Split into codewords and calculate reed-solomon error correction codes */ - for (i = 0; i < data_blocks; i++) { + for (i = 0; i < num_data_cws; i++) { for (p = 0; p < codeword_size; p++) { if (adjusted_string[i * codeword_size + p] == '1') { data_part[i] |= 0x01 << (codeword_size - (p + 1)); @@ -1887,40 +1902,40 @@ INTERNAL int zint_aztec(struct zint_symbol *symbol, struct zint_seg segs[], cons switch (codeword_size) { case 6: zint_rs_init_gf(&rs, 0x43); - zint_rs_init_code(&rs, ecc_blocks, 1); - zint_rs_encode_uint(&rs, data_blocks, data_part, ecc_part); + zint_rs_init_code(&rs, num_ecc_cws, 1); + zint_rs_encode_uint(&rs, num_data_cws, data_part, ecc_part); break; case 8: zint_rs_init_gf(&rs, 0x12d); - zint_rs_init_code(&rs, ecc_blocks, 1); - zint_rs_encode_uint(&rs, data_blocks, data_part, ecc_part); + zint_rs_init_code(&rs, num_ecc_cws, 1); + zint_rs_encode_uint(&rs, num_data_cws, data_part, ecc_part); break; case 10: if (!zint_rs_uint_init_gf(&rs_uint, 0x409, 1023)) { /* Can fail on malloc() */ return z_errtxt(ZINT_ERROR_MEMORY, symbol, 500, "Insufficient memory for Reed-Solomon log tables"); } - zint_rs_uint_init_code(&rs_uint, ecc_blocks, 1); - zint_rs_uint_encode(&rs_uint, data_blocks, data_part, ecc_part); + zint_rs_uint_init_code(&rs_uint, num_ecc_cws, 1); + zint_rs_uint_encode(&rs_uint, num_data_cws, data_part, ecc_part); zint_rs_uint_free(&rs_uint); break; case 12: if (!zint_rs_uint_init_gf(&rs_uint, 0x1069, 4095)) { /* Can fail on malloc() */ return z_errtxt(ZINT_ERROR_MEMORY, symbol, 700, "Insufficient memory for Reed-Solomon log tables"); } - zint_rs_uint_init_code(&rs_uint, ecc_blocks, 1); - zint_rs_uint_encode(&rs_uint, data_blocks, data_part, ecc_part); + zint_rs_uint_init_code(&rs_uint, num_ecc_cws, 1); + zint_rs_uint_encode(&rs_uint, num_data_cws, data_part, ecc_part); zint_rs_uint_free(&rs_uint); break; } - for (i = 0; i < ecc_blocks; i++) { + for (i = 0; i < num_ecc_cws; i++) { adjusted_length = z_bin_append_posn(ecc_part[i], codeword_size, adjusted_string, adjusted_length); } /* Invert the data so that actual data is on the outside and reed-solomon on the inside */ memset(bit_pattern, '0', AZTEC_MAP_POSN_MAX + 1); - total_bits = (data_blocks + ecc_blocks) * codeword_size; + total_bits = (num_data_cws + num_ecc_cws) * codeword_size; for (i = 0; i < total_bits; i++) { bit_pattern[i] = adjusted_string[total_bits - i - 1]; } @@ -1941,10 +1956,10 @@ INTERNAL int zint_aztec(struct zint_symbol *symbol, struct zint_seg segs[], cons descriptor[0] = ((layers - 1) & 0x02) ? '1' : '0'; descriptor[1] = ((layers - 1) & 0x01) ? '1' : '0'; - /* The next 6 bits represent the number of data blocks minus 1 */ - descriptor[2] = reader_init || ((data_blocks - 1) & 0x20) ? '1' : '0'; + /* The next 6 bits represent the number of data codewords minus 1 */ + descriptor[2] = reader_init || ((num_data_cws - 1) & 0x20) ? '1' : '0'; for (i = 3; i < 8; i++) { - descriptor[i] = ((data_blocks - 1) & (0x10 >> (i - 3))) ? '1' : '0'; + descriptor[i] = ((num_data_cws - 1) & (0x10 >> (i - 3))) ? '1' : '0'; } if (debug_print) printf("Mode Message = %.8s\n", descriptor); } else { @@ -1953,10 +1968,10 @@ INTERNAL int zint_aztec(struct zint_symbol *symbol, struct zint_seg segs[], cons descriptor[i] = ((layers - 1) & (0x10 >> i)) ? '1' : '0'; } - /* The next 11 bits represent the number of data blocks minus 1 */ - descriptor[5] = reader_init || ((data_blocks - 1) & 0x400) ? '1' : '0'; + /* The next 11 bits represent the number of data codewords minus 1 */ + descriptor[5] = reader_init || ((num_data_cws - 1) & 0x400) ? '1' : '0'; for (i = 6; i < 16; i++) { - descriptor[i] = ((data_blocks - 1) & (0x200 >> (i - 6))) ? '1' : '0'; + descriptor[i] = ((num_data_cws - 1) & (0x200 >> (i - 6))) ? '1' : '0'; } if (debug_print) printf("Mode Message = %.16s\n", descriptor); } @@ -2034,9 +2049,9 @@ INTERNAL int zint_aztec(struct zint_symbol *symbol, struct zint_seg segs[], cons if (debug_print) { printf("Generating a %dx%d %s symbol with %d layers\n", dim, dim, compact ? "compact" : "full-size", layers); - printf("Requires %d codewords of %d-bits\n", data_blocks + ecc_blocks, codeword_size); + printf("Requires %d codewords of %d-bits\n", num_data_cws + num_ecc_cws, codeword_size); printf(" (%d data words, %d ecc words, %.1f%%, output option_1 0x%X, option_2 %d)\n", - data_blocks, ecc_blocks, ecc_ratio * 100, symbol->option_1, symbol->option_2); + num_data_cws, num_ecc_cws, ecc_ratio * 100, symbol->option_1, symbol->option_2); } return error_number; diff --git a/backend/aztec.h b/backend/aztec.h index ea0527fd..5711af9f 100644 --- a/backend/aztec.h +++ b/backend/aztec.h @@ -254,7 +254,7 @@ static const short AztecSizes[32] = { }; static const short AztecCompactSizes[4] = { - 17, 40, 51, 64 /* 64 data blocks (Mode Message max) but 76 altogether */ + 17, 40, 51, 64 /* 64 data codewords (Mode Message max) but 76 altogether */ }; /* Tables `AztecDataSizes` and `AztecCompactDataSizes` generated by "backend/tools/gen_aztec_data_sizes.php" */ diff --git a/backend/aztec_trace.h b/backend/aztec_trace.h index 2cbb708d..128b3dbf 100644 --- a/backend/aztec_trace.h +++ b/backend/aztec_trace.h @@ -34,25 +34,25 @@ #define Z_AZTEC_TRACE_H static void AZ_TRACE_EdgeToString(char *buf, const unsigned char *source, const int length, const char initial_mode, - struct az_edge *edges, struct az_edge *edge) { + struct az_edge *edges, struct az_edge *edge) { struct az_edge *previous_edge = AZ_PREVIOUS(edges, edge); int previousMode = previous_edge ? previous_edge->mode : initial_mode; - int previous = previous_edge ? (int) (previous_edge - edges) : 0; - int current = (int) (edge - edges); + int previous = previous_edge ? (int) (previous_edge - edges) : 0; + int current = (int) (edge - edges); (void)length; if (buf) { sprintf(buf, "%d_%c_%d %c(%d,%d) %d -> %d_%c_%d", edge->from, az_mode_char(previousMode), previous, az_mode_char(edge->mode), source[edge->from], edge->len, - edge->size, edge->from + 1, az_mode_char(edge->mode), current); + edge->size, edge->from + 1, az_mode_char(edge->mode), current); } else { printf("%d_%c_%d %c(%d,%d) %d -> %d_%c_%d", edge->from, az_mode_char(previousMode), previous, az_mode_char(edge->mode), source[edge->from], edge->len, - edge->size, edge->from + 1, az_mode_char(edge->mode), current); + edge->size, edge->from + 1, az_mode_char(edge->mode), current); } } static void AZ_TRACE_Path(const unsigned char *source, const int length, const char initial_mode, - struct az_edge *edges, struct az_edge *edge, char *result, const int result_size) { + struct az_edge *edges, struct az_edge *edge, char *result, const int result_size) { struct az_edge *current; AZ_TRACE_EdgeToString(result, source, length, initial_mode, edges, edge); current = AZ_PREVIOUS(edges, edge); diff --git a/backend/code.c b/backend/code.c index 46ae849b..10ce931e 100644 --- a/backend/code.c +++ b/backend/code.c @@ -241,9 +241,9 @@ INTERNAL int zint_excode39(struct zint_symbol *symbol, unsigned char source[], i } /* Then send the buffer to the C39 function */ - if ((error_number = zint_code39(symbol, buffer, (int) (b - buffer))) >= ZINT_ERROR) { - return error_number; - } + error_number = zint_code39(symbol, buffer, (int) (b - buffer)); + /* Due to above checks & not using content segs, can only return warning (height) */ + assert(error_number < ZINT_ERROR); if (saved_option_2 == 2) { symbol->option_2 = 2; /* Restore */ diff --git a/backend/code1.c b/backend/code1.c index d1bbbc3b..b94117a4 100644 --- a/backend/code1.c +++ b/backend/code1.c @@ -1,7 +1,7 @@ /* code1.c - USS Code One */ /* libzint - the open source barcode library - Copyright (C) 2009-2025 Robin Stuart + Copyright (C) 2009-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -195,30 +195,30 @@ static int c1_look_ahead_test(const unsigned char source[], const int length, co byte_count = C1_MULT_3; } + assert(current_mode != C1_EDI); /* Not called in EDI mode */ switch (current_mode) { case C1_C40: c40_count = 0; break; /* Step J2 */ case C1_TEXT: text_count = 0; break; /* Step J3 */ - case C1_EDI: edi_count = 0; break; /* Missing in spec */ case C1_BYTE: byte_count = 0; break; /* Step J4 */ } for (sp = position; sp < length; sp++) { - const unsigned char c = source[sp]; - const int is_extended = !z_isascii(c); + const unsigned char ch = source[sp]; + const int is_extended = !z_isascii(ch); /* Step L */ - if (z_isdigit(c)) { + if (z_isdigit(ch)) { ascii_count += C1_MULT_1_DIV_2; /* Step L1 */ } else { if (is_extended) { - ascii_count = ceilf(ascii_count) + C1_MULT_2; /* Step L2 */ + ascii_count = C1_MULT_CEIL(ascii_count) + C1_MULT_2; /* Step L2 */ } else { - ascii_count = ceilf(ascii_count) + C1_MULT_1; /* Step L3 */ + ascii_count = C1_MULT_CEIL(ascii_count) + C1_MULT_1; /* Step L3 */ } } /* Step M */ - if (c1_isc40(c)) { + if (c1_isc40(ch)) { c40_count += C1_MULT_2_DIV_3; /* Step M1 */ } else if (is_extended) { c40_count += C1_MULT_8_DIV_3; /* Step M2 */ @@ -227,7 +227,7 @@ static int c1_look_ahead_test(const unsigned char source[], const int length, co } /* Step N */ - if (c1_istext(c)) { + if (c1_istext(ch)) { text_count += C1_MULT_2_DIV_3; /* Step N1 */ } else if (is_extended) { text_count += C1_MULT_8_DIV_3; /* Step N2 */ @@ -236,7 +236,7 @@ static int c1_look_ahead_test(const unsigned char source[], const int length, co } /* Step O */ - if (c1_isedi(c)) { + if (c1_isedi(ch)) { edi_count += C1_MULT_2_DIV_3; /* Step O1 */ } else if (is_extended) { edi_count += C1_MULT_13_DIV_3; /* Step O2 */ @@ -245,7 +245,7 @@ static int c1_look_ahead_test(const unsigned char source[], const int length, co } /* Step P */ - if (gs1 && c == '\x1D') { + if (gs1 && ch == '\x1D') { byte_count += C1_MULT_3; /* Step P1 */ } else { byte_count += C1_MULT_1; /* Step P2 */ @@ -978,7 +978,7 @@ static int c1_encode(struct zint_symbol *symbol, unsigned char source[], int len } /* Call `c1_encode()` for each segment */ -static int c1_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, const int gs1, +static void c1_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, const int gs1, unsigned int target[], int *p_data_length, int *p_last_mode) { int i; int tp = 0; @@ -994,8 +994,6 @@ static int c1_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co } *p_data_length = tp; - - return 0; } /* Set symbol from datagrid */ @@ -1160,9 +1158,7 @@ INTERNAL int zint_codeone(struct zint_symbol *symbol, struct zint_seg segs[], co i); } - if (c1_encode_segs(symbol, segs, seg_count, gs1, target, &data_length, &last_mode)) { - return ZINT_ERROR_MEMORY; /* `c1_encode_segs()` only returns non-zero with OOM */ - } + c1_encode_segs(symbol, segs, seg_count, gs1, target, &data_length, &last_mode); assert(data_length); /* Can't exceed C1_MAX_CWS as input <= 90 */ if (data_length > 38) { @@ -1245,9 +1241,7 @@ INTERNAL int zint_codeone(struct zint_symbol *symbol, struct zint_seg segs[], co int blocks, data_blocks, ecc_blocks, ecc_length; int last_mode; - if (c1_encode_segs(symbol, segs, seg_count, gs1, target, &data_length, &last_mode)) { - return ZINT_ERROR_MEMORY; /* `c1_encode_segs()` only returns non-zero with OOM */ - } + c1_encode_segs(symbol, segs, seg_count, gs1, target, &data_length, &last_mode); if (data_length == 0) { return z_errtxt(ZINT_ERROR_TOO_LONG, symbol, 517, diff --git a/backend/common.c b/backend/common.c index 4326ea3f..722ba4d5 100644 --- a/backend/common.c +++ b/backend/common.c @@ -998,6 +998,24 @@ INTERNAL void z_hrt_conv_gs1_brackets_nochk(struct zint_symbol *symbol, const un symbol->text[length] = '\0'; } +#ifdef ZINT_TEST +/* For testing content segment `calloc()`/`malloc()` failures */ +static int z_ct_fail_id = 0; +static int z_ct_fail_at = 0; + +INTERNAL void zint_test_ct_set_fail(const int id, const int at) { + z_ct_fail_id = id; + z_ct_fail_at = at; +} + +#define ct_calloc(id, num, sz) (z_ct_fail_at > 0 && z_ct_fail_id == (id) && --z_ct_fail_at == 0 \ + ? NULL : calloc(num, sz)) +#define ct_malloc(id, sz) (z_ct_fail_at > 0 && z_ct_fail_id == (id) && --z_ct_fail_at == 0 ? NULL : malloc(sz)) +#else +#define ct_calloc(id, num, sz) calloc(num, sz) +#define ct_malloc(id, sz) malloc(sz) +#endif + /* Initialize `content_segs` for `seg_count` segments. On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ INTERNAL int z_ct_init_segs(struct zint_symbol *symbol, const int seg_count) { int i; @@ -1005,7 +1023,8 @@ INTERNAL int z_ct_init_segs(struct zint_symbol *symbol, const int seg_count) { if (symbol->content_segs) { z_ct_free_segs(symbol); } - if (!(symbol->content_segs = (struct zint_seg *) calloc((size_t) seg_count, sizeof(struct zint_seg)))) { + if (!(symbol->content_segs + = (struct zint_seg *) ct_calloc(Z_CT_FAIL_ID_INIT_SEGS, (size_t) seg_count, sizeof(struct zint_seg)))) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 243, "Insufficient memory for content segs buffer"); } for (i = 0; i < seg_count; i++) { @@ -1039,7 +1058,8 @@ static int ct_init_seg_source(struct zint_symbol *symbol, const int seg_idx, con assert(!symbol->content_segs[seg_idx].source); assert(length > 0); - if (!(symbol->content_segs[seg_idx].source = (unsigned char *) malloc((size_t) length))) { + if (!(symbol->content_segs[seg_idx].source + = (unsigned char *) ct_malloc(Z_CT_FAIL_ID_INIT_SEG_SRC, (size_t) length))) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 245, "Insufficient memory for content segs source buffer"); } return 0; diff --git a/backend/common.h b/backend/common.h index d2da2e21..475e2774 100644 --- a/backend/common.h +++ b/backend/common.h @@ -142,12 +142,13 @@ typedef unsigned __int64 uint64_t; #define z_isfintf(arg) (fmodf(arg, 1.0f) == 0.0f) /* Simple versions of functions with no dependence on locale */ -#define z_isdigit(ch) ((ch) <= '9' && (ch) >= '0') -#define z_isupper(ch) ((ch) >= 'A' && (ch) <= 'Z') -#define z_islower(ch) ((ch) >= 'a' && (ch) <= 'z') -#define z_isalpha(ch) (z_isupper(ch) || z_islower(ch)) -#define z_isascii(ch) (!((ch) & ~0x7F)) -#define z_iscntrl(ch) (!((ch) & ~0x1F) || (ch) == 127) +#define z_isdigit(ch) ((ch) <= '9' && (ch) >= '0') +#define z_isxdigit(ch) (z_isdigit(ch) || (((ch) | 0x20) >= 'a' && ((ch) | 0x20) <= 'f')) +#define z_isupper(ch) ((ch) >= 'A' && (ch) <= 'Z') +#define z_islower(ch) ((ch) >= 'a' && (ch) <= 'z') +#define z_isalpha(ch) z_islower(ch | 0x20) +#define z_isascii(ch) (!((ch) & ~0x7F)) +#define z_iscntrl(ch) (!((ch) & ~0x1F) || (ch) == 127) /* Shorthands to cast away char pointer signedness */ #define ZUCP(p) ((unsigned char *) (p)) @@ -355,6 +356,12 @@ INTERNAL void z_hrt_printf_nochk(struct zint_symbol *symbol, const char *fmt, .. INTERNAL void z_hrt_conv_gs1_brackets_nochk(struct zint_symbol *symbol, const unsigned char source[], const int length); +#ifdef ZINT_TEST +/* For testing content segment `calloc()`/`malloc()` failures */ +#define Z_CT_FAIL_ID_INIT_SEGS 1 +#define Z_CT_FAIL_ID_INIT_SEG_SRC 2 +INTERNAL void zint_test_ct_set_fail(const int id, const int at); +#endif /* Initialize `content_segs` for `seg_count` segments. On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ INTERNAL int z_ct_init_segs(struct zint_symbol *symbol, const int seg_count); diff --git a/backend/composite.c b/backend/composite.c index 6a8c3a3d..c98dfcbb 100644 --- a/backend/composite.c +++ b/backend/composite.c @@ -66,12 +66,14 @@ INTERNAL int zint_ean_leading_zeroes(struct zint_symbol *symbol, const unsigned unsigned char local_source[], int *p_with_addon, unsigned char *zfirst_part, unsigned char *zsecond_part); -INTERNAL int zint_dbar_omnstk_set_height(struct zint_symbol *symbol, const int first_row); +INTERNAL int zint_dbar_stk_set_height(struct zint_symbol *symbol, const int first_row, const int no_errtxt); INTERNAL int zint_dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int length, const int cc_rows); INTERNAL int zint_dbar_ltd_cc(struct zint_symbol *symbol, unsigned char source[], int length, const int cc_rows); INTERNAL int zint_dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int length, const int cc_rows); INTERNAL int zint_dbar_exp_date(const unsigned char source[], const int length, const int position); +INTERNAL int zint_micropdf_variant(const int cols, const int mclength); + static int cc_min(const int first, const int second) { if (first <= second) @@ -111,11 +113,9 @@ static int cc_encode928(const unsigned short bitString[], unsigned short codeWor /* CC-A 2D component */ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_width) { - int i, segment, bitlen, cwCnt, variant; - int k, offset, j, total, rsCodeWords[8] = {0}; - int LeftRAPStart, RightRAPStart, CentreRAPStart, StartCluster; + int i, j, bitlen, cwCnt, ecc_cwds, variant; + int offset, rsCodeWords[8] = {0}; int LeftRAP, RightRAP, CentreRAP, Cluster; - int loop; unsigned short codeWords[28] = {0}; unsigned short bitStr[13] = {0}; char pattern[580]; @@ -126,14 +126,14 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w bitlen = (int) strlen(source); - for (segment = 0; segment < 13; segment++) { - const int strpos = segment * 16; + for (j = 0; j < 13; j++) { + const int strpos = j * 16; if (strpos >= bitlen) { break; } for (i = 0; i < 16 && strpos + i < bitlen; i++) { if (source[strpos + i] == '1') { - bitStr[segment] |= (0x8000 >> i); + bitStr[j] |= (0x8000 >> i); } } } @@ -173,15 +173,15 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w break; } - symbol->rows = cc_aVariants[variant]; - k = cc_aVariants[17 + variant]; - offset = cc_aVariants[34 + variant]; + symbol->rows = cc_aVariants[0][variant]; + ecc_cwds = cc_aVariants[1][variant]; + offset = cc_aVariants[2][variant]; /* Reed-Solomon error correction */ for (i = 0; i < cwCnt; i++) { - total = (codeWords[i] + rsCodeWords[k - 1]) % 929; - for (j = k - 1; j >= 0; j--) { + const int total = (codeWords[i] + rsCodeWords[ecc_cwds - 1]) % 929; + for (j = ecc_cwds - 1; j >= 0; j--) { if (j == 0) { rsCodeWords[j] = (929 - (total * cc_aCoeffs[offset + j]) % 929) % 929; } else { @@ -190,85 +190,66 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w } } - for (j = 0; j < k; j++) { + for (j = 0; j < ecc_cwds; j++) { if (rsCodeWords[j] != 0) { rsCodeWords[j] = 929 - rsCodeWords[j]; } } - for (i = k - 1; i >= 0; i--) { + for (i = ecc_cwds - 1; i >= 0; i--) { codeWords[cwCnt] = rsCodeWords[i]; cwCnt++; } /* Place data into table */ - LeftRAPStart = cc_aRAPTable[variant]; - CentreRAPStart = cc_aRAPTable[variant + 17]; - RightRAPStart = cc_aRAPTable[variant + 34]; - StartCluster = cc_aRAPTable[variant + 51] / 3; + LeftRAP = cc_aRAPTable[0][variant] - 1; + CentreRAP = cc_aRAPTable[1][variant] - 1; + RightRAP = cc_aRAPTable[2][variant] - 1; - LeftRAP = LeftRAPStart; - CentreRAP = CentreRAPStart; - RightRAP = RightRAPStart; - Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + Cluster = cc_aRAPTable[3][variant]; /* Pre-divided by 3 */ for (i = 0; i < symbol->rows; i++) { + const int k = i * cc_width; bp = 0; offset = 929 * Cluster; - k = i * cc_width; /* Copy the data into codebarre */ if (cc_width != 3) { - bp = z_bin_append_posn(zint_pdf_rap_side[LeftRAP - 1], 10, pattern, bp); + bp = z_bin_append_posn(zint_pdf_rap_side[LeftRAP], 10, pattern, bp); } - bp = z_bin_append_posn(zint_pdf_bitpattern[offset + codeWords[k]], 16, pattern, bp); - pattern[bp++] = '0'; + bp = z_bin_append_posn(((int) zint_pdf_bitpattern[offset + codeWords[k]]) << 1, 17, pattern, bp); if (cc_width >= 2) { if (cc_width == 3) { - bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP - 1], 10, pattern, bp); + bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP], 10, pattern, bp); } - bp = z_bin_append_posn(zint_pdf_bitpattern[offset + codeWords[k + 1]], 16, pattern, bp); - pattern[bp++] = '0'; + bp = z_bin_append_posn(((int) zint_pdf_bitpattern[offset + codeWords[k + 1]]) << 1, 17, pattern, bp); if (cc_width >= 3) { if (cc_width == 4) { - bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP - 1], 10, pattern, bp); + bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP], 10, pattern, bp); } - bp = z_bin_append_posn(zint_pdf_bitpattern[offset + codeWords[k + 2]], 16, pattern, bp); - pattern[bp++] = '0'; + bp = z_bin_append_posn(((int) zint_pdf_bitpattern[offset + codeWords[k + 2]]) << 1, 17, pattern, bp); if (cc_width == 4) { - bp = z_bin_append_posn(zint_pdf_bitpattern[offset + codeWords[k + 3]], 16, pattern, bp); - pattern[bp++] = '0'; + bp = z_bin_append_posn(((int) zint_pdf_bitpattern[offset + codeWords[k + 3]]) << 1, 17, pattern, + bp); } } } - bp = z_bin_append_posn(zint_pdf_rap_side[RightRAP - 1], 10, pattern, bp); + bp = z_bin_append_posn(zint_pdf_rap_side[RightRAP], 10, pattern, bp); pattern[bp++] = '1'; /* Stop */ /* So now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ - for (loop = 0; loop < bp; loop++) { - if (pattern[loop] == '1') { - z_set_module(symbol, i, loop); + for (j = 0; j < bp; j++) { + if (pattern[j] == '1') { + z_set_module(symbol, i, j); } } symbol->row_height[i] = 2; /* Set up RAPs and Cluster for next row */ - LeftRAP++; - CentreRAP++; - RightRAP++; - Cluster++; - - if (LeftRAP == 53) { - LeftRAP = 1; - } - if (CentreRAP == 53) { - CentreRAP = 1; - } - if (RightRAP == 53) { - RightRAP = 1; - } - if (Cluster == 3) { - Cluster = 0; - } + LeftRAP = LeftRAP == 51 ? 0 : LeftRAP + 1; + CentreRAP = CentreRAP == 51 ? 0 : CentreRAP + 1; + RightRAP = RightRAP == 51 ? 0 : RightRAP + 1; + Cluster = Cluster == 2 ? 0 : Cluster + 1; } symbol->width = bp; @@ -284,17 +265,16 @@ static void cc_b(struct zint_symbol *symbol, const char source[], const int cc_w unsigned char *data_string = (unsigned char *) z_alloca(length + 3); short chainemc[180]; int mclength = 0; - int k, j, p, longueur, mccorrection[50] = {0}, offset; - int total; char pattern[580]; - int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster; - int LeftRAP, CentreRAP, RightRAP, Cluster, loop; - int columns; - int bp = 0; + int variant; +#ifndef NDEBUG + int ecc_cwds; +#endif const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; for (i = 0; i < length; i++) { const int binloc = i * 8; + int p; data_string[i] = 0; for (p = 0; p < 8; p++) { @@ -311,183 +291,27 @@ static void cc_b(struct zint_symbol *symbol, const char source[], const int cc_w /* Now figure out which variant of the symbol to use and load values accordingly */ - variant = 0; - - if (cc_width == 2) { - if (mclength <= 8) { - variant = 7; - } else if (mclength <= 13) { - variant = 8; - } else if (mclength <= 19) { - variant = 9; - } else if (mclength <= 24) { - variant = 10; - } else if (mclength <= 29) { - variant = 11; - } else if (mclength <= 33) { - variant = 12; - } else { - variant = 13; - } - } else if (cc_width == 3) { - if (mclength <= 6) { - variant = 14; - } else if (mclength <= 10) { - variant = 15; - } else if (mclength <= 14) { - variant = 16; - } else if (mclength <= 18) { - variant = 17; - } else if (mclength <= 24) { - variant = 18; - } else if (mclength <= 34) { - variant = 19; - } else if (mclength <= 46) { - variant = 20; - } else if (mclength <= 58) { - variant = 21; - } else if (mclength <= 70) { - variant = 22; - } else { - variant = 23; - } - } else if (cc_width == 4) { - if (mclength <= 8) { - variant = 24; - } else if (mclength <= 12) { - variant = 25; - } else if (mclength <= 18) { - variant = 26; - } else if (mclength <= 24) { - variant = 27; - } else if (mclength <= 30) { - variant = 28; - } else if (mclength <= 39) { - variant = 29; - } else if (mclength <= 54) { - variant = 30; - } else if (mclength <= 72) { - variant = 31; - } else if (mclength <= 90) { - variant = 32; - } else if (mclength <= 108) { - variant = 33; - } else { - variant = 34; - } - } + variant = zint_micropdf_variant(cc_width, mclength); + assert(variant > 0); /* Now we have the variant we can load the data - from here on the same as MicroPDF417 code */ variant--; assert(variant >= 0); - columns = zint_pdf_MicroVariants[variant]; /* columns */ - symbol->rows = zint_pdf_MicroVariants[variant + 34]; /* rows */ - k = zint_pdf_MicroVariants[variant + 68]; /* Number of EC CWs */ - longueur = (columns * symbol->rows) - k; /* Number of non-EC CWs */ - i = longueur - mclength; /* Amount of padding required */ - offset = zint_pdf_MicroVariants[variant + 102]; /* Coefficient offset */ + assert(zint_pdf_MicroVariants[0][variant] == cc_width); /* columns */ + symbol->rows = zint_pdf_MicroVariants[1][variant]; /* rows */ +#ifndef NDEBUG + ecc_cwds = zint_pdf_MicroVariants[2][variant]; /* Number of EC CWs */ +#else + (void) zint_pdf_MicroVariants[2][variant]; /* Number of EC CWs */ +#endif + /* Binary input padded to target length so no padding necessary */ + assert(cc_width * symbol->rows == mclength + ecc_cwds); - /* Binary input padded to target length so no padding should be necessary */ - while (i > 0) { - chainemc[mclength++] = 900; /* Not reached */ - i--; - } - - /* Reed-Solomon error correction */ - longueur = mclength; - for (i = 0; i < longueur; i++) { - total = (chainemc[i] + mccorrection[k - 1]) % 929; - for (j = k - 1; j >= 0; j--) { - if (j == 0) { - mccorrection[j] = (929 - (total * zint_pdf_Microcoeffs[offset + j]) % 929) % 929; - } else { - mccorrection[j] = (mccorrection[j - 1] + 929 - (total * zint_pdf_Microcoeffs[offset + j]) % 929) - % 929; - } - } - } - - for (j = 0; j < k; j++) { - if (mccorrection[j] != 0) { - mccorrection[j] = 929 - mccorrection[j]; - } - } - /* We add these codes to the string */ - for (i = k - 1; i >= 0; i--) { - chainemc[mclength++] = mccorrection[i]; - } - - /* Now get the RAP (Row Address Pattern) start values */ - LeftRAPStart = zint_pdf_RAPTable[variant]; - CentreRAPStart = zint_pdf_RAPTable[variant + 34]; - RightRAPStart = zint_pdf_RAPTable[variant + 68]; - StartCluster = zint_pdf_RAPTable[variant + 102] / 3; - - /* That's all values loaded, get on with the encoding */ - - LeftRAP = LeftRAPStart; - CentreRAP = CentreRAPStart; - RightRAP = RightRAPStart; - Cluster = StartCluster; - /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + zint_micropdf_expand(symbol, chainemc, mclength, pattern, cc_width, variant, debug_print); for (i = 0; i < symbol->rows; i++) { - bp = 0; - offset = 929 * Cluster; - k = i * columns; - /* Copy the data into codebarre */ - bp = z_bin_append_posn(zint_pdf_rap_side[LeftRAP - 1], 10, pattern, bp); - bp = z_bin_append_posn(zint_pdf_bitpattern[offset + chainemc[k]], 16, pattern, bp); - pattern[bp++] = '0'; - if (cc_width >= 2) { - if (cc_width == 3) { - bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP - 1], 10, pattern, bp); - } - bp = z_bin_append_posn(zint_pdf_bitpattern[offset + chainemc[k + 1]], 16, pattern, bp); - pattern[bp++] = '0'; - if (cc_width >= 3) { - if (cc_width == 4) { - bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP - 1], 10, pattern, bp); - } - bp = z_bin_append_posn(zint_pdf_bitpattern[offset + chainemc[k + 2]], 16, pattern, bp); - pattern[bp++] = '0'; - if (cc_width == 4) { - bp = z_bin_append_posn(zint_pdf_bitpattern[offset + chainemc[k + 3]], 16, pattern, bp); - pattern[bp++] = '0'; - } - } - } - bp = z_bin_append_posn(zint_pdf_rap_side[RightRAP - 1], 10, pattern, bp); - pattern[bp++] = '1'; /* Stop */ - - /* So now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ - for (loop = 0; loop < bp; loop++) { - if (pattern[loop] == '1') { - z_set_module(symbol, i, loop); - } - } symbol->row_height[i] = 2; - - /* Set up RAPs and Cluster for next row */ - LeftRAP++; - CentreRAP++; - RightRAP++; - Cluster++; - - if (LeftRAP == 53) { - LeftRAP = 1; - } - if (CentreRAP == 53) { - CentreRAP = 1; - } - if (RightRAP == 53) { - RightRAP = 1; - } - if (Cluster == 3) { - Cluster = 0; - } } - symbol->width = bp; if (debug_print) { printf("CC-B Columns: %d, Rows: %d, Variant: %d, CodeWords: %d\n", @@ -496,13 +320,13 @@ static void cc_b(struct zint_symbol *symbol, const char source[], const int cc_w } /* CC-C 2D component - byte compressed PDF417 */ -static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_width, const int ecc_level) { +static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_width, const int ecc) { const int length = (int) strlen(source) / 8; - int i, p; + int i; unsigned char *data_string = (unsigned char *) z_alloca(length + 4); short chainemc[1000]; - int mclength = 0, k; - int offset, longueur, loop, total, j, mccorrection[520] = {0}; + int mclength = 0, ecc_cwds; + int offset, j, mccorrection[520] = {0}; int c1, c2, c3, dummy[35]; char pattern[580]; int bp = 0; @@ -510,6 +334,7 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w for (i = 0; i < length; i++) { const int binloc = i * 8; + int p; data_string[i] = 0; for (p = 0; p < 8; p++) { @@ -523,6 +348,7 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w chainemc[mclength++] = 920; /* CC-C identifier */ zint_pdf_byteprocess(chainemc, &mclength, data_string, 0, length, 0); + assert(mclength > 0); /* Suppress clang-tidy-23 warning clang-analyzer-security.ArrayBound */ chainemc[0] = mclength; @@ -532,28 +358,15 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w fputc('\n', stdout); } - k = 1; - for (i = 1; i <= (ecc_level + 1); i++) { - k *= 2; - } - /* 796 - we now take care of the Reed Solomon codes */ - switch (ecc_level) { - case 1: offset = 2; break; /* Not reached */ - case 2: offset = 6; break; /* Min ECC currently used is 2 */ - case 3: offset = 14; break; - case 4: offset = 30; break; - case 5: offset = 62; break; /* Max ECC currently used is 5 */ - case 6: offset = 126; break; /* Not reached */ - case 7: offset = 254; break; /* Not reached */ - case 8: offset = 510; break; /* Not reached */ - default: offset = 0; break; /* Not reached */ - } + assert(ecc >= 2 && ecc <= 5); + offset = (2 << ecc) - 2; + assert(offset >= 0 && offset <= 512); /* Suppress clang-tidy-23 warning clang-analyzer-security.ArrayBound */ + ecc_cwds = 1 << (ecc + 1); - longueur = mclength; - for (i = 0; i < longueur; i++) { - total = (chainemc[i] + mccorrection[k - 1]) % 929; - for (j = k - 1; j >= 0; j--) { + for (i = 0; i < mclength; i++) { + const int total = (chainemc[i] + mccorrection[ecc_cwds - 1]) % 929; + for (j = ecc_cwds - 1; j >= 0; j--) { if (j == 0) { mccorrection[j] = (929 - (total * zint_pdf_coefrs[offset + j]) % 929) % 929; } else { @@ -562,13 +375,13 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w } } - for (j = 0; j < k; j++) { + for (j = 0; j < ecc_cwds; j++) { if (mccorrection[j] != 0) { mccorrection[j] = 929 - mccorrection[j]; } } /* We add these codes to the string */ - for (i = k - 1; i >= 0; i--) { + for (i = ecc_cwds - 1; i >= 0; i--) { chainemc[mclength++] = mccorrection[i]; } @@ -577,15 +390,15 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w /* 818 - The CW string is finished */ symbol->rows = mclength / cc_width; c1 = (symbol->rows - 1) / 3; - c2 = ecc_level * 3 + (symbol->rows - 1) % 3; + c2 = ecc * 3 + (symbol->rows - 1) % 3; c3 = cc_width - 1; /* We now encode each row */ for (i = 0; i <= symbol->rows - 1; i++) { + const int k = (i / 3) * 30; for (j = 0; j < cc_width; j++) { dummy[j + 1] = chainemc[i * cc_width + j]; } - k = (i / 3) * 30; switch (i % 3) { case 0: dummy[0] = k + c1; @@ -607,14 +420,13 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w bp = z_bin_append_posn(0x1FEA8, 17, pattern, bp); /* Row start */ for (j = 0; j <= cc_width + 1; j++) { - bp = z_bin_append_posn(zint_pdf_bitpattern[offset + dummy[j]], 16, pattern, bp); - pattern[bp++] = '0'; + bp = z_bin_append_posn(((int) zint_pdf_bitpattern[offset + dummy[j]]) << 1, 17, pattern, bp); } bp = z_bin_append_posn(0x3FA29, 18, pattern, bp); /* Row Stop */ - for (loop = 0; loop < bp; loop++) { - if (pattern[loop] == '1') { - z_set_module(symbol, i, loop); + for (j = 0; j < bp; j++) { + if (pattern[j] == '1') { + z_set_module(symbol, i, j); } } symbol->row_height[i] = 3; @@ -623,7 +435,7 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w if (debug_print) { printf("CC-C Columns: %d, Rows: %d, CodeWords: %d, ECC Level: %d\n", - cc_width, symbol->rows, mclength, ecc_level); + cc_width, symbol->rows, mclength, ecc); } } @@ -667,15 +479,12 @@ static int cc_b_calc_padding(const int binary_length, const int cc_width) { return target_bitsize; } -static int cc_c_calc_padding(const int binary_length, int *p_cc_width, const int linear_width, int *p_ecc_level) { - int target_bitsize = 0; - int byte_length, codewords_used, ecc_level, ecc_codewords, rows; +static int cc_c_calc_padding(const int binary_length, int *p_cc_width, const int linear_width, int *p_ecc) { + int target_bitsize; + int codewords_used, ecc, ecc_cwds, rows; int codewords_total, target_codewords, target_bytesize; - - byte_length = binary_length / 8; - if (binary_length % 8 != 0) { - byte_length++; - } + int cc_width; + const int byte_length = (binary_length + 7) >> 3; codewords_used = (byte_length / 6) * 5; codewords_used += byte_length % 6; @@ -683,62 +492,62 @@ static int cc_c_calc_padding(const int binary_length, int *p_cc_width, const int /* Recommended minimum ecc levels ISO/IEC 1543:2015 (PDF417) Annex E Table E.1, restricted by CC-C codeword max 900 (30 cols * 30 rows), GS1 General Specifications 19.1 5.9.2.3 */ if (codewords_used <= 40) { - ecc_level = 2; + ecc = 2; } else if (codewords_used <= 160) { - ecc_level = 3; + ecc = 3; } else if (codewords_used <= 320) { - ecc_level = 4; + ecc = 4; } else if (codewords_used <= 833) { /* 900 - 3 - 64 */ - ecc_level = 5; + ecc = 5; } else if (codewords_used <= 865) { /* 900 - 3 - 32 */ - ecc_level = 4; /* Not recommended but allow to meet advertised "up to 2361 digits" (allows max 2372) */ + ecc = 4; /* Not recommended but allow to meet advertised "up to 2361 digits" (allows max 2372) */ } else { return 0; } - *p_ecc_level = ecc_level; - ecc_codewords = 1 << (ecc_level + 1); + *p_ecc = ecc; + ecc_cwds = 1 << (ecc + 1); - codewords_used += ecc_codewords; + codewords_used += ecc_cwds; codewords_used += 3; + assert(codewords_used <= 900); /* Minimum possible linear width (with GS1_NO_CHECK) is 11*5 (start, FNC1, linkage, data, check) + 13 stop */ assert(linear_width >= 68); /* -52 = 7 left shift (section 12.3 f) + 10 right quiet zone - 17 start + 2x17 row indicators + 18 stop */ - *p_cc_width = linear_width == 68 ? 1 : (linear_width - 52) / 17; /* Ensure > 0 */ - if (*p_cc_width > 30) { - *p_cc_width = 30; + cc_width = linear_width == 68 ? 1 : (linear_width - 52) / 17; /* Ensure > 0 */ + if (cc_width > 30) { + cc_width = 30; } - assert(*p_cc_width > 0); - rows = (int) ceil((double) codewords_used / *p_cc_width); + assert(cc_width > 0); + rows = (int) ceil((double) codewords_used / cc_width); /* Stop the symbol from becoming too high */ - while (rows > 30 && *p_cc_width < 30) { - (*p_cc_width)++; - rows = (int) ceil((double) codewords_used / *p_cc_width); + while (rows > 30 && cc_width < 30) { + cc_width++; + rows = (int) ceil((double) codewords_used / cc_width); } + assert(rows <= 30); /* Guaranteed by codewords_used <= 900 */ - if (rows > 30) { /* Should never happen given `codewords_used` check above (865 / 30 ~ 28.83) */ - return 0; /* Not reached */ - } if (rows < 3) { rows = 3; } - codewords_total = *p_cc_width * rows; + codewords_total = cc_width * rows; + *p_cc_width = cc_width; - target_codewords = codewords_total - ecc_codewords; + target_codewords = codewords_total - ecc_cwds; target_codewords -= 3; target_bytesize = 6 * (target_codewords / 5); target_bytesize += target_codewords % 5; - target_bitsize = 8 * target_bytesize; + target_bitsize = target_bytesize << 3; return target_bitsize; } /* Handles all data encodation from section 5 of ISO/IEC 24723 */ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char source[], const int length, - char binary_string[], const int cc_mode, int *p_cc_width, int *p_ecc_level, const int linear_width) { + char binary_string[], const int cc_mode, int *p_cc_width, int *p_ecc, const int linear_width) { int encoding_method, read_posn, alpha_pad; int i, j, ai_crop, ai_crop_posn, fnc1_latch; int ai90_mode, remainder; @@ -755,7 +564,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour ai_crop_posn = -1; fnc1_latch = 0; alpha_pad = 0; - *p_ecc_level = 0; + *p_ecc = 0; target_bitsize = 0; mode = GF_NUMERIC; @@ -1033,7 +842,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour target_bitsize = cc_b_calc_padding(bp, *p_cc_width); break; case 3: - target_bitsize = cc_c_calc_padding(bp, p_cc_width, linear_width, p_ecc_level); + target_bitsize = cc_c_calc_padding(bp, p_cc_width, linear_width, p_ecc); break; } @@ -1064,7 +873,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour switch (cc_mode) { case 1: target_bitsize = cc_a_calc_padding(bp, *p_cc_width); break; case 2: target_bitsize = cc_b_calc_padding(bp, *p_cc_width); break; - case 3: target_bitsize = cc_c_calc_padding(bp, p_cc_width, linear_width, p_ecc_level); break; + case 3: target_bitsize = cc_c_calc_padding(bp, p_cc_width, linear_width, p_ecc); break; } if (target_bitsize == 0) { @@ -1089,7 +898,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour binary_string[target_bitsize] = '\0'; if (debug_print) { - printf("ECC: %d, CC width %d\n", *p_ecc_level, *p_cc_width); + printf("ECC: %d, CC width %d\n", *p_ecc, *p_cc_width); printf("Binary: %s (%d)\n", binary_string, target_bitsize); } @@ -1120,9 +929,9 @@ static int cc_linear_dummy_run(struct zint_symbol *symbol, unsigned char *source } INTERNAL int zint_composite(struct zint_symbol *symbol, unsigned char source[], int length) { - int error_number = 0, warn_number = 0; - int cc_mode, cc_width = 0, ecc_level = 0; - int j, i, k; + int error_number = 0, warn_number; + int cc_mode, cc_width = 0, ecc = 0; + int i, j; /* Allow for 8 bits + 5-bit latch per char + 1000 bits overhead/padding */ const unsigned int bs = 13 * length + 1000 + 1; char *binary_string = (char *) z_alloca(bs); @@ -1135,6 +944,11 @@ INTERNAL int zint_composite(struct zint_symbol *symbol, unsigned char source[], if (debug_print) printf("Reduced length: %d\n", length); + /* Hack to initialize `warn_number` to warning (if any) returned by `zint_gs1_verify()` */ + warn_number = symbol->warn_level >> 8; + symbol->warn_level &= 0xFF; + assert(warn_number < ZINT_ERROR); + /* Perform sanity checks on input options first */ primary_len = (int) strlen(symbol->primary); if (primary_len == 0) { @@ -1222,7 +1036,7 @@ INTERNAL int zint_composite(struct zint_symbol *symbol, unsigned char source[], } if (cc_mode == 1) { - i = cc_binary_string(symbol, source, length, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); + i = cc_binary_string(symbol, source, length, binary_string, cc_mode, &cc_width, &ecc, linear_width); if (i == ZINT_ERROR_TOO_LONG) { symbol->errtxt[0] = '\0'; /* Unset error text */ cc_mode = 2; @@ -1233,7 +1047,7 @@ INTERNAL int zint_composite(struct zint_symbol *symbol, unsigned char source[], if (cc_mode == 2) { /* If the data didn't fit into CC-A it is recalculated for CC-B */ - i = cc_binary_string(symbol, source, length, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); + i = cc_binary_string(symbol, source, length, binary_string, cc_mode, &cc_width, &ecc, linear_width); if (i == ZINT_ERROR_TOO_LONG) { if (symbol->symbology != BARCODE_GS1_128_CC) { return ZINT_ERROR_TOO_LONG; @@ -1247,7 +1061,7 @@ INTERNAL int zint_composite(struct zint_symbol *symbol, unsigned char source[], if (cc_mode == 3) { /* If the data didn't fit in CC-B (and linear part is GS1-128) it is recalculated for CC-C */ - i = cc_binary_string(symbol, source, length, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); + i = cc_binary_string(symbol, source, length, binary_string, cc_mode, &cc_width, &ecc, linear_width); if (i != 0) { return i; } @@ -1255,15 +1069,15 @@ INTERNAL int zint_composite(struct zint_symbol *symbol, unsigned char source[], symbol->rows = 0; /* Composites are not stackable */ + assert(cc_mode >= 1 && cc_mode <= 3); switch (cc_mode) { - /* Note that ecc_level is only relevant to CC-C */ + /* Note that ecc is only relevant to CC-C */ case 1: cc_a(symbol, binary_string, cc_width); break; case 2: cc_b(symbol, binary_string, cc_width); break; - case 3: cc_c(symbol, binary_string, cc_width, ecc_level); break; - default: assert(0); break; /* Not reached */ + case 3: cc_c(symbol, binary_string, cc_width, ecc); break; } - if (symbol->option_1 >= 1 && symbol->option_1 <= 3 && symbol->option_1 != cc_mode) { + if (warn_number == 0 && symbol->option_1 >= 1 && symbol->option_1 <= 3 && symbol->option_1 != cc_mode) { warn_number = ZEXT z_errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 443, "Composite type changed from CC-%1$c to CC-%2$c", 'A' + (symbol->option_1 - 1), 'A' + (cc_mode - 1)); @@ -1401,8 +1215,8 @@ INTERNAL int zint_composite(struct zint_symbol *symbol, unsigned char source[], } break; case BARCODE_DBAR_EXP_CC: - for (k = 1; !z_module_is_set(linear, 1, k - 1) && z_module_is_set(linear, 1, k); k++); - top_shift = k; + for (j = 1; !z_module_is_set(linear, 1, j - 1) && z_module_is_set(linear, 1, j); j++); + top_shift = j; break; case BARCODE_UPCA_CC: bottom_shift = 2; @@ -1417,8 +1231,8 @@ INTERNAL int zint_composite(struct zint_symbol *symbol, unsigned char source[], top_shift = 1; break; case BARCODE_DBAR_EXPSTK_CC: - for (k = 1; !z_module_is_set(linear, 1, k - 1) && z_module_is_set(linear, 1, k); k++); - top_shift = k; + for (j = 1; !z_module_is_set(linear, 1, j - 1) && z_module_is_set(linear, 1, j); j++); + top_shift = j; break; } @@ -1460,31 +1274,40 @@ INTERNAL int zint_composite(struct zint_symbol *symbol, unsigned char source[], } symbol->rows += linear->rows; if (symbol->output_options & COMPLIANT_HEIGHT) { + /* Avoid overwriting any `zint_gs1_verify()` warning */ + const int no_errtxt = error_number != 0 || warn_number != 0; if (symbol->symbology == BARCODE_DBAR_STK_CC) { /* Databar Stacked needs special treatment due to asymmetric rows */ - error_number = zint_dbar_omnstk_set_height(symbol, symbol->rows - linear->rows + 1 /*first_row*/); + if (!no_errtxt) { + error_number = zint_dbar_stk_set_height(symbol, symbol->rows - linear->rows + 1 /*first_row*/, + no_errtxt); + } else { + (void) zint_dbar_stk_set_height(symbol, symbol->rows - linear->rows + 1 /*first_row*/, no_errtxt); + } } else if (symbol->symbology == BARCODE_DBAR_EXP_CC || symbol->symbology == BARCODE_DBAR_EXPSTK_CC) { /* If symbol->height given then min row height was returned, else default height */ - if (error_number == 0) { /* Avoid overwriting any `zint_gs1_verify()` warning */ + if (!no_errtxt) { error_number = z_set_height(symbol, symbol->height ? linear->height : 0.0f, - symbol->height ? 0.0f : linear->height, 0.0f, 0 /*no_errtxt*/); + symbol->height ? 0.0f : linear->height, 0.0f, no_errtxt); } else { (void) z_set_height(symbol, symbol->height ? linear->height : 0.0f, - symbol->height ? 0.0f : linear->height, 0.0f, 1 /*no_errtxt*/); + symbol->height ? 0.0f : linear->height, 0.0f, no_errtxt); } } else { /* If symbol->height given then min row height was returned, else default height */ - if (error_number == 0) { /* Avoid overwriting any previous warning (e.g. EAN-8 with add-on) */ + /* Avoid overwriting any previous warning (e.g. EAN-8 with add-on) */ + if (!no_errtxt) { error_number = z_set_height(symbol, symbol->height ? linear->height : 0.0f, - symbol->height ? 0.0f : linear->height, 0.0f, 0 /*no_errtxt*/); + symbol->height ? 0.0f : linear->height, 0.0f, no_errtxt); } else { (void) z_set_height(symbol, symbol->height ? linear->height : 0.0f, - symbol->height ? 0.0f : linear->height, 0.0f, 1 /*no_errtxt*/); + symbol->height ? 0.0f : linear->height, 0.0f, no_errtxt); } } } else { if (symbol->symbology == BARCODE_DBAR_STK_CC) { - (void) zint_dbar_omnstk_set_height(symbol, symbol->rows - linear->rows + 1 /*first_row*/); + (void) zint_dbar_stk_set_height(symbol, symbol->rows - linear->rows + 1 /*first_row*/, + 1 /*no_errtxt*/); } else { (void) z_set_height(symbol, symbol->height ? linear->height : 0.0f, symbol->height ? 0.0f : linear->height, 0.0f, 1 /*no_errtxt*/); diff --git a/backend/composite.h b/backend/composite.h index c0b0cc3a..897310d0 100644 --- a/backend/composite.h +++ b/backend/composite.h @@ -1,7 +1,7 @@ /* composite.c - Tables for UCC.EAN Composite Symbols */ /* libzint - the open source barcode library - Copyright (C) 2008-2024 Robin Stuart + Copyright (C) 2008-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -52,18 +52,18 @@ static const unsigned short cc_aCoeffs[30] = { }; /* rows, error codewords, k-offset of valid CC-A sizes from ISO/IEC 24723:2006 Table 9 */ -static const char cc_aVariants[51] = { - 5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, - 4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8, - 0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9, 15, 22 +static const char cc_aVariants[3][17] = { + { 5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7 }, + { 4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8 }, + { 0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9, 15, 22 } }; -/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24723:2006 tables 10 and 11 */ -static const char cc_aRAPTable[68] = { - 39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29, - 0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 26, 14, 9, - 19, 33, 12, 40, 46, 23, 52, 23, 13, 17, 27, 33, 52, 3, 6, 46, 41, - 6, 0, 3, 3, 3, 0, 3, 3, 0, 3, 6, 6, 0, 0, 0, 0, 3 +/* following is Left RAP, Centre RAP, Right RAP and (Start Cluster / 3) from ISO/IEC 24723:2006 tables 10 and 11 */ +static const char cc_aRAPTable[4][17] = { + { 39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29 }, + { 0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 26, 14, 9 }, + { 19, 33, 12, 40, 46, 23, 52, 23, 13, 17, 27, 33, 52, 3, 6, 46, 41 }, + { 2, 0, 1, 1, 1, 0, 1, 1, 0, 1, 2, 2, 0, 0, 0, 0, 1 } }; /* Row Address Patterns are as defined in pdf417.h */ diff --git a/backend/dotcode.c b/backend/dotcode.c index 4c77ce4a..55c5e432 100644 --- a/backend/dotcode.c +++ b/backend/dotcode.c @@ -1275,6 +1275,8 @@ INTERNAL int zint_dotcode(struct zint_symbol *symbol, struct zint_seg segs[], co min_dots = 9 * (data_length + 3 + (data_length / 2)) + 2; min_area = min_dots * 2; + assert(min_area >= 38); /* (9 * (1 + 3 + 0) + 2 = 19) * 2 */ + if (width == 0) { /* Automatic sizing */ /* Following Rule 3 (Section 5.2.2) and applying a recommended width to height ratio 3:2 */ @@ -1286,6 +1288,8 @@ INTERNAL int zint_dotcode(struct zint_symbol *symbol, struct zint_seg segs[], co height = (int) h; width = (int) w; + assert(height >= 5 && width >= 7); /* 38 * 0.666 = 25.308, 38 * 1.5 = 57 */ + if (((width + height) & 1) == 1) { if (width * height < min_area) { width++; @@ -1324,16 +1328,15 @@ INTERNAL int zint_dotcode(struct zint_symbol *symbol, struct zint_seg segs[], co height++; } } + assert(height >= 5 && width >= 5); if (debug_print) { printf("Width %d, Height %d\n", width, height); } if (height > 200 || width > 200) { - if (height > 200 && width > 200) { - ZEXT z_errtxtf(0, symbol, 526, "Resulting symbol size '%1$dx%2$d' (HxW) is too large (maximum 200x200)", - height, width); - } else if (width > 200) { + if (width > 200) { + assert(height <= 200); z_errtxtf(0, symbol, 528, "Resulting symbol width '%d' is too large (maximum 200)", width); } else { z_errtxtf(0, symbol, 735, "Resulting symbol height '%d' is too large (maximum 200)", height); @@ -1341,17 +1344,6 @@ INTERNAL int zint_dotcode(struct zint_symbol *symbol, struct zint_seg segs[], co return ZINT_ERROR_INVALID_OPTION; } - if (height < 5 || width < 5) { - /* Note: this branch probably no longer reached */ - assert(height >= 5 || width >= 5); /* If width < 5, min height is 19 */ - if (width < 5) { - z_errtxtf(0, symbol, 529, "Resulting symbol width '%d' is too small (minimum 5)", width); - } else { - z_errtxtf(0, symbol, 736, "Resulting symbol height '%d' is too small (minimum 5)", height); - } - return ZINT_ERROR_INVALID_OPTION; - } - n_dots = (height * width) / 2; dot_stream = (char *) z_alloca(height * width * 3); diff --git a/backend/eci.c b/backend/eci.c index 800435c4..88fe3412 100644 --- a/backend/eci.c +++ b/backend/eci.c @@ -1,7 +1,7 @@ /* eci.c - Extended Channel Interpretations */ /* libzint - the open source barcode library - Copyright (C) 2009-2025 Robin Stuart + Copyright (C) 2009-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -658,23 +658,12 @@ static int u_gb18030(const unsigned int u, unsigned char *dest) { /* Main ECI stuff */ -/* Helper to count the number of chars in a string within a range */ -static int chr_range_cnt(const unsigned char string[], const int length, const unsigned char c1, - const unsigned char c2) { +/* Helper to count the number of chars in a string less than or equal to `max` */ +static int chr_max_cnt(const unsigned char string[], const int length, const unsigned char max) { int count = 0; int i; - if (c1) { - for (i = 0; i < length; i++) { - if (string[i] >= c1 && string[i] <= c2) { - count++; - } - } - } else { - for (i = 0; i < length; i++) { - if (string[i] <= c2) { - count++; - } - } + for (i = 0; i < length; i++) { + count += string[i] <= max; } return count; } @@ -708,7 +697,7 @@ INTERNAL int zint_get_eci_length(const int eci, const unsigned char source[], in } else if (eci == 25 || eci == 33) { /* UTF-16 */ /* All ASCII chars take 2 bytes */ - length += chr_range_cnt(source, length, 0, 0x7F); + length += chr_max_cnt(source, length, 0x7F); /* Surrogate pairs are 4 UTF-8 bytes long so fit */ } else if (eci == 32) { /* GB 18030 */ @@ -717,7 +706,7 @@ INTERNAL int zint_get_eci_length(const int eci, const unsigned char source[], in } else if (eci == 34 || eci == 35) { /* UTF-32 */ /* Quadruple-up ASCII and double-up non-ASCII */ - length += chr_range_cnt(source, length, 0, 0x7F) * 2 + length; + length += chr_max_cnt(source, length, 0x7F) * 2 + length; } /* Big5, GB 2312, EUC-KR and GBK fit in UTF-8 length */ diff --git a/backend/filemem.c b/backend/filemem.c index 37fafa6f..24aefedd 100644 --- a/backend/filemem.c +++ b/backend/filemem.c @@ -60,6 +60,33 @@ # endif #endif +#ifdef ZINT_TEST +/* For testing `malloc()`/`realloc()` failures */ +static int fm_fail_id = 0; +static int fm_fail_at = 0; + +INTERNAL void zint_test_fm_set_fail(const int id, const int at) { + fm_fail_id = id; + fm_fail_at = at; +} + +#define FM_FAIL(id, ret) fm_fail_at > 0 && fm_fail_id == (id) && --fm_fail_at == 0 ? (ret) : +#define FM_FAIL_ERRNO(id, eno, ret) fm_fail_at > 0 && fm_fail_id == (id) && --fm_fail_at == 0 \ + ? (errno = (eno), (ret)) : +#define FM_FAIL_SETERR(id, eno) fm_fail_at > 0 && fm_fail_id == (id) && --fm_fail_at == 0 ? fm_seterr(fmp, eno) : + +#define fm_malloc(sz) (FM_FAIL(FM_FAIL_ID_MALLOC, NULL) malloc(sz)) +#define fm_realloc(ptr, sz) (FM_FAIL(FM_FAIL_ID_REALLOC, NULL) realloc(ptr, sz)) + +#else +#define FM_FAIL(id, ret) +#define FM_FAIL_ERRNO(id, eno, ret) +#define FM_FAIL_SETERR(id, eno) + +#define fm_malloc(sz) malloc(sz) +#define fm_realloc(ptr, sz) realloc(ptr, sz) +#endif + /* Helper to set `err` only if not already set, returning 0 always for convenience */ static int fm_seterr(struct filemem *restrict const fmp, const int err) { if (fmp->err == 0) { @@ -103,9 +130,8 @@ INTERNAL int zint_fm_open(struct filemem *restrict const fmp, struct zint_symbol #ifdef Z_NO_VSNPRINTF fmp->fp_null = NULL; #endif - if (fmp->flags & BARCODE_MEMORY_FILE) { - if (!(fmp->mem = (unsigned char *) malloc(FM_PAGE_SIZE))) { + if (!(fmp->mem = (unsigned char *) (FM_FAIL(FM_FAIL_ID_OPEN, NULL) fm_malloc(FM_PAGE_SIZE)))) { return fm_seterr(fmp, ENOMEM); } #ifdef ZINT_SANITIZEM /* Suppress clang -fsanitize=memory false positive */ @@ -128,7 +154,7 @@ INTERNAL int zint_fm_open(struct filemem *restrict const fmp, struct zint_symbol fmp->fp = stdout; return 1; } - if (!(fmp->fp = zint_out_fopen(symbol->outfile, mode))) { + if (!(fmp->fp = (FM_FAIL_ERRNO(FM_FAIL_ID_OPEN, EACCES, NULL) zint_out_fopen(symbol->outfile, mode)))) { return fm_seterr(fmp, errno); } return 1; @@ -159,7 +185,7 @@ static int fm_mem_expand(struct filemem *restrict const fmp, const size_t size) return fm_seterr(fmp, EOVERFLOW); } /* Protect against very large files & (Linux) OOM killer - cf `raster_malloc()` in "raster.c" */ - if (new_size > 0x40000000 /*1GB*/ || !(new_mem = (unsigned char *) realloc(fmp->mem, new_size))) { + if (new_size > 0x40000000 /*1GB*/ || !(new_mem = (unsigned char *) fm_realloc(fmp->mem, new_size))) { fm_clear_mem(fmp); return fm_seterr(fmp, new_size > 0x40000000 ? EINVAL : ENOMEM); } @@ -178,12 +204,13 @@ INTERNAL int zint_fm_write(const void *restrict ptr, const size_t size, const si if (fmp->err) { return 0; } + if (size == 0 || nitems == 0) { return 1; } if (fmp->flags & BARCODE_MEMORY_FILE) { const size_t tot_size = size * nitems; - if (tot_size / size != nitems) { + if ((FM_FAIL(FM_FAIL_ID_WRITE, 0) tot_size / size) != nitems) { return fm_seterr(fmp, EOVERFLOW); } if (!fm_mem_expand(fmp, tot_size)) { @@ -193,7 +220,7 @@ INTERNAL int zint_fm_write(const void *restrict ptr, const size_t size, const si fm_setpos(fmp, fmp->mempos + tot_size); return 1; } - if (fwrite(ptr, size, nitems, fmp->fp) != nitems) { + if ((FM_FAIL_ERRNO(FM_FAIL_ID_WRITE, EIO, 0) fwrite(ptr, size, nitems, fmp->fp)) != nitems) { return fm_seterr(fmp, errno); } return 1; @@ -206,14 +233,14 @@ INTERNAL int zint_fm_putc(const int ch, struct filemem *restrict const fmp) { return 0; } if (fmp->flags & BARCODE_MEMORY_FILE) { - if (!fm_mem_expand(fmp, 1)) { + if (!(FM_FAIL_SETERR(FM_FAIL_ID_PUTC, EIO) fm_mem_expand(fmp, 1))) { return 0; } fmp->mem[fmp->mempos] = (unsigned char) ch; fm_setpos(fmp, fmp->mempos + 1); return 1; } - if (fputc(ch, fmp->fp) == EOF) { + if ((FM_FAIL_ERRNO(FM_FAIL_ID_PUTC, EIO, EOF) fputc(ch, fmp->fp)) == EOF) { return fm_seterr(fmp, errno); } return 1; @@ -227,14 +254,14 @@ INTERNAL int zint_fm_puts(const char *str, struct filemem *restrict const fmp) { } if (fmp->flags & BARCODE_MEMORY_FILE) { const size_t len = strlen(str); - if (!fm_mem_expand(fmp, len)) { + if (!(FM_FAIL_SETERR(FM_FAIL_ID_PUTS, EIO) fm_mem_expand(fmp, len))) { return 0; } memcpy(fmp->mem + fmp->mempos, str, len); fm_setpos(fmp, fmp->mempos + len); return 1; } - if (fputs(str, fmp->fp) == EOF) { + if ((FM_FAIL_ERRNO(FM_FAIL_ID_PUTS, EIO, EOF) fputs(str, fmp->fp)) == EOF) { return fm_seterr(fmp, errno); } return 1; @@ -301,12 +328,12 @@ INTERNAL int zint_fm_printf(struct filemem *restrict const fmp, const char *fmt, } if (fmp->flags & BARCODE_MEMORY_FILE) { va_start(ap, fmt); - ret = fm_vprintf(fmp, fmt, ap); + ret = (FM_FAIL_SETERR(FM_FAIL_ID_PRINTF, EIO) fm_vprintf(fmp, fmt, ap)); va_end(ap); return ret; } va_start(ap, fmt); - ret = vfprintf(fmp->fp, fmt, ap) >= 0; + ret = (FM_FAIL_ERRNO(FM_FAIL_ID_PRINTF, EIO, -1) vfprintf(fmp->fp, fmt, ap)) >= 0; va_end(ap); return ret ? 1 : fm_seterr(fmp, errno); } @@ -323,8 +350,8 @@ INTERNAL int zint_fm_putsf(const char *prefix, const int dp, const float arg, st return 0; } if (prefix && *prefix) { - if (!zint_fm_puts(prefix, fmp)) { - return 0; + if (!(FM_FAIL_ERRNO(FM_FAIL_ID_PUTSF, EIO, 0) zint_fm_puts(prefix, fmp))) { + return fm_seterr(fmp, errno); } } @@ -345,7 +372,10 @@ INTERNAL int zint_fm_putsf(const char *prefix, const int dp, const float arg, st } } - return zint_fm_puts(buf, fmp); + if (!(FM_FAIL_ERRNO(FM_FAIL_ID_PUTSF, EIO, 0) zint_fm_puts(buf, fmp))) { + return fm_seterr(fmp, errno); + } + return 1; } /* `fclose()` if file, set `symbol->memfile` & `symbol->memfile_size` if memory, returning 1 on success, 0 on @@ -358,7 +388,7 @@ INTERNAL int zint_fm_close(struct filemem *restrict const fmp, struct zint_symbo return fm_seterr(fmp, EINVAL); } symbol->memfile_size = (int) fmp->mempos; - if ((size_t) symbol->memfile_size != fmp->mempos) { + if ((size_t) (FM_FAIL(FM_FAIL_ID_CLOSE, 0) symbol->memfile_size) != fmp->mempos) { fm_clear_mem(fmp); symbol->memfile_size = 0; return fm_seterr(fmp, EINVAL); @@ -375,12 +405,12 @@ INTERNAL int zint_fm_close(struct filemem *restrict const fmp, struct zint_symbo return fm_seterr(fmp, EINVAL); } if (fmp->flags & BARCODE_STDOUT) { - if (fflush(fmp->fp) != 0) { + if ((FM_FAIL_ERRNO(FM_FAIL_ID_CLOSE, EIO, EOF) fflush(fmp->fp)) != 0) { fmp->fp = NULL; return fm_seterr(fmp, errno); } } else { - if (fclose(fmp->fp) != 0) { + if ((FM_FAIL_ERRNO(FM_FAIL_ID_CLOSE, EIO, EOF) fclose(fmp->fp)) != 0) { fmp->fp = NULL; return fm_seterr(fmp, errno); } @@ -398,7 +428,8 @@ INTERNAL int zint_fm_seek(struct filemem *restrict const fmp, const long offset, if (fmp->flags & BARCODE_MEMORY_FILE) { const size_t start = whence == SEEK_SET ? 0 : whence == SEEK_CUR ? fmp->mempos : fmp->memend; const size_t new_pos = start + offset; - if ((offset > 0 && new_pos <= start) || (offset < 0 && new_pos >= start)) { /* Check for over/underflow */ + /* Check for over/underflow */ + if ((FM_FAIL(FM_FAIL_ID_SEEK, 1) (offset > 0 && new_pos <= start) || (offset < 0 && new_pos >= start))) { return fm_seterr(fmp, EINVAL); } if (!fm_mem_expand(fmp, new_pos)) { @@ -407,7 +438,7 @@ INTERNAL int zint_fm_seek(struct filemem *restrict const fmp, const long offset, fm_setpos(fmp, new_pos); return 1; } - if (fseek(fmp->fp, offset, whence) != 0) { + if ((FM_FAIL_ERRNO(FM_FAIL_ID_SEEK, EOVERFLOW, EOF) fseek(fmp->fp, offset, whence)) != 0) { return fm_seterr(fmp, errno); } return 1; @@ -421,13 +452,13 @@ INTERNAL long zint_fm_tell(struct filemem *restrict const fmp) { return -1; } if (fmp->flags & BARCODE_MEMORY_FILE) { - if (!fmp->mem) { + if (!(FM_FAIL(FM_FAIL_ID_TELL, NULL) fmp->mem)) { (void) fm_seterr(fmp, ENOMEM); return -1; } return (long) fmp->mempos; } - ret = ftell(fmp->fp); + ret = (FM_FAIL_ERRNO(FM_FAIL_ID_TELL, EOVERFLOW, -1) ftell(fmp->fp)); /* On many Linux distros `ftell()` returns LONG_MAX not -1 on error */ if (ret < 0 || ret == LONG_MAX) { (void) fm_seterr(fmp, errno); @@ -453,12 +484,12 @@ INTERNAL int zint_fm_flush(struct filemem *restrict const fmp) { return 0; } if (fmp->flags & BARCODE_MEMORY_FILE) { - if (!fmp->mem) { + if (!(FM_FAIL(FM_FAIL_ID_FLUSH, 0) fmp->mem)) { return fm_seterr(fmp, EINVAL); } return 1; } - if (fflush(fmp->fp) == EOF) { + if ((FM_FAIL_ERRNO(FM_FAIL_ID_FLUSH, EIO, EOF) fflush(fmp->fp)) == EOF) { return fm_seterr(fmp, errno); } return 1; diff --git a/backend/filemem.h b/backend/filemem.h index f096884b..3aada12f 100644 --- a/backend/filemem.h +++ b/backend/filemem.h @@ -90,6 +90,25 @@ INTERNAL int zint_fm_error(struct filemem *restrict const fmp); NOTE: don't use, included only for libpng compatibility */ INTERNAL int zint_fm_flush(struct filemem *restrict const fmp); +#ifdef ZINT_TEST +/* For testing `malloc()`/`realloc()` failures */ +#define FM_FAIL_ID_OPEN 1 +#define FM_FAIL_ID_WRITE 2 +#define FM_FAIL_ID_PUTC 3 +#define FM_FAIL_ID_PUTS 4 +#define FM_FAIL_ID_PRINTF 5 +#define FM_FAIL_ID_PUTSF 6 +#define FM_FAIL_ID_CLOSE 7 +#define FM_FAIL_ID_SEEK 8 +#define FM_FAIL_ID_TELL 9 +#define FM_FAIL_ID_FLUSH 10 +#define FM_FAIL_ID_MALLOC 11 +#define FM_FAIL_ID_REALLOC 12 + +INTERNAL void zint_test_fm_set_fail(const int id, const int at); +INTERNAL void zint_test_fm_set_alloc_fail(const int id, const int at); +#endif + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/backend/gif.c b/backend/gif.c index 673c05ce..4f89285c 100644 --- a/backend/gif.c +++ b/backend/gif.c @@ -30,6 +30,7 @@ */ /* SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include "common.h" @@ -163,14 +164,14 @@ static int gif_NextCode(struct gif_state *pState, unsigned char *pPixelValueCur, return 1; } -static int gif_lzw(struct gif_state *pState, unsigned char paletteBitSize) { +static void gif_lzw(struct gif_state *pState, unsigned char paletteBitSize) { unsigned char PixelValueCur; unsigned char CodeBits; unsigned short Pos; + assert(pState->pIn != pState->pInEnd); + /* > Get first data byte */ - if (pState->pIn == pState->pInEnd) - return 0; PixelValueCur = pState->map[*pState->pIn++]; /* Number of bits per data item (=pixel) * We need at least a value of 2, otherwise the cc and eoi code consumes @@ -217,7 +218,7 @@ static int gif_lzw(struct gif_state *pState, unsigned char paletteBitSize) { = (unsigned char) (pState->OutPosCur - pState->OutByteCountPos - 1); } pState->OutPosCur++; - return 1; + return; } /* Check for currently last code */ if (pState->FreeCode == (1U << CodeBits)) @@ -444,11 +445,7 @@ INTERNAL int zint_gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixe zint_fm_write(outbuf, 1, 10, State.fmp); /* Call lzw encoding */ - if (!gif_lzw(&State, paletteBitSize)) { - free(State.pOut); - (void) zint_fm_close(State.fmp, symbol); - return z_errtxt(ZINT_ERROR_MEMORY, symbol, 613, "Insufficient memory for GIF LZW buffer"); - } + gif_lzw(&State, paletteBitSize); zint_fm_write(State.pOut, 1, State.OutPosCur, State.fmp); free(State.pOut); diff --git a/backend/gridmtx.c b/backend/gridmtx.c index 66f1a9ec..a7f64270 100644 --- a/backend/gridmtx.c +++ b/backend/gridmtx.c @@ -781,14 +781,14 @@ static int gm_encode_segs(const unsigned int ddata[], const struct zint_seg segs static void gm_add_ecc(const char binary[], const int data_posn, const int layers, const int ecc_level, unsigned char word[]) { - int data_cw, i, j, wp, p; + int data_cws, i, j, wp, p; int n1, b1, n2, b2, e1, b3, e2; int block_size, ecc_size; unsigned char data[1320], block[130]; unsigned char data_block[115], ecc_block[70]; rs_t rs; - data_cw = gm_data_codewords[((layers - 1) * 5) + (ecc_level - 1)]; + data_cws = gm_data_cws[layers - 1][ecc_level - 1]; for (i = 0; i < 1320; i++) { data[i] = 0; @@ -805,7 +805,7 @@ static void gm_add_ecc(const char binary[], const int data_posn, const int layer /* Add padding codewords */ data[data_posn] = 0x00; - for (i = (data_posn + 1); i < data_cw; i++) { + for (i = (data_posn + 1); i < data_cws; i++) { if (i & 1) { data[i] = 0x7E; } else { @@ -814,13 +814,13 @@ static void gm_add_ecc(const char binary[], const int data_posn, const int layer } /* Get block sizes */ - n1 = gm_n1[(layers - 1)]; - b1 = gm_b1[(layers - 1)]; + n1 = gm_n1[layers - 1]; + b1 = gm_b1[layers - 1]; n2 = n1 - 1; - b2 = gm_b2[(layers - 1)]; - e1 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4)]; - b3 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 1]; - e2 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 2]; + b2 = gm_b2[layers - 1]; + e1 = gm_e1b3e2[layers - 1][ecc_level - 1][0]; + b3 = gm_e1b3e2[layers - 1][ecc_level - 1][1]; + e2 = gm_e1b3e2[layers - 1][ecc_level - 1][2]; zint_rs_init_gf(&rs, 0x89); @@ -921,7 +921,7 @@ static void gm_place_data_in_grid(const unsigned char word[], char grid[], const for (y = 0; y < modules; y++) { for (x = 0; x < modules; x++) { - macromodule = gm_macro_matrix[((y + offset) * 27) + (x + offset)]; + macromodule = gm_macro_matrix[y + offset][x + offset]; gm_place_macromodule(grid, x, y, word[macromodule * 2], word[(macromodule * 2) + 1], size); } } @@ -979,13 +979,13 @@ static void gm_place_layer_id(char *grid, const int size, const int layers, cons INTERNAL int zint_gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { int warn_number = 0; int size, modules, error_number; - int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level; + int auto_layers, min_layers, layers, rec_ecc_level, min_rec_ecc_level, ecc_level; int x, y, i; int full_multibyte; char binary[9300]; - int data_cw, input_latch = 0; + int data_cws; unsigned char word[1460] = {0}; - int data_max, reader = 0; + int reader = 0; const struct zint_structapp *p_structapp = NULL; int size_squared; int bin_len; @@ -1079,95 +1079,77 @@ INTERNAL int zint_gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], } /* Determine the size of the symbol */ - data_cw = bin_len / 7; /* Binary length always a multiple of 7 */ + data_cws = bin_len / 7; /* Binary length always a multiple of 7 */ auto_layers = 13; for (i = 12; i > 0; i--) { - if (gm_recommend_cw[(i - 1)] >= data_cw) { + if (gm_recommend_cws[i - 1] >= data_cws) { auto_layers = i; } } min_layers = 13; for (i = 12; i > 0; i--) { - if (gm_max_cw[(i - 1)] >= data_cw) { + if (gm_max_cws[i - 1] >= data_cws) { min_layers = i; } } layers = auto_layers; if (symbol->option_2 >= 1 && symbol->option_2 <= 13) { - input_latch = 1; if (symbol->option_2 >= min_layers) { layers = symbol->option_2; } else { return ZEXT z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 534, "Input too long for Version %1$d, requires %2$d codewords (maximum %3$d)", - symbol->option_2, data_cw, gm_max_cw[symbol->option_2 - 1]); + symbol->option_2, data_cws, gm_max_cws[symbol->option_2 - 1]); } } - auto_ecc_level = 3; + /* Table 11 - Recommended error correction levels - Recommended ECL */ + rec_ecc_level = 3; if (layers == 1) { - auto_ecc_level = 5; + rec_ecc_level = 5; } else if (layers == 2 || layers == 3) { - auto_ecc_level = 4; + rec_ecc_level = 4; } - ecc_level = auto_ecc_level; + ecc_level = rec_ecc_level; - min_ecc_level = 1; + /* Table 11 - Recommended error correction levels - Minimum Recommended ECL */ + min_rec_ecc_level = 1; if (layers == 1) { - min_ecc_level = 4; + min_rec_ecc_level = 4; } else if (layers == 2) { - min_ecc_level = 2; + min_rec_ecc_level = 2; } if (symbol->option_1 >= 1 && symbol->option_1 <= 5) { - if (symbol->option_1 >= min_ecc_level) { + /* Silently ignoring user-specified if less than minimum recommended */ + if (symbol->option_1 >= min_rec_ecc_level) { ecc_level = symbol->option_1; } else { - ecc_level = min_ecc_level; + ecc_level = min_rec_ecc_level; } } - if (data_cw > gm_data_codewords[5 * (layers - 1) + (ecc_level - 1)]) { - /* If layers user-specified (option_2), try reducing ECC level first */ - if (input_latch && ecc_level > min_ecc_level) { - do { - ecc_level--; - } while (data_cw > gm_data_codewords[5 * (layers - 1) + (ecc_level - 1)] && ecc_level > min_ecc_level); - } - while (data_cw > gm_data_codewords[5 * (layers - 1) + (ecc_level - 1)] && layers < 13) { - layers++; - } - /* ECC min level 1 for layers > 2 */ - while (data_cw > gm_data_codewords[5 * (layers - 1) + (ecc_level - 1)] && ecc_level > 1) { + if (data_cws > gm_data_cws[layers - 1][ecc_level - 1]) { + /* Reduce ECC level */ + const int min_ecc_level = layers > 1 ? 1 : 2; /* ECL 1 in version 1 symbols is invalid */ + do { ecc_level--; - } + } while (data_cws > gm_data_cws[layers - 1][ecc_level - 1] && ecc_level > min_ecc_level); + assert(data_cws <= gm_data_cws[layers - 1][ecc_level - 1]); } - data_max = 1313; - switch (ecc_level) { - case 2: data_max = 1167; break; - case 3: data_max = 1021; break; - case 4: data_max = 875; break; - case 5: data_max = 729; break; - } - - if (data_cw > data_max) { - return ZEXT z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 532, - "Input too long for ECC level %1$d, requires %2$d codewords (maximum %3$d)", - ecc_level, data_cw, data_max); - } if (debug_print) { - printf("Layers: %d, ECC level: %d, Data Codewords: %d\n", layers, ecc_level, data_cw); + printf("Layers: %d, ECC level: %d, Data Codewords: %d\n", layers, ecc_level, data_cws); } /* Feedback options */ symbol->option_1 = ecc_level; symbol->option_2 = layers; - gm_add_ecc(binary, data_cw, layers, ecc_level, word); + gm_add_ecc(binary, data_cws, layers, ecc_level, word); #ifdef ZINT_TEST - if (symbol->debug & ZINT_DEBUG_TEST) z_debug_test_codeword_dump(symbol, word, data_cw); + if (symbol->debug & ZINT_DEBUG_TEST) z_debug_test_codeword_dump(symbol, word, data_cws); #endif size = 6 + (layers * 12); modules = 1 + (layers * 2); diff --git a/backend/gridmtx.h b/backend/gridmtx.h index c5d70bee..e1012dbf 100644 --- a/backend/gridmtx.h +++ b/backend/gridmtx.h @@ -1,7 +1,7 @@ /* gridmtx.h - definitions for Grid Matrix */ /* libzint - the open source barcode library - Copyright (C) 2009-2022 Robin Stuart + Copyright (C) 2009-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -33,148 +33,99 @@ #ifndef Z_GRIDMTX_H #define Z_GRIDMTX_H +/* From Table 7 - Encoding of control characters */ static const char gm_shift_set[] = { - /* From Table 7 - Encoding of control characters */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* NULL -> SI */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* DLE -> US */ - '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', - ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' + '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', + ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' }; -static const unsigned short gm_recommend_cw[] = { - 9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021 +static const short gm_recommend_cws[13] = { + 9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021 }; -static const unsigned short gm_max_cw[] = { +static const short gm_max_cws[13] = { 11, 40, 79, 146, 218, 305, 405, 521, 650, 794, 953, 1125, 1313 }; -static const unsigned short gm_data_codewords[] = { - 0, 15, 13, 11, 9, - 45, 40, 35, 30, 25, - 89, 79, 69, 59, 49, - 146, 130, 114, 98, 81, - 218, 194, 170, 146, 121, - 305, 271, 237, 203, 169, - 405, 360, 315, 270, 225, - 521, 463, 405, 347, 289, - 650, 578, 506, 434, 361, - 794, 706, 618, 530, 441, - 953, 847, 741, 635, 529, - 1125, 1000, 875, 750, 625, - 1313, 1167, 1021, 875, 729 +static const short gm_data_cws[13][5] = { + { 0, 15, 13, 11, 9 }, /* 1 */ + { 45, 40, 35, 30, 25 }, /* 2 */ + { 89, 79, 69, 59, 49 }, /* 3 */ + { 146, 130, 114, 98, 81 }, /* 4 */ + { 218, 194, 170, 146, 121 }, /* 5 */ + { 305, 271, 237, 203, 169 }, /* 6 */ + { 405, 360, 315, 270, 225 }, /* 7 */ + { 521, 463, 405, 347, 289 }, /* 8 */ + { 650, 578, 506, 434, 361 }, /* 9 */ + { 794, 706, 618, 530, 441 }, /* 10 */ + { 953, 847, 741, 635, 529 }, /* 11 */ + { 1125, 1000, 875, 750, 625 }, /* 12 */ + { 1313, 1167, 1021, 875, 729 }, /* 13 */ }; -static const char gm_n1[] = { +/* Table A.1 N1 */ +static const char gm_n1[13] = { 18, 50, 98, 81, 121, 113, 113, 116, 121, 126, 118, 125, 122 }; -static const char gm_b1[] = { +/* Table A.1 B1 */ +static const char gm_b1[13] = { 1, 1, 1, 2, 2, 2, 2, 3, 2, 7, 5, 10, 6 }; -static const char gm_b2[] = { +/* Table A.1 B2 */ +static const char gm_b2[13] = { 0, 0, 0, 0, 0, 1, 2, 2, 4, 0, 4, 0, 6 }; -/* Values from table A.1 */ -static const char gm_ebeb[] = { - /* E1 B3 E2 B4 */ - 0, 0, 0, 0, /* version 1 */ - 3, 1, 0, 0, - 5, 1, 0, 0, - 7, 1, 0, 0, - 9, 1, 0, 0, - 5, 1, 0, 0, /* version 2 */ - 10, 1, 0, 0, - 15, 1, 0, 0, - 20, 1, 0, 0, - 25, 1, 0, 0, - 9, 1, 0, 0, /* version 3 */ - 19, 1, 0, 0, - 29, 1, 0, 0, - 39, 1, 0, 0, - 49, 1, 0, 0, - 8, 2, 0, 0, /* version 4 */ - 16, 2, 0, 0, - 24, 2, 0, 0, - 32, 2, 0, 0, - 41, 1, 40, 1, - 12, 2, 0, 0, /* version 5 */ - 24, 2, 0, 0, - 36, 2, 0, 0, - 48, 2, 0, 0, - 61, 1, 60, 1, - 11, 3, 0, 0, /* version 6 */ - 23, 1, 22, 2, - 34, 2, 33, 1, - 45, 3, 0, 0, - 57, 1, 56, 2, - 12, 1, 11, 3, /* version 7 */ - 23, 2, 22, 2, - 34, 3, 33, 1, - 45, 4, 0, 0, - 57, 1, 56, 3, - 12, 2, 11, 3, /* version 8 */ - 23, 5, 0, 0, - 35, 3, 34, 2, - 47, 1, 46, 4, - 58, 4, 57, 1, - 12, 6, 0, 0, /* version 9 */ - 24, 6, 0, 0, - 36, 6, 0, 0, - 48, 6, 0, 0, - 61, 1, 60, 5, - 13, 4, 12, 3, /* version 10 */ - 26, 1, 25, 6, - 38, 5, 37, 2, - 51, 2, 50, 5, - 63, 7, 0, 0, - 12, 6, 11, 3, /* version 11 */ - 24, 4, 23, 5, - 36, 2, 35, 7, - 47, 9, 0, 0, - 59, 7, 58, 2, - 13, 5, 12, 5, /* version 12 */ - 25, 10, 0, 0, - 38, 5, 37, 5, - 50, 10, 0, 0, - 63, 5, 62, 5, - 13, 1, 12, 11, /* version 13 */ - 25, 3, 24, 9, - 37, 5, 36, 7, - 49, 7, 48, 5, - 61, 9, 60, 3 +/* Table A.1 E1, B3, E2 */ +static const char gm_e1b3e2[13][5][3] = { + /* E1 B3 E2 */ + { { 0, 0, 0 }, { 3, 1, 0 }, { 5, 1, 0 }, { 7, 1, 0 }, { 9, 1, 0 } }, /* 1 */ + { { 5, 1, 0 }, { 10, 1, 0 }, { 15, 1, 0 }, { 20, 1, 0 }, { 25, 1, 0 } }, /* 2 */ + { { 9, 1, 0 }, { 19, 1, 0 }, { 29, 1, 0 }, { 39, 1, 0 }, { 49, 1, 0 } }, /* 3 */ + { { 8, 2, 0 }, { 16, 2, 0 }, { 24, 2, 0 }, { 32, 2, 0 }, { 41, 1, 40 } }, /* 4 */ + { { 12, 2, 0 }, { 24, 2, 0 }, { 36, 2, 0 }, { 48, 2, 0 }, { 61, 1, 60 } }, /* 5 */ + { { 11, 3, 0 }, { 23, 1, 22 }, { 34, 2, 33 }, { 45, 3, 0 }, { 57, 1, 56 } }, /* 6 */ + { { 12, 1, 11 }, { 23, 2, 22 }, { 34, 3, 33 }, { 45, 4, 0 }, { 57, 1, 56 } }, /* 7 */ + { { 12, 2, 11 }, { 23, 5, 0 }, { 35, 3, 34 }, { 47, 1, 46 }, { 58, 4, 57 } }, /* 8 */ + { { 12, 6, 0 }, { 24, 6, 0 }, { 36, 6, 0 }, { 48, 6, 0 }, { 61, 1, 60 } }, /* 9 */ + { { 13, 4, 12 }, { 26, 1, 25 }, { 38, 5, 37 }, { 51, 2, 50 }, { 63, 7, 0 } }, /* 10 */ + { { 12, 6, 11 }, { 24, 4, 23 }, { 36, 2, 35 }, { 47, 9, 0 }, { 59, 7, 58 } }, /* 11 */ + { { 13, 5, 12 }, { 25, 10, 0 }, { 38, 5, 37 }, { 50, 10, 0 }, { 63, 5, 62 } }, /* 12 */ + { { 13, 1, 12 }, { 25, 3, 24 }, { 37, 5, 36 }, { 49, 7, 48 }, { 61, 9, 60 } } /* 13 */ }; -static const unsigned short gm_macro_matrix[] = { - 728, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 727, 624, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 651, - 726, 623, 528, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 553, 652, - 725, 622, 527, 440, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 463, 554, 653, - 724, 621, 526, 439, 360, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 381, 464, 555, 654, - 723, 620, 525, 438, 359, 288, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 307, 382, 465, 556, 655, - 722, 619, 524, 437, 358, 287, 224, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 241, 308, 383, 466, 557, 656, - 721, 618, 523, 436, 357, 286, 223, 168, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 183, 242, 309, 384, 467, 558, 657, - 720, 617, 522, 435, 356, 285, 222, 167, 120, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 133, 184, 243, 310, 385, 468, 559, 658, - 719, 616, 521, 434, 355, 284, 221, 166, 119, 80, 49, 50, 51, 52, 53, 54, 55, 56, 91, 134, 185, 244, 311, 386, 469, 560, 659, - 718, 615, 520, 433, 354, 283, 220, 165, 118, 79, 48, 25, 26, 27, 28, 29, 30, 57, 92, 135, 186, 245, 312, 387, 470, 561, 660, - 717, 614, 519, 432, 353, 282, 219, 164, 117, 78, 47, 24, 9, 10, 11, 12, 31, 58, 93, 136, 187, 246, 313, 388, 471, 562, 661, - 716, 613, 518, 431, 352, 281, 218, 163, 116, 77, 46, 23, 8, 1, 2, 13, 32, 59, 94, 137, 188, 247, 314, 389, 472, 563, 662, - 715, 612, 517, 430, 351, 280, 217, 162, 115, 76, 45, 22, 7, 0, 3, 14, 33, 60, 95, 138, 189, 248, 315, 390, 473, 564, 663, - 714, 611, 516, 429, 350, 279, 216, 161, 114, 75, 44, 21, 6, 5, 4, 15, 34, 61, 96, 139, 190, 249, 316, 391, 474, 565, 664, - 713, 610, 515, 428, 349, 278, 215, 160, 113, 74, 43, 20, 19, 18, 17, 16, 35, 62, 97, 140, 191, 250, 317, 392, 475, 566, 665, - 712, 609, 514, 427, 348, 277, 214, 159, 112, 73, 42, 41, 40, 39, 38, 37, 36, 63, 98, 141, 192, 251, 318, 393, 476, 567, 666, - 711, 608, 513, 426, 347, 276, 213, 158, 111, 72, 71, 70, 69, 68, 67, 66, 65, 64, 99, 142, 193, 252, 319, 394, 477, 568, 667, - 710, 607, 512, 425, 346, 275, 212, 157, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 143, 194, 253, 320, 395, 478, 569, 668, - 709, 606, 511, 424, 345, 274, 211, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 195, 254, 321, 396, 479, 570, 669, - 708, 605, 510, 423, 344, 273, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 255, 322, 397, 480, 571, 670, - 707, 604, 509, 422, 343, 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 323, 398, 481, 572, 671, - 706, 603, 508, 421, 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, 399, 482, 573, 672, - 705, 602, 507, 420, 419, 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 483, 574, 673, - 704, 601, 506, 505, 504, 503, 502, 501, 500, 499, 498, 497, 496, 495, 494, 493, 492, 491, 490, 489, 488, 487, 486, 485, 484, 575, 674, - 703, 600, 599, 598, 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, 587, 586, 585, 584, 583, 582, 581, 580, 579, 578, 577, 576, 675, - 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, 676, +static const short gm_macro_matrix[27][27] = { + { 728, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650 }, + { 727, 624, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 651 }, + { 726, 623, 528, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 553, 652 }, + { 725, 622, 527, 440, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 463, 554, 653 }, + { 724, 621, 526, 439, 360, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 381, 464, 555, 654 }, + { 723, 620, 525, 438, 359, 288, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 307, 382, 465, 556, 655 }, + { 722, 619, 524, 437, 358, 287, 224, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 241, 308, 383, 466, 557, 656 }, + { 721, 618, 523, 436, 357, 286, 223, 168, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 183, 242, 309, 384, 467, 558, 657 }, + { 720, 617, 522, 435, 356, 285, 222, 167, 120, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 133, 184, 243, 310, 385, 468, 559, 658 }, + { 719, 616, 521, 434, 355, 284, 221, 166, 119, 80, 49, 50, 51, 52, 53, 54, 55, 56, 91, 134, 185, 244, 311, 386, 469, 560, 659 }, + { 718, 615, 520, 433, 354, 283, 220, 165, 118, 79, 48, 25, 26, 27, 28, 29, 30, 57, 92, 135, 186, 245, 312, 387, 470, 561, 660 }, + { 717, 614, 519, 432, 353, 282, 219, 164, 117, 78, 47, 24, 9, 10, 11, 12, 31, 58, 93, 136, 187, 246, 313, 388, 471, 562, 661 }, + { 716, 613, 518, 431, 352, 281, 218, 163, 116, 77, 46, 23, 8, 1, 2, 13, 32, 59, 94, 137, 188, 247, 314, 389, 472, 563, 662 }, + { 715, 612, 517, 430, 351, 280, 217, 162, 115, 76, 45, 22, 7, 0, 3, 14, 33, 60, 95, 138, 189, 248, 315, 390, 473, 564, 663 }, + { 714, 611, 516, 429, 350, 279, 216, 161, 114, 75, 44, 21, 6, 5, 4, 15, 34, 61, 96, 139, 190, 249, 316, 391, 474, 565, 664 }, + { 713, 610, 515, 428, 349, 278, 215, 160, 113, 74, 43, 20, 19, 18, 17, 16, 35, 62, 97, 140, 191, 250, 317, 392, 475, 566, 665 }, + { 712, 609, 514, 427, 348, 277, 214, 159, 112, 73, 42, 41, 40, 39, 38, 37, 36, 63, 98, 141, 192, 251, 318, 393, 476, 567, 666 }, + { 711, 608, 513, 426, 347, 276, 213, 158, 111, 72, 71, 70, 69, 68, 67, 66, 65, 64, 99, 142, 193, 252, 319, 394, 477, 568, 667 }, + { 710, 607, 512, 425, 346, 275, 212, 157, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 143, 194, 253, 320, 395, 478, 569, 668 }, + { 709, 606, 511, 424, 345, 274, 211, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 195, 254, 321, 396, 479, 570, 669 }, + { 708, 605, 510, 423, 344, 273, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 255, 322, 397, 480, 571, 670 }, + { 707, 604, 509, 422, 343, 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 323, 398, 481, 572, 671 }, + { 706, 603, 508, 421, 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, 399, 482, 573, 672 }, + { 705, 602, 507, 420, 419, 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 483, 574, 673 }, + { 704, 601, 506, 505, 504, 503, 502, 501, 500, 499, 498, 497, 496, 495, 494, 493, 492, 491, 490, 489, 488, 487, 486, 485, 484, 575, 674 }, + { 703, 600, 599, 598, 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, 587, 586, 585, 584, 583, 582, 581, 580, 579, 578, 577, 576, 675 }, + { 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, 676 } }; /* vim: set ts=4 sw=4 et : */ diff --git a/backend/gs1.c b/backend/gs1.c index d3b754bb..1c0f27d7 100644 --- a/backend/gs1.c +++ b/backend/gs1.c @@ -78,9 +78,8 @@ static int gs1_numeric(const unsigned char *data, int data_len, int offset, int data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (data_len) { const unsigned char *d = data + offset; @@ -128,9 +127,8 @@ static int gs1_cset82(const unsigned char *data, int data_len, int offset, int m data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (data_len) { const unsigned char *d = data + offset; @@ -155,9 +153,8 @@ static int gs1_cset39(const unsigned char *data, int data_len, int offset, int m data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (data_len) { const unsigned char *d = data + offset; @@ -182,9 +179,8 @@ static int gs1_cset64(const unsigned char *data, int data_len, int offset, int m data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (data_len) { const unsigned char *d = data + offset; @@ -215,9 +211,8 @@ static int gs1_csum(const unsigned char *data, int data_len, int offset, int min data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { const unsigned char *d = data + offset; @@ -250,9 +245,9 @@ static int gs1_csumalpha(const unsigned char *data, int data_len, int offset, in data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ + /* Do this check separately for backward compatibility */ if (data_len && data_len < 2) { *p_err_no = 4; @@ -294,9 +289,9 @@ static int gs1_gcppos1(const unsigned char *data, int data_len, int offset, int data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ + /* Do this check separately for backward compatibility */ if (data_len && data_len < 2) { *p_err_no = 4; @@ -652,13 +647,10 @@ static int gs1_iso4217(const unsigned char *data, int data_len, int offset, int static int gs1_pcenc(const unsigned char *data, int data_len, int offset, int min, int max, int *p_err_no, int *p_err_posn, char err_msg[50], const int length_only) { - static const char hex_chars[] = "0123456789ABCDEFabcdef"; - data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { const unsigned char *d = data + offset; @@ -671,7 +663,8 @@ static int gs1_pcenc(const unsigned char *data, int data_len, int offset, int mi *p_err_posn = (int) (d - data) + 1; return gs1_err_msg_cpy_nochk(err_msg, "Invalid % escape"); } - if (strchr(hex_chars, *(++d)) == NULL || strchr(hex_chars, *(++d)) == NULL) { + d += 2; + if (!z_isxdigit(*(d - 1)) || !z_isxdigit(*d)) { *p_err_no = 3; *p_err_posn = (int) (d - data) + 1; return gs1_err_msg_cpy_nochk(err_msg, "Invalid character for percent encoding"); @@ -690,9 +683,8 @@ static int gs1_yesno(const unsigned char *data, int data_len, int offset, int mi data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { if (data[offset] != '0' && data[offset] != '1') { @@ -713,9 +705,8 @@ static int gs1_importeridx(const unsigned char *data, int data_len, int offset, data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { const unsigned char *d = data + offset; @@ -737,9 +728,8 @@ static int gs1_nonzero(const unsigned char *data, int data_len, int offset, int data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { const int val = z_to_int(data + offset, data_len > max ? max : data_len); @@ -761,9 +751,8 @@ static int gs1_winding(const unsigned char *data, int data_len, int offset, int data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { if (data[offset] != '0' && data[offset] != '1' && data[offset] != '9') { @@ -783,9 +772,8 @@ static int gs1_zero(const unsigned char *data, int data_len, int offset, int min data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { if (data[offset] != '0') { @@ -843,9 +831,9 @@ static int gs1_iban(const unsigned char *data, int data_len, int offset, int min data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ + /* Do this check separately for backward compatibility */ if (data_len && data_len < 5) { *p_err_no = 4; @@ -920,9 +908,8 @@ static int gs1_nozeroprefix(const unsigned char *data, int data_len, int offset, data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { /* GS1 General Specifications Release 26.0 3.9.11 "The C/P serial number SHALL NOT begin with a "0" digit, @@ -1026,9 +1013,9 @@ static int gs1_couponcode(const unsigned char *data, int data_len, int offset, i data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ + /* Do separately for backward compatibility */ if (data_len && data_len < min_req_len) { *p_err_no = 4; @@ -1232,9 +1219,9 @@ static int gs1_couponposoffer(const unsigned char *data, int data_len, int offse data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ + /* Do separately for backward compatibility */ if (data_len && (data_len < min_len || data_len > max_len)) { *p_err_no = 4; @@ -1365,9 +1352,8 @@ static int gs1_hyphen(const unsigned char *data, int data_len, int offset, int m data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { const unsigned char *d = data + offset; @@ -1392,9 +1378,8 @@ static int gs1_iso5218(const unsigned char *data, int data_len, int offset, int data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { /* 0 = Not known, 1 = Male, 2 = Female, 9 = Not applicable */ @@ -1414,9 +1399,8 @@ static int gs1_posinseqslash(const unsigned char *data, int data_len, int offset data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { const unsigned char *d = data + offset; @@ -1478,9 +1462,8 @@ static int gs1_hasnondigit(const unsigned char *data, int data_len, int offset, data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { const unsigned char *d = data + offset; @@ -1561,9 +1544,8 @@ static int gs1_packagetype(const unsigned char *data, int data_len, int offset, data_len = data_len < offset ? 0 : data_len - offset; - if (data_len < min) { - return 0; - } + (void)min; + assert(data_len >= min); /* Min checked before being called */ if (!length_only && data_len) { /* Adapted from GS1 Syntax Dictionary and Linters diff --git a/backend/hanxin.c b/backend/hanxin.c index ecd0c250..70b2dbe5 100644 --- a/backend/hanxin.c +++ b/backend/hanxin.c @@ -1531,8 +1531,8 @@ INTERNAL int zint_hanxin(struct zint_symbol *symbol, struct zint_seg segs[], con if (!done) { /* Try GB 18030 */ int error_number = zint_gb18030_utf8(symbol, local_segs[i].source, &local_segs[i].length, dd); - if (error_number != 0) { - return error_number; + if (error_number != 0) { /* Shouldn't happen */ + return error_number; /* Not reached */ } if (local_segs[i].eci != 32) { warn_number = z_errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 543, diff --git a/backend/library.c b/backend/library.c index cea5097c..9ec0c305 100644 --- a/backend/library.c +++ b/backend/library.c @@ -245,6 +245,26 @@ INTERNAL int zint_plot_raster(struct zint_symbol *symbol, int rotate_angle, int /* Plot to EMF/EPS/SVG */ INTERNAL int zint_plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type); +/* Helper to convert `error_number` based on `warn_level` */ +static int error_warn_level(int error_number, struct zint_symbol *symbol) { + if (error_number < ZINT_ERROR && (symbol->warn_level & 0xFF) == WARN_FAIL_ALL) { + /* Convert to error equivalent */ + if (error_number == ZINT_WARN_NONCOMPLIANT) { + error_number = ZINT_ERROR_NONCOMPLIANT; + } else if (error_number == ZINT_WARN_USES_ECI) { + error_number = ZINT_ERROR_USES_ECI; + } else if (error_number == ZINT_WARN_INVALID_OPTION) { + error_number = ZINT_ERROR_INVALID_OPTION; + } else if (error_number == ZINT_WARN_HRT_TRUNCATED) { + error_number = ZINT_ERROR_HRT_TRUNCATED; + } else { /* Shouldn't happen */ + assert(0); /* Not reached */ + error_number = ZINT_ERROR_ENCODING_PROBLEM; + } + } + return error_number; +} + /* Prefix error message with Error/Warning */ static int error_tag(int error_number, struct zint_symbol *symbol, const int err_id, const char *error_string) { @@ -252,21 +272,7 @@ static int error_tag(int error_number, struct zint_symbol *symbol, const int err if (error_string) { z_errtxt(0, symbol, err_id, error_string); } - if (error_number < ZINT_ERROR && symbol->warn_level == WARN_FAIL_ALL) { - /* Convert to error equivalent */ - if (error_number == ZINT_WARN_NONCOMPLIANT) { - error_number = ZINT_ERROR_NONCOMPLIANT; - } else if (error_number == ZINT_WARN_USES_ECI) { - error_number = ZINT_ERROR_USES_ECI; - } else if (error_number == ZINT_WARN_INVALID_OPTION) { - error_number = ZINT_ERROR_INVALID_OPTION; - } else if (error_number == ZINT_WARN_HRT_TRUNCATED) { - error_number = ZINT_ERROR_HRT_TRUNCATED; - } else { /* Shouldn't happen */ - assert(0); /* Not reached */ - error_number = ZINT_ERROR_ENCODING_PROBLEM; - } - } + error_number = error_warn_level(error_number, symbol); if (error_number >= ZINT_ERROR) { z_errtxt_adj(0, symbol, "Error %s", NULL); } else { @@ -366,6 +372,7 @@ static int supports_non_iso8859_1(const int symbology) { /* Returns 1 if `symbol` can process EXTRA_ESCAPE_MODE */ static int supports_extra_escape_mode(const struct zint_symbol *const symbol) { + /* Note if change this must change copy in "frontend/main.c" */ return symbol->symbology == BARCODE_CODE128 || ((symbol->symbology == BARCODE_AZTEC || symbol->symbology == BARCODE_DATAMATRIX) && (symbol->input_mode & 0x07) != GS1_MODE); @@ -1206,50 +1213,48 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ } if ((symbol->input_mode & 0x07) == GS1_MODE || check_force_gs1(symbol->symbology)) { - if (gs1_compliant(symbol->symbology)) { - /* Reduce input for composite and non-forced symbologies, others (GS1_128 and DBAR_EXP based) will - handle it themselves */ - const int is_composite = z_is_composite(symbol->symbology); + /* Reduce input for composite and non-forced symbologies, others (GS1_128 and DBAR_EXP based) will + handle it themselves */ + const int is_composite = z_is_composite(symbol->symbology); - /* Deal with any ECI first */ - if (symbol->eci) { - /* Check that ECI is at least CSET82 (an ASCII Invariant subset) compatible */ - if (symbol->eci == 25 || (symbol->eci >= 33 && symbol->eci <= 35)) { /* UTF-16/32 BE/LE */ - return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 856, - "In GS1 mode ECI must be ASCII compatible"); - } - /* Note not warning here that ECI is not supported in GS1 mode, leaving it up to individual - symbologies, as standards are inconsistent in mentioning it */ + assert(gs1_compliant(symbol->symbology)); + + /* Deal with any ECI first */ + if (symbol->eci) { + /* Check that ECI is at least CSET82 (an ASCII Invariant subset) compatible */ + if (symbol->eci == 25 || (symbol->eci >= 33 && symbol->eci <= 35)) { /* UTF-16/32 BE/LE */ + return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 856, "In GS1 mode ECI must be ASCII compatible"); } + /* Note not warning here that ECI is not supported in GS1 mode, leaving it up to individual + symbologies, as standards are inconsistent in mentioning it */ + } - if (is_composite || !check_force_gs1(symbol->symbology)) { - unsigned char *reduced = (unsigned char *) z_alloca(local_segs[0].length + 1); - error_number = zint_gs1_verify(symbol, local_segs[0].source, local_segs[0].length, reduced, - &local_segs[0].length, 0 /*set_hrt*/); - if (error_number) { + if (is_composite || !check_force_gs1(symbol->symbology)) { + unsigned char *reduced = (unsigned char *) z_alloca(local_segs[0].length + 1); + error_number = zint_gs1_verify(symbol, local_segs[0].source, local_segs[0].length, reduced, + &local_segs[0].length, 0 /*set_hrt*/); + if (error_number) { #ifdef ZINT_HAVE_GS1SE - if (is_composite && !(symbol->input_mode & GS1SYNTAXENGINE_MODE)) { - z_errtxt_adj(0, symbol, "%1$s%2$s", " (2D component)"); - } + if (is_composite && !(symbol->input_mode & GS1SYNTAXENGINE_MODE)) { + z_errtxt_adj(0, symbol, "%1$s%2$s", " (2D component)"); + } #else - if (is_composite) { - z_errtxt_adj(0, symbol, "%1$s%2$s", " (2D component)"); - } + if (is_composite) { + z_errtxt_adj(0, symbol, "%1$s%2$s", " (2D component)"); + } #endif - error_number = error_tag(error_number, symbol, -1, NULL); - if (error_number >= ZINT_ERROR) { - return error_number; - } - warn_number = error_number; /* Override any previous warning (errtxt has been overwritten) */ - } - memcpy(local_segs[0].source, reduced, local_segs[0].length + 1); /* Include terminating NUL */ - /* Set content segs for non-composites (composites set their own content segs) */ - if (!is_composite && content_segs && z_ct_cpy(symbol, reduced, local_segs[0].length)) { - return error_tag(ZINT_ERROR_MEMORY, symbol, -1, NULL); /* `z_ct_cpy()` only fails with OOM */ + error_number = error_warn_level(error_number, symbol); + if (error_number >= ZINT_ERROR) { + return error_tag(error_number, symbol, -1, NULL); } + warn_number = error_number; /* Override any previous warning (errtxt has been overwritten) */ + symbol->warn_level |= (warn_number << 8); /* Hack to let `zint_composite()` know */ + } + memcpy(local_segs[0].source, reduced, local_segs[0].length + 1); /* Include terminating NUL */ + /* Set content segs for non-composites (composites set their own content segs) */ + if (!is_composite && content_segs && z_ct_cpy(symbol, reduced, local_segs[0].length)) { + return error_tag(ZINT_ERROR_MEMORY, symbol, -1, NULL); /* `z_ct_cpy()` only fails with OOM */ } - } else { - return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 210, "Selected symbology does not support GS1 mode"); } } else if (content_segs && supports_non_iso8859_1(symbol->symbology)) { /* Copy these as-is. The content seg `eci` (& maybe `source`) will need to be updated individually */ diff --git a/backend/output.c b/backend/output.c index a5e7d8b9..c7fdf975 100644 --- a/backend/output.c +++ b/backend/output.c @@ -189,7 +189,7 @@ INTERNAL int zint_out_colour_get_cmyk(const char *colour, int *cyan, int *magent return 1 + have_alpha; } -/* Convert internal colour chars "WCBMRYGK" to RGB */ +/* Convert internal colour chars "WCBMRYGK" to RGB. Returns 1 on success, else 0 */ INTERNAL int zint_out_colour_char_to_rgb(const unsigned char ch, unsigned char *red, unsigned char *green, unsigned char *blue) { static const char chars[] = "WCBMRYGK"; @@ -955,6 +955,12 @@ static int out_maybe_mkdir(const char *path) { return 0; } +#ifdef ZINT_TEST /* Wrapper for direct testing */ +INTERNAL int zint_test_out_maybe_mkdir(const char *path) { + return out_maybe_mkdir(path); +} +#endif + /* Create output file, creating sub-directories if necessary. Returns `fopen()` FILE pointer */ INTERNAL FILE *zint_out_fopen(char filename[256], const char *mode) { FILE *outfile; diff --git a/backend/output.h b/backend/output.h index 012b4257..59153f02 100644 --- a/backend/output.h +++ b/backend/output.h @@ -49,7 +49,7 @@ INTERNAL int zint_out_colour_get_rgb(const char *colour, unsigned char *red, uns INTERNAL int zint_out_colour_get_cmyk(const char *colour, int *cyan, int *magenta, int *yellow, int *black, unsigned char *rgb_alpha); -/* Convert internal colour chars "WCBMRYGK" to RGB */ +/* Convert internal colour chars "WCBMRYGK" to RGB. Returns 1 on success, else 0 */ INTERNAL int zint_out_colour_char_to_rgb(const unsigned char ch, unsigned char *red, unsigned char *green, unsigned char *blue); diff --git a/backend/pdf417.c b/backend/pdf417.c index 598abe43..7a3b264f 100644 --- a/backend/pdf417.c +++ b/backend/pdf417.c @@ -1364,17 +1364,9 @@ static int pdf_enc(struct zint_symbol *symbol, struct zint_seg segs[], const int chainemc[0] = mclength; /* 796 - we now take care of the Reed Solomon codes */ - switch (ecc) { - case 1: offset = 2; break; - case 2: offset = 6; break; - case 3: offset = 14; break; - case 4: offset = 30; break; - case 5: offset = 62; break; - case 6: offset = 126; break; - case 7: offset = 254; break; - case 8: offset = 510; break; - default: offset = 0; break; - } + assert(ecc >= 0 && ecc <= 8); + offset = (2 << ecc) - 2; + assert(offset >= 0 && offset <= 512); /* Suppress clang-tidy-23 warning clang-analyzer-security.ArrayBound */ for (i = 0; i < mclength; i++) { total = (chainemc[i] + mccorrection[ecc_cws - 1]) % 929; @@ -1477,7 +1469,7 @@ INTERNAL int zint_pdf417(struct zint_symbol *symbol, struct zint_seg segs[], con if (symbol->option_1 < -1 || symbol->option_1 > 8) { z_errtxtf(0, symbol, 460, "Error correction level '%d' out of range (0 to 8)", symbol->option_1); - if (symbol->warn_level == WARN_FAIL_ALL) { + if ((symbol->warn_level & 0xFF) == WARN_FAIL_ALL) { return ZINT_ERROR_INVALID_OPTION; } error_number = z_errtxt_adj(ZINT_WARN_INVALID_OPTION, symbol, "%1$s%2$s", ", ignoring"); @@ -1485,7 +1477,7 @@ INTERNAL int zint_pdf417(struct zint_symbol *symbol, struct zint_seg segs[], con } if (symbol->option_2 < 0 || symbol->option_2 > 30) { z_errtxtf(0, symbol, 461, "Number of columns '%d' out of range (1 to 30)", symbol->option_2); - if (symbol->warn_level == WARN_FAIL_ALL) { + if ((symbol->warn_level & 0xFF) == WARN_FAIL_ALL) { return ZINT_ERROR_INVALID_OPTION; } error_number = z_errtxt_adj(ZINT_WARN_INVALID_OPTION, symbol, "%1$s%2$s", ", ignoring"); @@ -1512,207 +1504,105 @@ INTERNAL int zint_pdf417(struct zint_symbol *symbol, struct zint_seg segs[], con return error_number; } -/* Like PDF417 only much smaller! */ -INTERNAL int zint_micropdf417(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { - int i, k, j, longueur, mccorrection[50] = {0}, offset; - int ecc_cwds; - int total, mclength, error_number = 0; - short chainemc[PDF_MAX_STREAM_LEN]; - char pattern[580]; - int bp = 0; - int structapp_cws[18] = {0}; /* 3 (Index) + 10 (ID) + 4 (Count) + 1 (Last) */ - int structapp_cp = 0; - int variant; - int LeftRAP, CentreRAP, RightRAP, Cluster, loop; - const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; - /* From ISO/IEC 24728:2006 Table 1 — MicroPDF417 version characteristics */ - static char col_max_codewords[5] = { 0, 20, 37, 82, 126 }; - - if ((i = z_segs_length(segs, seg_count)) > MICRO_PDF_MAX_LEN) { - return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 474, - "Input length %d too long (maximum " MICRO_PDF_MAX_LEN_S ")", i); - } - if (symbol->option_3) { - return z_errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 476, "Cannot specify rows for MicroPDF417"); - } - - /* Encoding starts out the same as PDF417, so use the same code */ - - if ((error_number = pdf_initial_segs(symbol, segs, seg_count, 1 /*is_micro*/, chainemc, &mclength, structapp_cws, - &structapp_cp))) { - assert(error_number >= ZINT_ERROR); - return error_number; - } - - /* This is where it all changes! */ - - if (mclength + structapp_cp > 126) { - return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 467, "Input too long, requires %d codewords (maximum 126)", - mclength + structapp_cp); - } - if (symbol->option_2 > 4) { - if (symbol->warn_level == WARN_FAIL_ALL) { - return z_errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 471, "Number of columns '%d' out of range (1 to 4)", - symbol->option_2); - } - error_number = z_errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 468, - "Number of columns '%d' out of range (1 to 4), ignoring", symbol->option_2); - symbol->option_2 = 0; - } - - if (debug_print) { - printf("\nEncoded Data Stream (%d):\n", mclength); - for (i = 0; i < mclength; i++) { - printf("%3d ", chainemc[i]); - } - fputc('\n', stdout); - } - - /* Now figure out which variant of the symbol to use and load values accordingly */ - - variant = 0; - - if (symbol->option_2 >= 1 && mclength + structapp_cp > col_max_codewords[symbol->option_2]) { - /* The user specified the column but the data doesn't fit - go to automatic */ - if (symbol->warn_level == WARN_FAIL_ALL) { - return ZEXT z_errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 469, - "Input too long for number of columns '%1$d', requires %2$d codewords (maximum %3$d)", - symbol->option_2, mclength + structapp_cp, col_max_codewords[symbol->option_2]); - } - error_number = z_errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 470, - "Input too long for number of columns '%d', ignoring", symbol->option_2); - symbol->option_2 = 0; - } - - if (symbol->option_2 == 1) { - /* The user specified 1 column and the data does fit */ - if (mclength + structapp_cp <= 4) { +/* Return variant based on `cols` and codeword length `mclength`. Returns 0 if `cols` 0 or no variant fits */ +INTERNAL int zint_micropdf_variant(const int cols, const int mclength) { + int variant = 0; + if (cols == 1) { + if (mclength <= 4) { variant = 1; - } else if (mclength + structapp_cp <= 7) { + } else if (mclength <= 7) { variant = 2; - } else if (mclength + structapp_cp <= 10) { + } else if (mclength <= 10) { variant = 3; - } else if (mclength + structapp_cp <= 12) { + } else if (mclength <= 12) { variant = 4; - } else if (mclength + structapp_cp <= 16) { + } else if (mclength <= 16) { variant = 5; } else { variant = 6; } - } else if (symbol->option_2 == 2) { - /* The user specified 2 columns and the data does fit */ - if (mclength + structapp_cp <= 8) { + } else if (cols == 2) { + if (mclength <= 8) { variant = 7; - } else if (mclength + structapp_cp <= 13) { + } else if (mclength <= 13) { variant = 8; - } else if (mclength + structapp_cp <= 19) { + } else if (mclength <= 19) { variant = 9; - } else if (mclength + structapp_cp <= 24) { + } else if (mclength <= 24) { variant = 10; - } else if (mclength + structapp_cp <= 29) { + } else if (mclength <= 29) { variant = 11; - } else if (mclength + structapp_cp <= 33) { + } else if (mclength <= 33) { variant = 12; } else { variant = 13; } - } else if (symbol->option_2 == 3) { - /* The user specified 3 columns and the data does fit */ - if (mclength + structapp_cp <= 6) { + } else if (cols == 3) { + if (mclength <= 6) { variant = 14; - } else if (mclength + structapp_cp <= 10) { + } else if (mclength <= 10) { variant = 15; - } else if (mclength + structapp_cp <= 14) { + } else if (mclength <= 14) { variant = 16; - } else if (mclength + structapp_cp <= 18) { + } else if (mclength <= 18) { variant = 17; - } else if (mclength + structapp_cp <= 24) { + } else if (mclength <= 24) { variant = 18; - } else if (mclength + structapp_cp <= 34) { + } else if (mclength <= 34) { variant = 19; - } else if (mclength + structapp_cp <= 46) { + } else if (mclength <= 46) { variant = 20; - } else if (mclength + structapp_cp <= 58) { + } else if (mclength <= 58) { variant = 21; - } else if (mclength + structapp_cp <= 70) { + } else if (mclength <= 70) { variant = 22; } else { variant = 23; } - } else if (symbol->option_2 == 4) { - /* The user specified 4 columns and the data does fit */ - if (mclength + structapp_cp <= 8) { + } else if (cols == 4) { + if (mclength <= 8) { variant = 24; - } else if (mclength + structapp_cp <= 12) { + } else if (mclength <= 12) { variant = 25; - } else if (mclength + structapp_cp <= 18) { + } else if (mclength <= 18) { variant = 26; - } else if (mclength + structapp_cp <= 24) { + } else if (mclength <= 24) { variant = 27; - } else if (mclength + structapp_cp <= 30) { + } else if (mclength <= 30) { variant = 28; - } else if (mclength + structapp_cp <= 39) { + } else if (mclength <= 39) { variant = 29; - } else if (mclength + structapp_cp <= 54) { + } else if (mclength <= 54) { variant = 30; - } else if (mclength + structapp_cp <= 72) { + } else if (mclength <= 72) { variant = 31; - } else if (mclength + structapp_cp <= 90) { + } else if (mclength <= 90) { variant = 32; - } else if (mclength + structapp_cp <= 108) { + } else if (mclength <= 108) { variant = 33; } else { variant = 34; } - } else { - /* Zint can choose automatically from all available variations */ - for (i = 27; i >= 0; i--) { - /* Note mclength + structapp_cp <= 126 and pdf_MicroAutosize[27] == 126 so variant will be set */ - if (pdf_MicroAutosize[i] >= mclength + structapp_cp) { - variant = pdf_MicroAutosize[i + 28]; - } else { - break; - } - } } - assert(variant > 0); /* Suppress clang-tidy clang-analyzer-core.uninitialized.Assign */ + return variant; +} - /* Now we have the variant we can load the data */ - variant--; - symbol->option_2 = zint_pdf_MicroVariants[variant]; /* Columns */ - symbol->rows = zint_pdf_MicroVariants[variant + 34]; /* Rows */ - ecc_cwds = zint_pdf_MicroVariants[variant + 68]; /* Number of EC CWs */ - longueur = (symbol->option_2 * symbol->rows) - ecc_cwds; /* Number of non-EC CWs */ - i = longueur - (mclength + structapp_cp); /* Amount of padding required */ - offset = zint_pdf_MicroVariants[variant + 102]; /* Coefficient offset */ - - /* Feedback options */ - /* Place in top byte, leaving bottom one for maybe future use - also compatible with AZTEC */ - symbol->option_1 = ((int) z_stripf(roundf(z_stripf(ecc_cwds * 100.0f / (longueur + ecc_cwds))))) << 8; - - if (debug_print) { - fputs("\nChoose symbol size:\n", stdout); - printf("%d columns x %d rows, variant %d\n", symbol->option_2, symbol->rows, variant + 1); - printf("%d data codewords (including %d pads), %d ecc codewords\n", longueur, i, ecc_cwds); - fputc('\n', stdout); - } - - /* We add the padding */ - while (i-- > 0) { - chainemc[mclength++] = 900; - } - - /* We add the Structured Append Macro Control Block if any */ - if (structapp_cp) { - for (i = 0; i < structapp_cp; i++) { - chainemc[mclength++] = structapp_cws[i]; - } - } +INTERNAL void zint_micropdf_expand(struct zint_symbol *symbol, short *chainemc, int mclength, char *pattern, + const int cols, const int variant, const int debug_print) { + int bp = 0; /* Suppress gcc warning -Wmaybe-uninitialized */ + int i, k, j, mccorrection[50] = {0}, ecc_cwds; + int offset = zint_pdf_MicroVariants[3][variant]; /* Coefficient offset */ + int LeftRAP = zint_pdf_RAPTable[0][variant] - 1; + int CentreRAP = zint_pdf_RAPTable[1][variant] - 1; + int RightRAP = zint_pdf_RAPTable[2][variant] - 1; + int Cluster; /* Reed-Solomon error correction */ - longueur = mclength; - for (i = 0; i < longueur; i++) { - total = (chainemc[i] + mccorrection[ecc_cwds - 1]) % 929; + ecc_cwds = zint_pdf_MicroVariants[2][variant]; /* Number of EC CWs */ + assert(ecc_cwds >= 7); /* Suppress clang-tidy-23 warning clang-analyzer-security.ArrayBound */ + + for (i = 0; i < mclength; i++) { + const int total = (chainemc[i] + mccorrection[ecc_cwds - 1]) % 929; for (j = ecc_cwds - 1; j >= 0; j--) { if (j == 0) { mccorrection[j] = (929 - (total * zint_pdf_Microcoeffs[offset + j]) % 929) % 929; @@ -1746,74 +1636,173 @@ INTERNAL int zint_micropdf417(struct zint_symbol *symbol, struct zint_seg segs[] } #endif - /* Now get the RAP (Row Address Pattern) start values */ - LeftRAP = zint_pdf_RAPTable[variant]; - CentreRAP = zint_pdf_RAPTable[variant + 34]; - RightRAP = zint_pdf_RAPTable[variant + 68]; - Cluster = zint_pdf_RAPTable[variant + 102] / 3; + /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + Cluster = zint_pdf_RAPTable[3][variant]; /* Pre-divided by 3 */ /* That's all values loaded, get on with the encoding */ - /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ - if (debug_print) fputs("\nInternal row representation:\n", stdout); for (i = 0; i < symbol->rows; i++) { if (debug_print) printf("row %d: ", i); bp = 0; offset = 929 * Cluster; - k = i * symbol->option_2; + k = i * cols; /* Copy the data into codebarre */ - bp = z_bin_append_posn(zint_pdf_rap_side[LeftRAP - 1], 10, pattern, bp); + bp = z_bin_append_posn(zint_pdf_rap_side[LeftRAP], 10, pattern, bp); bp = z_bin_append_posn(((int) zint_pdf_bitpattern[offset + chainemc[k]]) << 1, 17, pattern, bp); - if (symbol->option_2 >= 2) { - if (symbol->option_2 == 3) { - bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP - 1], 10, pattern, bp); + if (cols >= 2) { + if (cols == 3) { + bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP], 10, pattern, bp); } bp = z_bin_append_posn(((int) zint_pdf_bitpattern[offset + chainemc[k + 1]]) << 1, 17, pattern, bp); - if (symbol->option_2 >= 3) { - if (symbol->option_2 == 4) { - bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP - 1], 10, pattern, bp); + if (cols >= 3) { + if (cols == 4) { + bp = z_bin_append_posn(zint_pdf_rap_centre[CentreRAP], 10, pattern, bp); } bp = z_bin_append_posn(((int) zint_pdf_bitpattern[offset + chainemc[k + 2]]) << 1, 17, pattern, bp); - if (symbol->option_2 == 4) { + if (cols == 4) { bp = z_bin_append_posn(((int) zint_pdf_bitpattern[offset + chainemc[k + 3]]) << 1, 17, pattern, bp); } } } - bp = z_bin_append_posn(zint_pdf_rap_side[RightRAP - 1], 10, pattern, bp); + bp = z_bin_append_posn(zint_pdf_rap_side[RightRAP], 10, pattern, bp); pattern[bp++] = '1'; /* Stop */ if (debug_print) printf("%.*s\n", bp, pattern); /* So now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ - for (loop = 0; loop < bp; loop++) { - if (pattern[loop] == '1') { - z_set_module(symbol, i, loop); + for (j = 0; j < bp; j++) { + if (pattern[j] == '1') { + z_set_module(symbol, i, j); } } /* Set up RAPs and Cluster for next row */ - LeftRAP++; - CentreRAP++; - RightRAP++; - Cluster++; - - if (LeftRAP == 53) { - LeftRAP = 1; - } - if (CentreRAP == 53) { - CentreRAP = 1; - } - if (RightRAP == 53) { - RightRAP = 1; - } - if (Cluster == 3) { - Cluster = 0; - } + LeftRAP = LeftRAP == 51 ? 0 : LeftRAP + 1; + CentreRAP = CentreRAP == 51 ? 0 : CentreRAP + 1; + RightRAP = RightRAP == 51 ? 0 : RightRAP + 1; + Cluster = Cluster == 2 ? 0 : Cluster + 1; } symbol->width = bp; +} + +/* Like PDF417 only much smaller! */ +INTERNAL int zint_micropdf417(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { + int i, longueur, padding; + int ecc_cwds; + int mclength, error_number = 0; + short chainemc[PDF_MAX_STREAM_LEN]; + char pattern[580]; + int structapp_cws[18] = {0}; /* 3 (Index) + 10 (ID) + 4 (Count) + 1 (Last) */ + int structapp_cp = 0; + int variant; + const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; + /* From ISO/IEC 24728:2006 Table 1 — MicroPDF417 version characteristics */ + static char col_max_codewords[5] = { 0, 20, 37, 82, 126 }; + + if ((i = z_segs_length(segs, seg_count)) > MICRO_PDF_MAX_LEN) { + return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 474, + "Input length %d too long (maximum " MICRO_PDF_MAX_LEN_S ")", i); + } + if (symbol->option_3) { + return z_errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 476, "Cannot specify rows for MicroPDF417"); + } + + /* Encoding starts out the same as PDF417, so use the same code */ + + if ((error_number = pdf_initial_segs(symbol, segs, seg_count, 1 /*is_micro*/, chainemc, &mclength, structapp_cws, + &structapp_cp))) { + assert(error_number >= ZINT_ERROR); + return error_number; + } + + /* This is where it all changes! */ + + if (mclength + structapp_cp > 126) { + return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 467, "Input too long, requires %d codewords (maximum 126)", + mclength + structapp_cp); + } + if (symbol->option_2 > 4) { + if ((symbol->warn_level & 0xFF) == WARN_FAIL_ALL) { + return z_errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 471, "Number of columns '%d' out of range (1 to 4)", + symbol->option_2); + } + error_number = z_errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 468, + "Number of columns '%d' out of range (1 to 4), ignoring", symbol->option_2); + symbol->option_2 = 0; + } + + if (debug_print) { + printf("\nEncoded Data Stream (%d):\n", mclength); + for (i = 0; i < mclength; i++) { + printf("%3d ", chainemc[i]); + } + fputc('\n', stdout); + } + + /* Now figure out which variant of the symbol to use and load values accordingly */ + + if (symbol->option_2 >= 1 && mclength + structapp_cp > col_max_codewords[symbol->option_2]) { + /* The user specified the column but the data doesn't fit - go to automatic */ + if ((symbol->warn_level & 0xFF) == WARN_FAIL_ALL) { + return ZEXT z_errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 469, + "Input too long for number of columns '%1$d', requires %2$d codewords (maximum %3$d)", + symbol->option_2, mclength + structapp_cp, col_max_codewords[symbol->option_2]); + } + error_number = z_errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 470, + "Input too long for number of columns '%d', ignoring", symbol->option_2); + symbol->option_2 = 0; + } + + /* If the user didn't specify column or the data doesn't fit */ + if (!(variant = zint_micropdf_variant(symbol->option_2, mclength + structapp_cp))) { + /* Zint can choose automatically from all available variations */ + for (i = 27; i >= 0; i--) { + /* Note mclength + structapp_cp <= 126 and pdf_MicroAutosize[27] == 126 so variant will be set */ + if (pdf_MicroAutosize[i] >= mclength + structapp_cp) { + variant = pdf_MicroAutosize[i + 28]; + } else { + break; + } + } + } + assert(variant > 0); /* Suppress clang-tidy-23 warning clang-analyzer-core.uninitialized.Assign */ + + /* Now we have the variant we can load the data */ + variant--; + symbol->option_2 = zint_pdf_MicroVariants[0][variant]; /* Columns */ + symbol->rows = zint_pdf_MicroVariants[1][variant]; /* Rows */ + ecc_cwds = zint_pdf_MicroVariants[2][variant]; /* Number of EC CWs */ + + longueur = (symbol->option_2 * symbol->rows) - ecc_cwds; /* Number of non-EC CWs */ + padding = longueur - (mclength + structapp_cp); /* Amount of padding required */ + + /* Feedback options */ + /* Place in top byte, leaving bottom one for maybe future use - also compatible with AZTEC */ + symbol->option_1 = ((int) z_stripf(roundf(z_stripf(ecc_cwds * 100.0f / (longueur + ecc_cwds))))) << 8; + + if (debug_print) { + fputs("\nChoose symbol size:\n", stdout); + printf("%d columns x %d rows, variant %d\n", symbol->option_2, symbol->rows, variant + 1); + printf("%d data codewords (including %d pads), %d ecc codewords\n", longueur, padding, ecc_cwds); + fputc('\n', stdout); + } + + /* We add the padding */ + while (padding-- > 0) { + chainemc[mclength++] = 900; + } + + /* We add the Structured Append Macro Control Block if any */ + if (structapp_cp) { + for (i = 0; i < structapp_cp; i++) { + chainemc[mclength++] = structapp_cws[i]; + } + } + + zint_micropdf_expand(symbol, chainemc, mclength, pattern, symbol->option_2, variant, debug_print); /* ISO/IEC 24728:2006 Section 5.8.2 2X minimum row height */ if (error_number) { diff --git a/backend/pdf417.h b/backend/pdf417.h index 8a8a6f5d..cdde0bb6 100644 --- a/backend/pdf417.h +++ b/backend/pdf417.h @@ -46,7 +46,7 @@ INTERNAL_DATA_EXTERN const unsigned short zint_pdf_coefrs[1022]; INTERNAL_DATA_EXTERN const unsigned short zint_pdf_bitpattern[2787]; /* 2787 = 929 * 3 */ /* Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 15438:2015 Tables 10, 11 and 12 */ -INTERNAL_DATA_EXTERN const char zint_pdf_RAPTable[136]; /* 34 * 4 */ +INTERNAL_DATA_EXTERN const char zint_pdf_RAPTable[4][34]; /* Left and Right Row Address Pattern from ISO/IEC 15438:2015 Table 2 */ INTERNAL_DATA_EXTERN const unsigned short zint_pdf_rap_side[52]; @@ -57,13 +57,16 @@ INTERNAL_DATA_EXTERN const unsigned short zint_pdf_rap_centre[52]; /* MicroPDF417 coefficients from ISO/IEC 24728:2006 Annex F */ INTERNAL_DATA_EXTERN const unsigned short zint_pdf_Microcoeffs[344]; -/* Number of Data Columns (1st 34), Number of Rows (2nd 34), Number of EC CWs (3rd 34) from ISO/IEC 24728:2006 Table 1 - and k-offsets (4th 34) into `zint_pdf_Microcoeffs[]` above */ -INTERNAL_DATA_EXTERN const unsigned short zint_pdf_MicroVariants[136]; /* 34 * 4 */ +/* Number of Data Columns (row 0), Number of Rows (1), Number of EC CWs (2) from ISO/IEC 24728:2006 Table 1 + and k-offsets (3) into `zint_pdf_Microcoeffs[]` above */ +INTERNAL_DATA_EXTERN const unsigned short zint_pdf_MicroVariants[4][34]; INTERNAL void zint_pdf_byteprocess(short *chainemc, int *p_mclength, const unsigned char chaine[], int start, const int length, const int lastmode); +INTERNAL void zint_micropdf_expand(struct zint_symbol *symbol, short *chainemc, int mclength, char *pattern, + const int cols, const int variant, const int debug_print); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/backend/pdf417_tabs.h b/backend/pdf417_tabs.h index 41200a95..0d1a2f8b 100644 --- a/backend/pdf417_tabs.h +++ b/backend/pdf417_tabs.h @@ -413,12 +413,12 @@ INTERNAL_DATA const unsigned short zint_pdf_bitpattern[2787] = { /* 2787 = 929 * 0xC3EA, 0xC3E9, 0x83CA, 0x87DA, 0x83C9, 0x87D9, 0xE3F5 }; -/* Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 15438:2015 Tables 10, 11 and 12 */ -INTERNAL_DATA const char zint_pdf_RAPTable[136] = { /* 34 * 4 */ - 1, 8, 36, 19, 9, 25, 1, 1, 8, 36, 19, 9, 27, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, 47, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 19, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, - 9, 8, 36, 19, 17, 33, 1, 9, 8, 36, 19, 17, 35, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, 43, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, - 0, 3, 6, 0, 6, 0, 0, 0, 3, 6, 0, 6, 6, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0, 3, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0 +/* Left RAP, Centre RAP, Right RAP and (Start Cluster / 3) from ISO/IEC 15438:2015 Tables 10, 11 and 12 */ +INTERNAL_DATA const char zint_pdf_RAPTable[4][34] = { + { 1, 8, 36, 19, 9, 25, 1, 1, 8, 36, 19, 9, 27, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, 47, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 19, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25 }, + { 9, 8, 36, 19, 17, 33, 1, 9, 8, 36, 19, 17, 35, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, 43, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49 }, + { 0, 1, 2, 0, 2, 0, 0, 0, 1, 2, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 2, 2, 0, 1, 0, 0, 2, 0, 0, 0, 0, 2, 2, 0 } }; /* Left and Right Row Address Pattern from ISO/IEC 15438:2015 Table 2 */ @@ -507,13 +507,13 @@ INTERNAL_DATA const unsigned short zint_pdf_Microcoeffs[344] = { 718, 435 }; -/* Number of Data Columns (1st 34), Number of Rows (2nd 34), Number of EC CWs (3rd 34) from ISO/IEC 24728:2006 Table 1 - and k-offsets (4th 34) into `zint_pdf_Microcoeffs[]` above */ -INTERNAL_DATA const unsigned short zint_pdf_MicroVariants[136] = { /* 34 * 4 */ - 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 11, 14, 17, 20, 24, 28, 8, 11, 14, 17, 20, 23, 26, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 4, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, - 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 11, 13, 15, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, 8, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, - 0, 0, 0, 7, 7, 7, 7, 15, 15, 24, 34, 57, 84, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294, 7, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294 +/* Number of Data Columns (row 0), Number of Rows (1), Number of EC CWs (2) from ISO/IEC 24728:2006 Table 1 + and k-offsets (3) into `zint_pdf_Microcoeffs[]` above */ +INTERNAL_DATA const unsigned short zint_pdf_MicroVariants[4][34] = { + { 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, + { 11, 14, 17, 20, 24, 28, 8, 11, 14, 17, 20, 23, 26, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 4, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44 }, + { 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 11, 13, 15, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, 8, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50 }, + { 0, 0, 0, 7, 7, 7, 7, 15, 15, 24, 34, 57, 84, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294, 7, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294 } }; #ifdef __cplusplus diff --git a/backend/png.c b/backend/png.c index 8325f193..8c020274 100644 --- a/backend/png.c +++ b/backend/png.c @@ -1,7 +1,7 @@ /* png.c - Handles output to PNG file */ /* libzint - the open source barcode library - Copyright (C) 2009-2025 Robin Stuart + Copyright (C) 2009-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -32,6 +32,7 @@ #ifndef ZINT_NO_PNG +#include #include #include #include @@ -42,49 +43,42 @@ #include "filemem.h" #include "output.h" -/* Note using "wpng_" prefix not "png_" to avoid clashing with libpng */ +/* Note using "zpng_" prefix not "png_" to avoid clashing with libpng */ /* Note if change this need to change "backend/tests/test_png.c" definition also */ -struct wpng_error_type { +struct zpng_error_type { struct zint_symbol *symbol; jmp_buf jmpbuf; }; -static void wpng_error_handler(png_structp png_ptr, png_const_charp msg) { - struct wpng_error_type *wpng_error_ptr; - - wpng_error_ptr = (struct wpng_error_type *) png_get_error_ptr(png_ptr); - if (wpng_error_ptr == NULL) { - /* we are completely hosed now */ - fprintf(stderr, "Error 636: libpng error: %s\n", msg ? msg : ""); - fprintf(stderr, "Error 637: jmpbuf not recoverable, terminating\n"); - fflush(stderr); - return; /* libpng will call abort() */ - } - z_errtxtf(0, wpng_error_ptr->symbol, 635, "libpng error: %s", msg ? msg : ""); - longjmp(wpng_error_ptr->jmpbuf, 1); +/* Passed to `png_create_write_struct()` as `error_fn` */ +static void zpng_error_handler(png_structp png_ptr, png_const_charp msg) { + struct zpng_error_type *error_ptr = (struct zpng_error_type *) png_get_error_ptr(png_ptr); + assert(error_ptr); + z_errtxtf(0, error_ptr->symbol, 635, "libpng error: %s", msg ? msg : ""); + longjmp(error_ptr->jmpbuf, 1); } #ifdef ZINT_TEST /* Wrapper for direct testing */ -INTERNAL void zint_test_wpng_error_handler(png_structp png_ptr, png_const_charp msg) { - wpng_error_handler(png_ptr, msg); +INTERNAL void zint_test_zpng_error_handler(png_structp png_ptr, png_const_charp msg) { + zpng_error_handler(png_ptr, msg); } #endif /* libpng write callback */ -static void wpng_write(png_structp png_ptr, png_bytep ptr, size_t size) { +static void zpng_write(png_structp png_ptr, png_bytep ptr, size_t size) { struct filemem *fmp = (struct filemem *) png_get_io_ptr(png_ptr); (void) zint_fm_write(ptr, 1, size, fmp); } /* libpng flush callback */ -static void wpng_flush(png_structp png_ptr) { +static void zpng_flush(png_structp png_ptr) { struct filemem *fmp = (struct filemem *) png_get_io_ptr(png_ptr); (void) zint_fm_flush(fmp); } /* Guesstimate best compression strategy */ -static int wpng_guess_compression_strategy(struct zint_symbol *symbol, const unsigned char *pixelbuf) { +static int zpng_guess_compression_strategy(struct zint_symbol *symbol, const unsigned char *pixelbuf) { (void)pixelbuf; /* TODO: Do properly */ @@ -104,7 +98,7 @@ static int wpng_guess_compression_strategy(struct zint_symbol *symbol, const uns } INTERNAL int zint_png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf) { - struct wpng_error_type wpng_error; + struct zpng_error_type zpng_error; /* Passed to `png_create_write_struct()` as `error_ptr` */ struct filemem fm; struct filemem *const fmp = &fm; png_structp png_ptr; @@ -123,7 +117,7 @@ INTERNAL int zint_png_pixel_plot(struct zint_symbol *symbol, const unsigned char const unsigned char *pb; unsigned char *outdata = (unsigned char *) z_alloca(symbol->bitmap_width); - wpng_error.symbol = symbol; + zpng_error.symbol = symbol; (void) zint_out_colour_get_rgb(symbol->fgcolour, &fg.red, &fg.green, &fg.blue, &fg_alpha); (void) zint_out_colour_get_rgb(symbol->bgcolour, &bg.red, &bg.green, &bg.blue, &bg_alpha); @@ -217,7 +211,7 @@ INTERNAL int zint_png_pixel_plot(struct zint_symbol *symbol, const unsigned char } /* Set up error handling routine as proc() above */ - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &wpng_error, wpng_error_handler, NULL); + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &zpng_error, zpng_error_handler, NULL); if (!png_ptr) { (void) zint_fm_close(fmp, symbol); return z_errtxt(ZINT_ERROR_MEMORY, symbol, 633, "Insufficient memory for PNG write structure buffer"); @@ -231,20 +225,20 @@ INTERNAL int zint_png_pixel_plot(struct zint_symbol *symbol, const unsigned char } /* catch jumping here */ - if (setjmp(wpng_error.jmpbuf)) { + if (setjmp(zpng_error.jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); (void) zint_fm_close(fmp, symbol); return ZINT_ERROR_MEMORY; } /* Set our output functions */ - png_set_write_fn(png_ptr, fmp, wpng_write, wpng_flush); + png_set_write_fn(png_ptr, fmp, zpng_write, zpng_flush); /* set compression */ png_set_compression_level(png_ptr, 9); /* Compression strategy can make a difference */ - compression_strategy = wpng_guess_compression_strategy(symbol, pixelbuf); + compression_strategy = zpng_guess_compression_strategy(symbol, pixelbuf); if (compression_strategy != Z_DEFAULT_STRATEGY) { png_set_compression_strategy(png_ptr, compression_strategy); } @@ -302,6 +296,12 @@ INTERNAL int zint_png_pixel_plot(struct zint_symbol *symbol, const unsigned char } /* write row contents to file */ png_write_row(png_ptr, outdata); + +#ifdef ZINT_TEST + if (symbol->debug & 4096) { /* ZINT_DEBUG_TEST_PNG_FLUSH */ + png_write_flush(png_ptr); + } +#endif } } @@ -312,7 +312,8 @@ INTERNAL int zint_png_pixel_plot(struct zint_symbol *symbol, const unsigned char png_destroy_write_struct(&png_ptr, &info_ptr); if (zint_fm_error(fmp)) { - ZEXT z_errtxtf(0, symbol, 638, "Incomplete write of PNG output (%1$d: %2$s)", fmp->err, strerror(fmp->err)); + (void) ZEXT z_errtxtf(0, symbol, 638, "Incomplete write of PNG output (%1$d: %2$s)", + fmp->err, strerror(fmp->err)); (void) zint_fm_close(fmp, symbol); return ZINT_ERROR_FILE_WRITE; } @@ -328,6 +329,6 @@ INTERNAL int zint_png_pixel_plot(struct zint_symbol *symbol, const unsigned char #else #if defined(__clang__) /* Suppresses clang-tidy-18 "clang-diagnostic-empty-translation-unit" */ -typedef int wpng_make_clang_tidy_compilers_happy; +typedef int zpng_make_clang_tidy_compilers_happy; #endif #endif /* ZINT_NO_PNG */ diff --git a/backend/ps.c b/backend/ps.c index b597f8bb..a850d3d7 100644 --- a/backend/ps.c +++ b/backend/ps.c @@ -422,30 +422,13 @@ INTERNAL int zint_ps_plot(struct zint_symbol *symbol) { previous_diameter = circle->diameter - circle->width; radius = 0.5f * previous_diameter; } - if (circle->colour) { /* Legacy - no longer used */ - /* A 'white' circle */ - if (is_rgb) { - ps_put_rgbcolor(red_paper, green_paper, blue_paper, fmp); - } else { - ps_put_cmykcolor(cyan_paper, magenta_paper, yellow_paper, black_paper, fmp); - } - ps_put_circle(symbol, circle, radius, 0 /*type*/, fmp); - if (circle->next) { - if (is_rgb) { - ps_put_rgbcolor(red_ink, green_ink, blue_ink, fmp); - } else { - ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, fmp); - } - } + assert(circle->colour == 0); /* Legacy - no longer used */ + if (circle->next && circle->y == circle->next->y && circle->diameter == circle->next->diameter) { + ps_put_circle(symbol, circle, radius, type_latch ? 2 : 1, fmp); + type_latch = 1; } else { - /* A 'black' circle */ - if (circle->next && circle->y == circle->next->y && circle->diameter == circle->next->diameter) { - ps_put_circle(symbol, circle, radius, type_latch ? 2 : 1, fmp); - type_latch = 1; - } else { - ps_put_circle(symbol, circle, radius, type_latch ? 3 : 0, fmp); - type_latch = 0; - } + ps_put_circle(symbol, circle, radius, type_latch ? 3 : 0, fmp); + type_latch = 0; } } diff --git a/backend/qr.c b/backend/qr.c index 14e10257..7c75b408 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -2352,6 +2352,8 @@ INTERNAL int zint_upnqr(struct zint_symbol *symbol, unsigned char source[], int user_mask = 0; /* Ignore */ } + /* Can't be GS1_MODE as checked before being called */ + assert((symbol->input_mode & 0x07) == DATA_MODE || (symbol->input_mode & 0x07) == UNICODE_MODE); switch (symbol->input_mode & 0x07) { case DATA_MODE: /* Input is already in ISO-8859-2 format */ @@ -2360,10 +2362,6 @@ INTERNAL int zint_upnqr(struct zint_symbol *symbol, unsigned char source[], int modes[i] = 'B'; } break; - case GS1_MODE: /* Should never happen as checked before being called */ - return z_errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 571, - "UPNQR does not support GS1 data"); /* Not reached */ - break; case UNICODE_MODE: error_number = zint_utf8_to_eci(4, source, preprocessed, &length); if (error_number != 0) { diff --git a/backend/raster.c b/backend/raster.c index f6e4c7f7..5ab86838 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -53,6 +53,54 @@ #define ZFONT_HALIGN_RIGHT 2 #define ZFONT_UPCEAN_TEXT 4 /* Helper flag to indicate dealing with EAN/UPC */ +#ifdef ZINT_TEST +/* For testing `malloc()` failure */ + +static int raster_fail_id = 0; /* RAST_FAIL_ID_XXX below */ +static int raster_fail_at = 0; /* Number of times before failure */ + +INTERNAL void zint_test_raster_set_fail(const int id, const int at) { + raster_fail_id = id; + raster_fail_at = at; +} + +/* TODO: add new "raster.h" & put these in it */ +#define RAST_FAIL_ID_BITMAP 1 +#define RAST_FAIL_ID_ALPHA 2 +#define RAST_FAIL_ID_ROTATED 3 +#define RAST_FAIL_ID_MC_PIXELBUF 4 +#define RAST_FAIL_ID_MC_HEXAGON 5 +#define RAST_FAIL_ID_DOTTY_SCALED 6 +#define RAST_FAIL_ID_PIXELBUF 7 +#define RAST_FAIL_ID_SCALED 8 + +#define rast_malloc(id, sz) (raster_fail_at > 0 && raster_fail_id == (id) && --raster_fail_at == 0 \ + ? NULL : malloc(sz)) + +#define raster_malloc_bitmap(sz, psz) raster_malloc(RAST_FAIL_ID_BITMAP, sz, psz) +#define raster_malloc_alpha(sz, psz) raster_malloc(RAST_FAIL_ID_ALPHA, sz, psz) +#define raster_malloc_rotated(sz, psz) raster_malloc(RAST_FAIL_ID_ROTATED, sz, psz) +#define raster_malloc_mc_pixelbuf(sz, psz) raster_malloc(RAST_FAIL_ID_MC_PIXELBUF, sz, psz) +#define raster_malloc_mc_hexagon(sz, psz) raster_malloc(RAST_FAIL_ID_MC_HEXAGON, sz, psz) +#define raster_malloc_dotty_scaled(sz, psz) raster_malloc(RAST_FAIL_ID_DOTTY_SCALED, sz, psz) +#define raster_malloc_pixelbuf(sz, psz) raster_malloc(RAST_FAIL_ID_PIXELBUF, sz, psz) +#define raster_malloc_scaled(sz, psz) raster_malloc(RAST_FAIL_ID_SCALED, sz, psz) + +#else + +#define rast_malloc(id, sz) malloc(sz) + +#define raster_malloc_bitmap(sz, psz) raster_malloc(sz, psz) +#define raster_malloc_alpha(sz, psz) raster_malloc(sz, psz) +#define raster_malloc_rotated(sz, psz) raster_malloc(sz, psz) +#define raster_malloc_mc_pixelbuf(sz, psz) raster_malloc(sz, psz) +#define raster_malloc_mc_hexagon(sz, psz) raster_malloc(sz, psz) +#define raster_malloc_dotty_scaled(sz, psz) raster_malloc(sz, psz) +#define raster_malloc_pixelbuf(sz, psz) raster_malloc(sz, psz) +#define raster_malloc_scaled(sz, psz) raster_malloc(sz, psz) + +#endif + #ifndef ZINT_NO_PNG INTERNAL int zint_png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf); #endif /* ZINT_NO_PNG */ @@ -64,14 +112,18 @@ INTERNAL int zint_tif_pixel_plot(struct zint_symbol *symbol, const unsigned char static const char ultra_colour[] = "0CBMRYGKW"; /* Wrapper to pre-check `size` on `malloc()` isn't too big (`prev_size` given if doing 2nd `malloc()` in a row) */ +#ifdef ZINT_TEST +static void *raster_malloc(const int id, size_t size, size_t prev_size) { +#else static void *raster_malloc(size_t size, size_t prev_size) { +#endif /* Check for large image `malloc`s, which produce very large files most systems can't handle anyway */ /* Also `malloc()` on Linux will (usually) succeed regardless of request, and then get untrappably killed on access by OOM killer if too much, so this is a crude mitigation */ if (size + prev_size < size /*Overflow check*/ || size + prev_size > 0x40000000 /*1GB*/) { return NULL; } - return malloc(size); + return rast_malloc(id, size); } static int buffer_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf) { @@ -112,7 +164,7 @@ static int buffer_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf symbol->alphamap = NULL; } - if (!(symbol->bitmap = (unsigned char *) raster_malloc(bm_bitmap_size, 0 /*prev_size*/))) { + if (!(symbol->bitmap = (unsigned char *) raster_malloc_bitmap(bm_bitmap_size, 0 /*prev_size*/))) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 661, "Insufficient memory for bitmap buffer"); } #ifdef ZINT_SANITIZEM /* Suppress clang -fsanitize=memory false positive */ @@ -121,7 +173,7 @@ static int buffer_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf if (plot_alpha) { const size_t alpha_size = (size_t) symbol->bitmap_width * symbol->bitmap_height; - if (!(symbol->alphamap = (unsigned char *) raster_malloc(alpha_size, bm_bitmap_size))) { + if (!(symbol->alphamap = (unsigned char *) raster_malloc_alpha(alpha_size, bm_bitmap_size))) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 662, "Insufficient memory for alphamap buffer"); } for (row = 0; row < symbol->bitmap_height; row++) { @@ -182,7 +234,7 @@ static int save_raster_image_to_file(struct zint_symbol *symbol, const int image if (rotate_angle) { size_t image_size = (size_t) image_width * image_height; - if (!(rotated_pixbuf = (unsigned char *) raster_malloc((size_t) image_size, 0 /*prev_size*/))) { + if (!(rotated_pixbuf = (unsigned char *) raster_malloc_rotated((size_t) image_size, 0 /*prev_size*/))) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 650, "Insufficient memory for pixel buffer"); } #ifdef ZINT_SANITIZEM /* Suppress clang -fsanitize=memory false positive */ @@ -799,13 +851,13 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang assert(image_width && image_height); image_size = (size_t) image_width * image_height; - if (!(pixelbuf = (unsigned char *) raster_malloc(image_size, 0 /*prev_size*/))) { + if (!(pixelbuf = (unsigned char *) raster_malloc_mc_pixelbuf(image_size, 0 /*prev_size*/))) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 655, "Insufficient memory for pixel buffer"); } memset(pixelbuf, DEFAULT_PAPER, image_size); hex_size = (size_t) hex_width * hex_height; - if (!(scaled_hexagon = (unsigned char *) raster_malloc(hex_size, image_size))) { + if (!(scaled_hexagon = (unsigned char *) raster_malloc_mc_hexagon(hex_size, image_size))) { free(pixelbuf); return z_errtxt(ZINT_ERROR_MEMORY, symbol, 656, "Insufficient memory for pixel buffer"); } @@ -893,7 +945,7 @@ static int plot_raster_dotty(struct zint_symbol *symbol, const int rotate_angle, scale_size = (size_t) scale_width * scale_height; /* Apply scale options by creating pixel buffer */ - if (!(scaled_pixelbuf = (unsigned char *) raster_malloc(scale_size, 0 /*prev_size*/))) { + if (!(scaled_pixelbuf = (unsigned char *) raster_malloc_dotty_scaled(scale_size, 0 /*prev_size*/))) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 657, "Insufficient memory for pixel buffer"); } memset(scaled_pixelbuf, DEFAULT_PAPER, scale_size); @@ -1068,7 +1120,7 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl assert(image_width && image_height); image_size = (size_t) image_width * image_height; - if (!(pixelbuf = (unsigned char *) raster_malloc(image_size, 0 /*prev_size*/))) { + if (!(pixelbuf = (unsigned char *) raster_malloc_pixelbuf(image_size, 0 /*prev_size*/))) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 658, "Insufficient memory for pixel buffer"); } memset(pixelbuf, DEFAULT_PAPER, image_size); @@ -1407,7 +1459,8 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl const int scale_height = (int) z_stripf(image_height * scaler); /* Apply scale options by creating another pixel buffer */ - if (!(scaled_pixelbuf = (unsigned char *) raster_malloc((size_t) scale_width * scale_height, image_size))) { + if (!(scaled_pixelbuf = (unsigned char *) raster_malloc_scaled((size_t) scale_width * scale_height, + image_size))) { free(pixelbuf); return z_errtxt(ZINT_ERROR_MEMORY, symbol, 659, "Insufficient memory for scaled pixel buffer"); } diff --git a/backend/reedsol.c b/backend/reedsol.c index 8336444f..b5d85b47 100644 --- a/backend/reedsol.c +++ b/backend/reedsol.c @@ -58,6 +58,20 @@ #include "reedsol.h" #include "reedsol_logs.h" +#ifdef ZINT_TEST +/* For testing `calloc()` failure */ + +static int rs_fail_id = 0; /* RS_FAIL_ID_XXX */ + +INTERNAL void zint_test_rs_set_fail(const int id) { + rs_fail_id = id; +} + +#define rs_calloc(id, num, sz) (rs_fail_id == (id) ? NULL : calloc(num, sz)) +#else +#define rs_calloc(id, num, sz) calloc(num, sz) +#endif + /* rs_init_gf(&rs, prime_poly) initialises the parameters for the Galois Field. The symbol size is determined from the highest bit set in poly This implementation will support sizes up to 8 bits (see rs_uint_init_gf() @@ -258,10 +272,10 @@ INTERNAL int zint_rs_uint_init_gf(rs_uint_t *rs_uint, const unsigned int prime_p rs_uint->logt = NULL; rs_uint->alog = NULL; - if (!(logt = (unsigned short *) calloc(b, sizeof(unsigned short)))) { + if (!(logt = (unsigned short *) rs_calloc(RS_FAIL_ID_LOGT, b, sizeof(unsigned short)))) { return 0; } - if (!(alog = (unsigned short *) calloc(b * 2, sizeof(unsigned short)))) { + if (!(alog = (unsigned short *) rs_calloc(RS_FAIL_ID_ALOG, b * 2, sizeof(unsigned short)))) { free(logt); return 0; } diff --git a/backend/reedsol.h b/backend/reedsol.h index 07130215..c6a9ec53 100644 --- a/backend/reedsol.h +++ b/backend/reedsol.h @@ -71,6 +71,13 @@ INTERNAL void zint_rs_uint_encode(const rs_uint_t *rs_uint, const int datalen, c unsigned int *res); INTERNAL void zint_rs_uint_free(rs_uint_t *rs_uint); +#ifdef ZINT_TEST +/* For testing `calloc()` failure */ +#define RS_FAIL_ID_LOGT 1 +#define RS_FAIL_ID_ALOG 2 +INTERNAL void zint_test_rs_set_fail(const int id); +#endif + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/backend/rss.c b/backend/rss.c index 42b399ba..38ec2c54 100644 --- a/backend/rss.c +++ b/backend/rss.c @@ -69,34 +69,37 @@ #include "gs1.h" #include "rss.h" -/* `combins()' in ISO/IEC 24724:2011 Annex B */ +/* `combins()` in ISO/IEC 24724:2011 Annex B */ /**************************************************************************** * dbar_combins(n,r): returns the number of Combinations of r selected from n: * Combinations = n! / (n - r)! * r! ****************************************************************************/ static int dbar_combins(const int n, const int r) { - int i; - int maxDenom, minDenom; - int val = 1, j = 1; + /* Generated by "backend/tests/test_rss -f test_generate_combins -g" (which uses `combins()`) */ + static const short combins[18][6] = { + { 1, 1, 1, 1, 1, 1 }, /* 0 */ + { 1, 1, 1, 1, 1, 1 }, /* 1 */ + { 1, 2, 1, 1, 1, 1 }, /* 2 */ + { 1, 3, 3, 1, 1, 1 }, /* 3 */ + { 1, 4, 6, 4, 1, 1 }, /* 4 */ + { 1, 5, 10, 10, 5, 1 }, /* 5 */ + { 1, 6, 15, 20, 15, 6 }, /* 6 */ + { 1, 7, 21, 35, 35, 21 }, /* 7 */ + { 1, 8, 28, 56, 70, 56 }, /* 8 */ + { 1, 9, 36, 84, 126, 126 }, /* 9 */ + { 1, 10, 45, 120, 210, 252 }, /* 10 */ + { 1, 11, 55, 165, 330, 462 }, /* 11 */ + { 1, 12, 66, 220, 495, 792 }, /* 12 */ + { 1, 13, 78, 286, 715, 1287 }, /* 13 */ + { 1, 14, 91, 364, 1001, 2002 }, /* 14 */ + { 1, 15, 105, 455, 1365, 3003 }, /* 15 */ + { 1, 16, 120, 560, 1820, 4368 }, /* 16 */ + { 1, 17, 136, 680, 2380, 6188 } /* 17 */ + }; - if (n - r > r) { - minDenom = r; - maxDenom = n - r; - } else { - minDenom = n - r; - maxDenom = r; - } - for (i = n; i > maxDenom; i--) { - val *= i; - if (j <= minDenom) { - val /= j; - j++; - } - } - for (; j <= minDenom; j++) { - val /= j; - } - return val; + assert(n >= 0 && n < 18); /* Max 19 modules (DBAR_LTD) - 2 */ + assert(r >= 0 && r < 6); /* Max 7 elements (DBAR_LTD) - 2 */ + return combins[n][r]; } /* `getRSSwidths()' in ISO/IEC 24724:2011 Annex B, modified to use arg `widths` instead of static, @@ -280,7 +283,8 @@ static void dbar_omn_separator(struct zint_symbol *symbol, int width, const int } /* Set Databar Stacked height, maintaining 5:7 ratio of the 2 main row heights */ -INTERNAL int zint_dbar_omnstk_set_height(struct zint_symbol *symbol, const int first_row) { +INTERNAL int zint_dbar_stk_set_height(struct zint_symbol *symbol, const int first_row, const int no_errtxt) { + int error_number = 0; float fixed_height = 0.0f; const int second_row = first_row + 2; /* 2 row separator */ int i; @@ -297,12 +301,11 @@ INTERNAL int zint_dbar_omnstk_set_height(struct zint_symbol *symbol, const int f (symbol->row_height[first_row] + symbol->row_height[second_row])); if (symbol->row_height[first_row] < 0.5f) { /* Absolute minimum */ symbol->row_height[first_row] = 0.5f; - symbol->row_height[second_row] = 0.7f; + symbol->row_height[second_row] = 0.7f; /* 0.7f is actually 0.699999988 (0x3F333333) */ } else { symbol->row_height[second_row] = z_stripf(symbol->height - fixed_height - symbol->row_height[first_row]); - if (symbol->row_height[second_row] < 0.7f) { - symbol->row_height[second_row] = 0.7f; - } + /* (h - 1) * 5/12 >= 0.5 -> h - 1 >= 0.5 * 12/5 -> h >= 2.2 -> rh[sr] >= (2.2 - 1 - 0.5) -> rh[sr] >= 0.7 */ + assert(symbol->row_height[second_row] >= 0.7f); } } symbol->height = z_stripf(z_stripf(symbol->row_height[first_row] + symbol->row_height[second_row]) @@ -310,11 +313,14 @@ INTERNAL int zint_dbar_omnstk_set_height(struct zint_symbol *symbol, const int f if (symbol->output_options & COMPLIANT_HEIGHT) { if (symbol->row_height[first_row] < 5.0f || symbol->row_height[second_row] < 7.0f) { - return z_errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 379, "Height not compliant with standards"); + error_number = ZINT_WARN_NONCOMPLIANT; + if (!no_errtxt) { + z_errtxt(0, symbol, 379, "Height not compliant with standards"); + } } } - return 0; + return error_number; } /* Return DataBar Omnidirectional group (outside -1, inside +5-1) */ @@ -523,8 +529,8 @@ INTERNAL int zint_dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[] symbol->width = 50; } - if (symbol->symbology != BARCODE_DBAR_STK_CC) { /* Composite calls `zint_dbar_omnstk_set_height()` itself */ - error_number = zint_dbar_omnstk_set_height(symbol, 0 /*first_row*/); + if (symbol->symbology != BARCODE_DBAR_STK_CC) { /* Composite calls `zint_dbar_stk_set_height()` itself */ + error_number = zint_dbar_stk_set_height(symbol, 0 /*first_row*/, 0 /*no_errtxt*/); } } else if (symbol->symbology == BARCODE_DBAR_OMNSTK || symbol->symbology == BARCODE_DBAR_OMNSTK_CC) { diff --git a/backend/svg.c b/backend/svg.c index d27c6024..157fd246 100644 --- a/backend/svg.c +++ b/backend/svg.c @@ -30,6 +30,7 @@ */ /* SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include @@ -295,24 +296,14 @@ INTERNAL int zint_svg_plot(struct zint_symbol *symbol) { svg_put_fattrib(" cy=\"", 2, circle->y, fmp); svg_put_fattrib(" r=\"", circle->width ? 3 : 2, radius, fmp); - if (circle->colour) { /* Legacy - no longer used */ - if (circle->width) { - zint_fm_printf(fmp, " stroke=\"#%s\"", bgcolour_string); - svg_put_fattrib(" stroke-width=\"", 3, circle->width, fmp); - zint_fm_puts(" fill=\"none\"", fmp); - } else { - zint_fm_printf(fmp, " fill=\"#%s\"", bgcolour_string); - } - /* This doesn't work how the user is likely to expect - more work needed! */ - svg_put_opacity_close(bg_alpha, bg_alpha_opacity, 1 /*close*/, fmp); - } else { - if (circle->width) { - zint_fm_printf(fmp, " stroke=\"#%s\"", fgcolour_string); - svg_put_fattrib(" stroke-width=\"", 3, circle->width, fmp); - zint_fm_puts(" fill=\"none\"", fmp); - } - svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fmp); + assert(circle->colour == 0); /* Legacy - no longer used */ + if (circle->width) { + zint_fm_printf(fmp, " stroke=\"#%s\"", fgcolour_string); + svg_put_fattrib(" stroke-width=\"", 3, circle->width, fmp); + zint_fm_puts(" fill=\"none\"", fmp); } + /* This doesn't work how the user is likely to expect - more work needed! */ + svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fmp); circle = circle->next; } diff --git a/backend/tests/data/gif/ultra_box.gif b/backend/tests/data/gif/ultra_box.gif new file mode 100644 index 0000000000000000000000000000000000000000..1dea957d10447b6100535592224d7b0c8bd5d08b GIT binary patch literal 239 zcmZ?wbh9u|RA7)}_{6~Q|Nnm=2GKBz0mx%u&;b!3H4MyqDt6uZXK>1M^$wAi^XbH>62Q$lzW)-9j7F;-x@?_?R9R7RoQ`V02w fCVI^)Gu&o<{NzEG)78~}64!6symk9FCxbNrvCd=u literal 0 HcmV?d00001 diff --git a/backend/tests/data/png/telepen_compliant_dpmm_300dpi.png b/backend/tests/data/png/telepen_compliant_dpmm_300dpi.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac0ef1dbabae02feefd3d774486673e7976f7b3 GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0y~yU{nCID;Sx9WXAKoZ-EqBfKQ0)|NsAi%+N!Z>wpwz zfk$L91B0G22s2hJwJ!q-R(rZQhD02GdvPOYg98uig@$Q;2@fS+=85lg^xM#{ICPI~|V literal 0 HcmV?d00001 diff --git a/backend/tests/data/tif/code32_dpmm_200dpi.tif b/backend/tests/data/tif/code32_dpmm_200dpi.tif new file mode 100644 index 0000000000000000000000000000000000000000..bd4b8eab993e938999ef57f7777564b2caa0c428 GIT binary patch literal 698 zcmebD)MC(KVqj=6INonK!zS&#gzrOnQ98mehsMdVJ$@IcoCQXq_ z(=V-Q)*&D_rY~=G35m|2dJGWs+MLO^#n1oV)eb(P=lswp>|f z8s%EG*>zv^`s-PD&mFHi5czJ}YBsTt`TK9K37_4ju0G*V%*G$qaaO-e&pq4xDdGBIPO_Bih8}Tocf*u&S(hM|aDfwrA&$zf21h1~ zIDJa-XYkzAGGEyF(v;O&E*su#mOOTG^)Ut?VV4|aN!W(n8@Vvfq{`JK!nNvprC+8K!QUHD0R;h(l#lLA4i7mv zWLOyW9UGqss4y}#G$=R-v#{zZvVdebug; - +static const char *test_many_states_data(char *buf, const int length) { static char modes_buf[6][6] = { { 'A', 'B', ' ', 'C', 'D', 'E' }, /* AZ_U */ { 'a', ' ', 'b', 'c', 'd', 'e' }, /* AZ_L */ @@ -352,21 +350,7 @@ static void test_many_states(const testCtx *const p_ctx) { { '1', ',', ' ', '2', '3', ',' }, /* AZ_D */ { 'A', '*', '\016', '2', '1', '0' }, /* Single AZ_B () amongst non-AZ_B */ }; - - int i, j, k, ret; - struct zint_symbol *symbol = NULL; - - const int length = 3191; - char buf[3191]; - - char escaped[9216]; - char cmp_buf[32768]; - char cmp_msg[1024]; - - /* Only do zxing-cpp test if asked, too slow otherwise */ - int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); - - testStartSymbol(p_ctx->func_name, &symbol); + int i, j, k; for (i = 0; i < length; i += 36) { for (j = 0; j < 6; j++) { @@ -381,6 +365,28 @@ static void test_many_states(const testCtx *const p_ctx) { break; } } + return buf; +} + +static void test_many_states(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + int ret; + struct zint_symbol *symbol = NULL; + + const int length = 3191; + char buf[3191]; + + char escaped[9216]; + char cmp_buf[32768]; + char cmp_msg[1024]; + + /* Only do zxing-cpp test if asked, too slow otherwise */ + int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); + + testStartSymbol(p_ctx->func_name, &symbol); + + (void) test_many_states_data(buf, length); symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); @@ -392,21 +398,19 @@ static void test_many_states(const testCtx *const p_ctx) { ret = ZBarcode_Encode(symbol, TCU(buf), length); assert_nonzero(ret < ZINT_ERROR, "ZBarcode_Encode(%d) ret %d >= ZINT_ERROR (%s)\n", length, ret, symbol->errtxt); - if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, buf, length, debug)) { + if (do_zxingcpp && testUtilCanZXingCPP(0, symbol, buf, length, debug)) { int cmp_len, ret_len; char modules_dump[22801 + 1]; assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), - -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, buf, length, modules_dump, 3 /*zxingcpp_cmp*/, + -1, "testUtilModulesDump == -1\n"); + ret = testUtilZXingCPP(0, symbol, buf, length, modules_dump, 3 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", - i, testUtilBarcodeName(symbol->symbology), ret); + assert_zero(ret, "%s testUtilZXingCPP ret %d != 0\n", testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, buf, length, NULL /*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); + assert_zero(ret, "%s testUtilZXingCPPCmp %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", + testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped); } ZBarcode_Delete(symbol); @@ -9933,6 +9937,84 @@ static void test_fuzz(const testCtx *const p_ctx) { testFinish(); } +INTERNAL void zint_test_az_set_fail(const int id, const int at); + +/* TODO: put these & above def in "aztec.h" (& rename existing "aztec.h" to "aztec_tabs.h" */ +#define AZ_FAIL_ID_LIST_INIT 1 +#define AZ_FAIL_ID_CPY 2 +#define AZ_FAIL_ID_ADD_CHK 3 +#define AZ_FAIL_ID_LIST_ADD_CHK 4 + +static void test_alloc(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int output_options; + const char *data; + int length; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_MEMORY_FILE, "Aa345", -1, ZINT_ERROR_MEMORY, { 1, 2, 3, 0, 0 }, 3, AZ_FAIL_ID_LIST_INIT }, + /* 1*/ { BARCODE_MEMORY_FILE, "\015\012. , : ", -1, ZINT_ERROR_MEMORY, { 1, 2, 3, 0, 0 }, 3, AZ_FAIL_ID_LIST_INIT }, + /* 2*/ { BARCODE_MEMORY_FILE, "Aa345", -1, ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0 }, 1, AZ_FAIL_ID_CPY }, + /* 3*/ { BARCODE_MEMORY_FILE, "ABC\241", -1, ZINT_ERROR_MEMORY, { 5, 0, 0, 0, 0 }, 1, AZ_FAIL_ID_CPY }, + /* 4*/ { BARCODE_MEMORY_FILE, "\241\015\012", -1, ZINT_ERROR_MEMORY, { 4, 0, 0, 0, 0 }, 1, AZ_FAIL_ID_CPY }, + /* 5*/ { BARCODE_MEMORY_FILE, NULL, 32, ZINT_ERROR_MEMORY, { 7, 42, 95, 96, 0 }, 4, AZ_FAIL_ID_CPY }, + /* 6*/ { BARCODE_MEMORY_FILE, NULL, 32, ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0 }, 1, AZ_FAIL_ID_ADD_CHK }, + /* 7*/ { BARCODE_MEMORY_FILE, "Code 2D!", -1, ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0 }, 1, AZ_FAIL_ID_LIST_ADD_CHK }, + /* 8*/ { BARCODE_MEMORY_FILE, "+/EO5232013", -1, ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0 }, 1, AZ_FAIL_ID_LIST_ADD_CHK }, + /* 9*/ { BARCODE_MEMORY_FILE, "+/KN12345A", -1, ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0 }, 1, AZ_FAIL_ID_LIST_ADD_CHK }, + /* 10*/ { BARCODE_MEMORY_FILE, ", . , ", -1, ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0 }, 1, AZ_FAIL_ID_LIST_ADD_CHK }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + char buf[3191]; + const char *text; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + if (data[i].data) { + text = data[i].data; + } else { + assert_nonzero(data[i].length > 0, "i:%d data length %d <= 0\n", i, data[i].length); + assert_nonzero(data[i].length <= ARRAY_SIZE(buf), "i:%d data length %d > buf %d\n", + i, data[i].length, ARRAY_SIZE(buf)); + text = test_many_states_data(buf, data[i].length); + } + length = testUtilSetSymbol(symbol, BARCODE_AZTEC, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + text, data[i].length, debug); + zint_test_az_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Encode(symbol, ZCUCP(text), length); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_az_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -9945,6 +10027,7 @@ int main(int argc, char *argv[]) { { "test_ct", test_ct }, { "test_ct_segs", test_ct_segs }, { "test_fuzz", test_fuzz }, + { "test_alloc", test_alloc }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_bmp.c b/backend/tests/test_bmp.c index 1279d022..3c9a0cdc 100644 --- a/backend/tests/test_bmp.c +++ b/backend/tests/test_bmp.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020-2025 Robin Stuart + Copyright (C) 2020-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -101,7 +101,7 @@ static void test_pixel_plot(const testCtx *const p_ctx) { symbol->bitmap = (unsigned char *) data_buf; - ret = zint_bmp_pixel_plot(symbol, TCU(data_buf)); + ret = zint_bmp_pixel_plot(symbol, ZCUCP(data_buf)); assert_equal(ret, data[i].ret, "i:%d zint_bmp_pixel_plot ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); @@ -201,7 +201,7 @@ static void test_print(const testCtx *const p_ctx) { strcpy(symbol->bgcolour, data[i].bgcolour); } - ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); @@ -307,12 +307,72 @@ static void test_outfile(const testCtx *const p_ctx) { testFinish(); } +#include "filemem.h" + +static void test_fm(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + const char *data; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_ACCESS, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_OPEN }, + /* 1*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 5, 11, 0, 0, 0 }, 2, FM_FAIL_ID_WRITE }, + /* 2*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + /* 3*/ { BARCODE_DATAMATRIX, BARCODE_STDOUT, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, "out.bmp"); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_fm_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ { "test_pixel_plot", test_pixel_plot }, { "test_print", test_print }, { "test_outfile", test_outfile }, + { "test_fm", test_fm }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_code1.c b/backend/tests/test_code1.c index 8b24a16b..414f44e5 100644 --- a/backend/tests/test_code1.c +++ b/backend/tests/test_code1.c @@ -210,21 +210,29 @@ static void test_large(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", + i, data[i].length, (int) strlen(data_buf)); - length = testUtilSetSymbol(symbol, BARCODE_CODEONE, -1 /*input_mode*/, data[i].eci, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODEONE, -1 /*input_mode*/, data[i].eci, + -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, + data_buf, data[i].length, debug); if (data[i].structapp.count) { symbol->structapp = data[i].structapp; } ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } ZBarcode_Delete(symbol); @@ -312,15 +320,19 @@ static void test_input(const testCtx *const p_ctx) { } ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d symbol->errtxt %s != %s\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d symbol->errtxt %s != %s\n", + i, symbol->errtxt, data[i].expected_errtxt); assert_equal(symbol->option_2, data[i].expected_option_2, "i:%d symbol->option_2 %d != %d\n", - i, symbol->option_2, data[i].expected_option_2); + i, symbol->option_2, data[i].expected_option_2); ZBarcode_Delete(symbol); } @@ -2900,7 +2912,8 @@ static void test_encode(const testCtx *const p_ctx) { char bwipp_buf[32768] ZINT_TESTUTIL_SANITIZEM_INIT; char bwipp_msg[1024]; - int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ + /* Only do BWIPP test if asked, too slow otherwise */ + int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); testStartSymbol(p_ctx->func_name, &symbol); @@ -2911,13 +2924,16 @@ static void test_encode(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_CODEONE, data[i].input_mode, data[i].eci, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODEONE, data[i].input_mode, data[i].eci, + -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, + data[i].data, data[i].length, debug); if (data[i].structapp.count) { symbol->structapp = data[i].structapp; } ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, { %d, %d, \"%s\" }, \"%s\", %d, %s, %d, %d, %d, \"%s\",\n", @@ -2936,9 +2952,11 @@ static void test_encode(const testCtx *const p_ctx) { int width, row; assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", - i, symbol->rows, data[i].expected_rows, testUtilEscape(data[i].data, length, escaped, sizeof(escaped))); + i, symbol->rows, data[i].expected_rows, testUtilEscape(data[i].data, length, + escaped, sizeof(escaped))); assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", - i, symbol->width, data[i].expected_width, testUtilEscape(data[i].data, length, escaped, sizeof(escaped))); + i, symbol->width, data[i].expected_width, testUtilEscape(data[i].data, length, + escaped, sizeof(escaped))); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", @@ -2946,14 +2964,20 @@ static void test_encode(const testCtx *const p_ctx) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, + bwipp_buf, sizeof(bwipp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, + data[i].expected); } } } @@ -3067,7 +3091,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { "0010011101100011101011" "0011010111000001111101" }, - /* 4*/ { UNICODE_MODE, -1, { 0, 0, "" }, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 70, 76, 0, "AIM ITS/04-023:2022 Annex A example; BWIPP different encodation", + /* 4*/ { UNICODE_MODE, -1, { 0, 0, "" }, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 70, 76, 1, "AIM ITS/04-023:2022 Annex A example", "1000110101010110001000100011111010110011011010101111000111000010111011110011" "0001101101110100100010010110111110100101111100011011101000110101010010101010" "0111101111011010010111011010001100110000001000101000110001000100001101101011" @@ -3088,8 +3112,8 @@ static void test_encode_segs(const testCtx *const p_ctx) { "0010101000101100001101000010101100110001111110111011000001011110101011101110" "0010100110000010010000111110011101011000000101111001010000001000001000101000" "0111100100110110111100101110101110111100011001011011001000010011111001101000" - "1110101100110101100110110010101011000011111110101000110010110100101110100010" - "1111100111101001000001010010011110001000111111101001011101110000011011100101" + "1110101100110101100110110010101011000011001101001011110010110100101110100010" + "1111100111101001000001010010011110001000001110011011111101110000011011100101" "1000101000100010001000100010100010001000100010001010001000100010001000101000" "0001100001000100010001000110000100010001000100011000010001000100010001100001" "1000111000100010001000100011100010001000100010001110001000100010001000111000" @@ -3120,24 +3144,24 @@ static void test_encode_segs(const testCtx *const p_ctx) { "0001100001000100010001000110000100010001000100011000010001000100010001100001" "1000101000100010001000100010100010001000100010001010001000100010001000101000" "0001100001000100010001000110000100010001000100011000010001000100010001100001" - "1000101000100010001000100010100010001000100010001010001000111001101111100110" - "0001100001000100010001000110000100010001000100011000010001000110100010100101" - "0101101000101000110010110110001110100100110101001000001100000010011101100010" - "0100101100111011100101111110111100100011111000111010110101000110001000100111" - "1011100010000010011110111110111011110111001100111000101011101100001101100001" - "0011111101010101000010110011010000101111001101011101101100000011001101111110" - "1001101110000000010100100110001000011000010000001001100010100101011001100000" - "1010100110110100010001001110110010011100001101001000000010100010111111100101" - "0001101110111011011001101110001100010010110101111000101011101001111000100000" - "0100100011110110101101100110010110110100101011001011011000011001000111100011" - "1010101111011001001000100110010011010011110100101010010111000101001001100110" - "1011100010101101111110010010001011100010010101111001001111010100011111100001" - "0110101001011011001101100110110001100100010000101011010010101001110100100110" - "1101101000100011101100101110100110011111100111111001010100100101111101100010" - "1100100010111011001011100010100100011110001000101011000010100011101011101111" - "1110100101000010010101100010010111010111001110011010010101111110100000100011" - "0110101011010011001101110110100011011101001011011001000100000001110011101110" - "1110110001111000110010010111100110011010101100011101011011100000011001110111" + "1000101000100010001000100010100010001000100010001010001000100110100101100110" + "0001100001000100010001000110000100010001000100011000010001110000010011100011" + "1101101010000000001001111110001110011010000010011011010011010110100110100010" + "1110101001001000011011100010011100110011111110011001101000011000110100101000" + "1000100011010000100011101010010011000100100101001010010111110100101111100001" + "1001110010011100001000011111010001001110011100011101011111011010100111110011" + "1011101100011011000000111110001100011011010011011010111100101001011101101100" + "0110101010111111010011110010100101011101010001111010100011100110000010100011" + "1011101110101111001011100110101000100111000011101000100011010101011101100100" + "1111100101001011101100011010111010100001100011111010100100101010010010101101" + "0100101001010011010000101110001011000110110101011011111001100101101101101101" + "0100100110101001111001111010101011000001001101111010000111011101101110100111" + "1100100010101000010111000010101101110000101011101001001101100011000010101010" + "1000100000001010100111010010110010100010000111101010101101111110110111101001" + "0010100111101101100111110010101101110001111111101000111110010010111000101110" + "0101100000110000001001101010111011100101011011001001100111011001111100100110" + "1111101011000100111100011110001101010100000011101000110000100111110000101110" + "1010111010101010000111011111100011000000001000111101000110011101001110111101" }, /* 5*/ { UNICODE_MODE, -1, { 0, 0, "" }, { { TU("price:$439.97"), -1, 3 }, { TU("零售价:¥3149.79"), -1, 29 }, { TU("Preis:444,90 €"), -1, 17 } }, 0, 40, 42, 1, "AIM ITS/04-023:2022 Annex A example price only", "100011010101011000101100100001110111110110" @@ -3289,7 +3313,8 @@ static void test_encode_segs(const testCtx *const p_ctx) { char bwipp_buf[32768] ZINT_TESTUTIL_SANITIZEM_INIT; char bwipp_msg[1024]; - int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ + /* Only do BWIPP test if asked, too slow otherwise */ + int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); testStartSymbol(p_ctx->func_name, &symbol); @@ -3309,20 +3334,28 @@ static void test_encode_segs(const testCtx *const p_ctx) { for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++); ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { char escaped1[4096]; char escaped2[4096]; - int length = data[i].segs[0].length == -1 ? (int) z_ustrlen(data[i].segs[0].source) : data[i].segs[0].length; - int length1 = data[i].segs[1].length == -1 ? (int) z_ustrlen(data[i].segs[1].source) : data[i].segs[1].length; - int length2 = data[i].segs[2].length == -1 ? (int) z_ustrlen(data[i].segs[2].source) : data[i].segs[2].length; - printf(" /*%3d*/ { %s, %d, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n", + int length = data[i].segs[0].length == -1 + ? (int) z_ustrlen(data[i].segs[0].source) : data[i].segs[0].length; + int length1 = data[i].segs[1].length == -1 + ? (int) z_ustrlen(data[i].segs[1].source) : data[i].segs[1].length; + int length2 = data[i].segs[2].length == -1 + ? (int) z_ustrlen(data[i].segs[2].source) : data[i].segs[2].length; + printf(" /*%3d*/ { %s, %d, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }," + " { TU(\"%s\"), %d, %d } }, %s, %d, %d, %d, \"%s\",\n", i, testUtilInputModeName(data[i].input_mode), data[i].option_2, data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, - testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci, - testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci, - testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci, + testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), + data[i].segs[0].length, data[i].segs[0].eci, + testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), + data[i].segs[1].length, data[i].segs[1].eci, + testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), + data[i].segs[2].length, data[i].segs[2].eci, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].comment); if (ret < ZINT_ERROR) { testUtilModulesPrint(symbol, " ", "\n"); @@ -3335,24 +3368,30 @@ static void test_encode_segs(const testCtx *const p_ctx) { int width, row; assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", - i, symbol->rows, data[i].expected_rows); + i, symbol->rows, data[i].expected_rows); assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", - i, symbol->width, data[i].expected_width); + i, symbol->width, data[i].expected_width); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", - i, ret, width, row); + i, ret, width, row); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwippSegs(i, symbol, -1, data[i].option_2, -1, data[i].segs, seg_count, NULL, bwipp_buf, sizeof(bwipp_buf)); - assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwippSegs(i, symbol, -1, data[i].option_2, -1, data[i].segs, seg_count, NULL, + bwipp_buf, sizeof(bwipp_buf)); + assert_zero(ret, "i:%d %s testUtilBwippSegs ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, + data[i].expected); } } } @@ -3430,13 +3469,13 @@ static void test_rt(const testCtx *const p_ctx) { if (ret < ZINT_ERROR) { assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", - i, symbol->eci, data[i].expected_eci); + i, symbol->eci, data[i].expected_eci); if (symbol->output_options & BARCODE_CONTENT_SEGS) { assert_nonnull(symbol->content_segs, "i:%d content_segs NULL\n", i); assert_nonnull(symbol->content_segs[0].source, "i:%d content_segs[0].source NULL\n", i); assert_equal(symbol->content_segs[0].length, expected_length, - "i:%d content_segs[0].length %d != expected_length %d\n", - i, symbol->content_segs[0].length, expected_length); + "i:%d content_segs[0].length %d != expected_length %d\n", + i, symbol->content_segs[0].length, expected_length); assert_zero(memcmp(symbol->content_segs[0].source, data[i].expected, expected_length), "i:%d content_segs[0].source memcmp(%s, %s, %d) != 0\n", i, testUtilEscape((const char *) symbol->content_segs[0].source, symbol->content_segs[0].length, @@ -3517,8 +3556,9 @@ static void test_rt_segs(const testCtx *const p_ctx) { assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); - assert_equal(symbol->content_seg_count, data[i].expected_content_seg_count, "i:%d symbol->content_seg_count %d != %d\n", - i, symbol->content_seg_count, data[i].expected_content_seg_count); + assert_equal(symbol->content_seg_count, data[i].expected_content_seg_count, + "i:%d symbol->content_seg_count %d != %d\n", + i, symbol->content_seg_count, data[i].expected_content_seg_count); if (symbol->output_options & BARCODE_CONTENT_SEGS) { assert_nonnull(symbol->content_segs, "i:%d content_segs NULL\n", i); for (j = 0; j < symbol->content_seg_count; j++) { @@ -3529,7 +3569,8 @@ static void test_rt_segs(const testCtx *const p_ctx) { assert_equal(symbol->content_segs[j].length, expected_length, "i:%d content_segs[%d].length %d != expected_length %d\n", i, j, symbol->content_segs[j].length, expected_length); - assert_zero(memcmp(symbol->content_segs[j].source, data[i].expected_content_segs[j].source, expected_length), + assert_zero(memcmp(symbol->content_segs[j].source, data[i].expected_content_segs[j].source, + expected_length), "i:%d content_segs[%d].source memcmp(%s, %s, %d) != 0\n", i, j, testUtilEscape((const char *) symbol->content_segs[j].source, expected_length, escaped, sizeof(escaped)), @@ -3565,7 +3606,7 @@ static void test_fuzz(const testCtx *const p_ctx) { static const struct item data[] = { /* 0*/ { -1, "3333P33B\035333V3333333333333\0363", -1, 0, 1, "" }, /* #181 Nico Gunkel, OSS-Fuzz */ /* 1*/ { -1, "{{-06\024755712162106130000000829203983\377", -1, 0, 1, "" }, /* #232 Jan Schrewe, CI-Fuzz, out-of-bounds in is_last_single_ascii() sp + 1 */ - /* 2*/ { -1, "\000\000\000\367\000\000\000\000\000\103\040\000\000\244\137\140\140\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\165\060\060\060\060\061\060\060\114\114\060\010\102\102\102\102\102\102\102\102\057\102\100\102\057\233\100\102", 60, 0, 1, "" }, /* #300 (#4) Andre Maute (`c1_c40text_cnt()` not accounting for extended ASCII shifts) */ + /* 2*/ { -1, "\000\000\000\367\000\000\000\000\000\103\040\000\000\244\137\140\140\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\165\060\060\060\060\061\060\060\114\114\060\010\102\102\102\102\102\102\102\102\057\102\100\102\057\233\100\102", 60, 0, 0, "" }, /* #300 (#4) Andre Maute (`c1_c40text_cnt()` not accounting for extended ASCII shifts); BWIPP: different encodation (does not switch at end to C40, same no. of codewords) */ /* 3*/ { 10, "\153\153\153\060\001\000\134\153\153\015\015\353\362\015\015\015\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\362\362\000", 65, ZINT_ERROR_TOO_LONG, 1, "" }, /* #300 (#8) Andre Maute (`c1_encode()` looping on latch) */ /* 4*/ { 10, "\015\015\353\362\015\015\015\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\110\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\362\362\000", 39, 0, 1, "" }, /* #300 (#8 shortened) Andre Maute */ /* 5*/ { 10, "\153\153\153\153\153\060\001\000\000\134\153\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\153\153\153\153\153\043\000\000\307\000\147\000\000\000\043\113\153\162\162\215\220", 90, ZINT_ERROR_TOO_LONG, 1, "" }, /* #300 (#12) Andre Maute (too small buffer for Version T) */ @@ -3577,7 +3618,8 @@ static void test_fuzz(const testCtx *const p_ctx) { char bwipp_buf[32768] ZINT_TESTUTIL_SANITIZEM_INIT; char bwipp_msg[1024]; - int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); /* Only do BWIPP test if asked, too slow otherwise */ + /* Only do BWIPP test if asked, too slow otherwise */ + int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); testStartSymbol(p_ctx->func_name, &symbol); @@ -3588,24 +3630,34 @@ static void test_fuzz(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_CODEONE, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODEONE, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, + data[i].data, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[4096]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, + sizeof(bwipp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, modules_dump); + i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, + modules_dump); } } } diff --git a/backend/tests/test_code128.c b/backend/tests/test_code128.c index da1f3a56..b71b4034 100644 --- a/backend/tests/test_code128.c +++ b/backend/tests/test_code128.c @@ -1346,6 +1346,7 @@ static void test_upu_s10_input(const testCtx *const p_ctx) { int debug = p_ctx->debug; struct item { + int output_options; const char *data; int ret; int expected_width; @@ -1353,36 +1354,37 @@ static void test_upu_s10_input(const testCtx *const p_ctx) { const char *comment; }; static const struct item data[] = { - /* 0*/ { "AB123456789ABC", ZINT_ERROR_TOO_LONG, 0, "Error 834: Input length 14 wrong (12 or 13 characters required)", "" }, - /* 1*/ { "AB1234567AB", ZINT_ERROR_TOO_LONG, 0, "Error 834: Input length 11 wrong (12 or 13 characters required)", "" }, - /* 2*/ { "1B123456789AB", ZINT_ERROR_INVALID_DATA, 0, "Error 835: Invalid character in Service Indicator (first 2 characters) (alphabetic only)", "" }, - /* 3*/ { "1B12345678AB", ZINT_ERROR_INVALID_DATA, 0, "Error 835: Invalid character in Service Indicator (first 2 characters) (alphabetic only)", "" }, - /* 4*/ { "A2123456789AB", ZINT_ERROR_INVALID_DATA, 0, "Error 835: Invalid character in Service Indicator (first 2 characters) (alphabetic only)", "" }, - /* 5*/ { "A212345678AB", ZINT_ERROR_INVALID_DATA, 0, "Error 835: Invalid character in Service Indicator (first 2 characters) (alphabetic only)", "" }, - /* 6*/ { "ABX23456789AB", ZINT_ERROR_INVALID_DATA, 0, "Error 836: Invalid character in Serial Number (middle 9 characters) (digits only)", "" }, - /* 7*/ { "AB12345678XAB", ZINT_ERROR_INVALID_DATA, 0, "Error 836: Invalid character in Serial Number (middle 9 characters) (digits only)", "" }, - /* 8*/ { "ABX2345678AB", ZINT_ERROR_INVALID_DATA, 0, "Error 836: Invalid character in Serial Number (middle 8 characters) (digits only)", "" }, - /* 9*/ { "AB1234567XAB", ZINT_ERROR_INVALID_DATA, 0, "Error 836: Invalid character in Serial Number (middle 8 characters) (digits only)", "" }, - /* 10*/ { "AB1234567891B", ZINT_ERROR_INVALID_DATA, 0, "Error 837: Invalid character in Country Code (last 2 characters) (alphabetic only)", "" }, - /* 11*/ { "AB123456781B", ZINT_ERROR_INVALID_DATA, 0, "Error 837: Invalid character in Country Code (last 2 characters) (alphabetic only)", "" }, - /* 12*/ { "AB123456789A2", ZINT_ERROR_INVALID_DATA, 0, "Error 837: Invalid character in Country Code (last 2 characters) (alphabetic only)", "" }, - /* 13*/ { "AB12345678A2", ZINT_ERROR_INVALID_DATA, 0, "Error 837: Invalid character in Country Code (last 2 characters) (alphabetic only)", "" }, - /* 14*/ { "AB123456789AB", ZINT_ERROR_INVALID_CHECK, 0, "Error 838: Invalid check digit '9', expecting '5'", "" }, - /* 15*/ { "JB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'JB' (first character should not be any of \"JKSTW\")", "" }, - /* 16*/ { "KB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'KB' (first character should not be any of \"JKSTW\")", "" }, - /* 17*/ { "LB123456785AD", 0, 156, "", "" }, - /* 18*/ { "SB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'SB' (first character should not be any of \"JKSTW\")", "" }, - /* 19*/ { "TB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'TB' (first character should not be any of \"JKSTW\")", "" }, - /* 20*/ { "WB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'WB' (first character should not be any of \"JKSTW\")", "" }, - /* 21*/ { "FB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'FB' (first 2 characters)", "" }, - /* 22*/ { "HB123456785AD", 0, 156, "", "" }, - /* 23*/ { "IB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'IB' (first 2 characters)", "" }, - /* 24*/ { "OB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'OB' (first 2 characters)", "" }, - /* 25*/ { "XB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'XB' (first 2 characters)", "" }, - /* 26*/ { "YB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'YB' (first 2 characters)", "" }, - /* 27*/ { "AB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 841: Country Code 'AB' (last two characters) is not ISO 3166-1", "" }, - /* 28*/ { "AB123100000IE", 0, 156, "", "Check digit 10 -> 0" }, - /* 29*/ { "AB000000005IE", 0, 156, "", "Check digit 11 -> 5" }, + /* 0*/ { -1, "AB123456789ABC", ZINT_ERROR_TOO_LONG, 0, "Error 834: Input length 14 wrong (12 or 13 characters required)", "" }, + /* 1*/ { -1, "AB1234567AB", ZINT_ERROR_TOO_LONG, 0, "Error 834: Input length 11 wrong (12 or 13 characters required)", "" }, + /* 2*/ { -1, "1B123456789AB", ZINT_ERROR_INVALID_DATA, 0, "Error 835: Invalid character in Service Indicator (first 2 characters) (alphabetic only)", "" }, + /* 3*/ { -1, "1B12345678AB", ZINT_ERROR_INVALID_DATA, 0, "Error 835: Invalid character in Service Indicator (first 2 characters) (alphabetic only)", "" }, + /* 4*/ { -1, "A2123456789AB", ZINT_ERROR_INVALID_DATA, 0, "Error 835: Invalid character in Service Indicator (first 2 characters) (alphabetic only)", "" }, + /* 5*/ { -1, "A212345678AB", ZINT_ERROR_INVALID_DATA, 0, "Error 835: Invalid character in Service Indicator (first 2 characters) (alphabetic only)", "" }, + /* 6*/ { -1, "ABX23456789AB", ZINT_ERROR_INVALID_DATA, 0, "Error 836: Invalid character in Serial Number (middle 9 characters) (digits only)", "" }, + /* 7*/ { -1, "AB12345678XAB", ZINT_ERROR_INVALID_DATA, 0, "Error 836: Invalid character in Serial Number (middle 9 characters) (digits only)", "" }, + /* 8*/ { -1, "ABX2345678AB", ZINT_ERROR_INVALID_DATA, 0, "Error 836: Invalid character in Serial Number (middle 8 characters) (digits only)", "" }, + /* 9*/ { -1, "AB1234567XAB", ZINT_ERROR_INVALID_DATA, 0, "Error 836: Invalid character in Serial Number (middle 8 characters) (digits only)", "" }, + /* 10*/ { -1, "AB1234567891B", ZINT_ERROR_INVALID_DATA, 0, "Error 837: Invalid character in Country Code (last 2 characters) (alphabetic only)", "" }, + /* 11*/ { -1, "AB123456781B", ZINT_ERROR_INVALID_DATA, 0, "Error 837: Invalid character in Country Code (last 2 characters) (alphabetic only)", "" }, + /* 12*/ { -1, "AB123456789A2", ZINT_ERROR_INVALID_DATA, 0, "Error 837: Invalid character in Country Code (last 2 characters) (alphabetic only)", "" }, + /* 13*/ { -1, "AB12345678A2", ZINT_ERROR_INVALID_DATA, 0, "Error 837: Invalid character in Country Code (last 2 characters) (alphabetic only)", "" }, + /* 14*/ { -1, "AB123456789AB", ZINT_ERROR_INVALID_CHECK, 0, "Error 838: Invalid check digit '9', expecting '5'", "" }, + /* 15*/ { -1, "JB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'JB' (first character should not be any of \"JKSTW\")", "" }, + /* 16*/ { -1, "KB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'KB' (first character should not be any of \"JKSTW\")", "" }, + /* 17*/ { -1, "LB123456785AD", 0, 156, "", "" }, + /* 18*/ { -1, "SB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'SB' (first character should not be any of \"JKSTW\")", "" }, + /* 19*/ { -1, "TB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'TB' (first character should not be any of \"JKSTW\")", "" }, + /* 20*/ { -1, "WB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 839: Invalid Service Indicator 'WB' (first character should not be any of \"JKSTW\")", "" }, + /* 21*/ { -1, "FB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'FB' (first 2 characters)", "" }, + /* 22*/ { -1, "HB123456785AD", 0, 156, "", "" }, + /* 23*/ { -1, "IB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'IB' (first 2 characters)", "" }, + /* 24*/ { -1, "OB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'OB' (first 2 characters)", "" }, + /* 25*/ { -1, "XB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'XB' (first 2 characters)", "" }, + /* 26*/ { -1, "YB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 840: Non-standard Service Indicator 'YB' (first 2 characters)", "" }, + /* 27*/ { -1, "AB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 841: Country Code 'AB' (last two characters) is not ISO 3166-1", "" }, + /* 28*/ { COMPLIANT_HEIGHT, "AB123456785AB", ZINT_WARN_NONCOMPLIANT, 156, "Warning 841: Country Code 'AB' (last two characters) is not ISO 3166-1", "" }, + /* 29*/ { -1, "AB123100000IE", 0, 156, "", "Check digit 10 -> 0" }, + /* 30*/ { -1, "AB000000005IE", 0, 156, "", "Check digit 11 -> 5" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1408,15 +1410,16 @@ static void test_upu_s10_input(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); length = testUtilSetSymbol(symbol, BARCODE_UPU_S10, UNICODE_MODE, -1 /*eci*/, - -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { - printf(" /*%3d*/ { \"%s\", %s, %d, \"%s\", \"%s\" },\n", - i, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), + printf(" /*%3d*/ { %s, \"%s\", %s, %d, \"%s\", \"%s\" },\n", + i, testUtilOutputOptionsName(data[i].output_options), + testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->width, testUtilEscape(symbol->errtxt, (int) strlen(symbol->errtxt), escaped2, sizeof(escaped2)), data[i].comment); } else { diff --git a/backend/tests/test_code16k.c b/backend/tests/test_code16k.c index 6be6affb..964f2698 100644 --- a/backend/tests/test_code16k.c +++ b/backend/tests/test_code16k.c @@ -72,18 +72,26 @@ static void test_large(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", + i, data[i].length, (int) strlen(data_buf)); - length = testUtilSetSymbol(symbol, BARCODE_CODE16K, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data_buf, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODE16K, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1, -1, -1 /*output_options*/, + data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } ZBarcode_Delete(symbol); @@ -128,10 +136,13 @@ static void test_reader_init(const testCtx *const p_ctx) { symbol->debug = ZINT_DEBUG_TEST; /* Needed to get codeword dump in errtxt */ - length = testUtilSetSymbol(symbol, BARCODE_CODE16K, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1 /*option_2*/, -1, data[i].output_options, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODE16K, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1, data[i].output_options, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", @@ -139,10 +150,13 @@ static void test_reader_init(const testCtx *const p_ctx) { testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); } } @@ -230,7 +244,9 @@ static void test_input(const testCtx *const p_ctx) { /* 45*/ { UNICODE_MODE, -1, -1, 0, "ÿ12345678\012à12345678abcdef\0121\01223456\012\0127890àAàBCDEFà\012\012à", -1, 0, 12, 70, 0, 1, "(60) 76 100 95 12 34 56 78 101 74 101 98 64 99 12 34 56 78 100 65 66 67 68 69 70 98 74 17", 12, 0, "BWIPP different encodation, uses Sh2C + other differences" }, /* 46*/ { UNICODE_MODE, COMPLIANT_HEIGHT, -1, 4, "A", -1, 0, 2, 70, 1, 1, "(10) 1 33 103 103 103 103 103 103 52 82", 2, 4, "option_3 separator" }, /* 47*/ { UNICODE_MODE, COMPLIANT_HEIGHT, -1, 5, "A", -1, 0, 2, 70, 1, 1, "(10) 1 33 103 103 103 103 103 103 52 82", 2, 1, "option_3 invalid 5 -> 1" }, - /* 48*/ { UNICODE_MODE, -1, -1, 5, "A", -1, 0, 2, 70, 1, 1, "(10) 1 33 103 103 103 103 103 103 52 82", 2, 5, "option_3 invalid 5 ignored unless COMPLIANT_HEIGHT" }, + /* 48*/ { DATA_MODE, -1, -1, 0, "A\007A\200", -1, 0, 2, 70, 1, 899, "(10) 0 33 71 33 101 64 103 103 36 66", 2, 0, "" }, + /* 49*/ { DATA_MODE, -1, -1, 0, "1234A\007A\200", -1, 0, 3, 70, 1, 899, "(15) 9 12 34 101 33 71 33 101 64 103 103 103 103 7 91", 3, 0, "" }, + /* 50*/ { GS1_MODE, -1, -1, 0, "[10]1[90]1", -1, 0, 2, 70, 1, 1, "(10) 4 10 100 17 102 25 16 17 93 104", 2, 0, "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -260,7 +276,8 @@ static void test_input(const testCtx *const p_ctx) { data[i].data, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %d, %d, \"%s\", %d, %s, %d, %d, %d, %d, \"%s\", %d, %d, \"%s\" },\n", @@ -270,19 +287,28 @@ static void test_input(const testCtx *const p_ctx) { testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].bwipp_cmp, data[i].zxingcpp_cmp, symbol->errtxt, symbol->option_1, symbol->option_3, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[4096]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, cmp_buf, + sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -398,10 +424,13 @@ static void test_encode(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_CODE16K, data[i].input_mode, -1 /*eci*/, data[i].option_1, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_CODE16K, data[i].input_mode, -1 /*eci*/, + data[i].option_1, -1, -1, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, \"%s\", %s, %d, %d, \"%s\",\n", @@ -414,19 +443,25 @@ static void test_encode(const testCtx *const p_ctx) { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, ret, width, row, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, -1, -1, debug)) { - ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, data[i].option_1, -1, -1, data[i].data, length, NULL, cmp_buf, + sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; @@ -500,7 +535,8 @@ static void test_rt(const testCtx *const p_ctx) { expected_length = data[i].expected_length == -1 ? (int) strlen(data[i].expected) : data[i].expected_length; ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (ret < ZINT_ERROR) { assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", @@ -513,8 +549,8 @@ static void test_rt(const testCtx *const p_ctx) { i, symbol->content_segs[0].length, expected_length); assert_zero(memcmp(symbol->content_segs[0].source, data[i].expected, expected_length), "i:%d content_segs[0].source memcmp(%s, %s, %d) != 0\n", i, - testUtilEscape((const char *) symbol->content_segs[0].source, symbol->content_segs[0].length, - escaped, sizeof(escaped)), + testUtilEscape((const char *) symbol->content_segs[0].source, + symbol->content_segs[0].length, escaped, sizeof(escaped)), testUtilEscape(data[i].expected, expected_length, escaped2, sizeof(escaped2)), expected_length); assert_equal(symbol->content_segs[0].eci, data[i].expected_content_eci, diff --git a/backend/tests/test_common.c b/backend/tests/test_common.c index 2a45248c..eef7fdf0 100644 --- a/backend/tests/test_common.c +++ b/backend/tests/test_common.c @@ -55,20 +55,37 @@ static void test_isXXX(const testCtx *const p_ctx) { struct item { char ch; + int ret_isxdigit; + int ret_isalpha; int ret_isascii; int ret_iscntrl; }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { '\177', 1, 1 }, /* DEL */ - /* 1*/ { '\200', 0, 0 }, - /* 3*/ { '\0', 1, 1 }, - /* 3*/ { '\001', 1, 1 }, /* SOH */ - /* 2*/ { '\t', 1, 1 }, - /* 4*/ { '\037', 1, 1 }, /* US */ - /* 5*/ { ' ', 1, 0 }, - /* 6*/ { '!', 1, 0 }, - /* 7*/ { '~', 1, 0 }, + /* 0*/ { '0', 1, 0, 1, 0 }, + /* 1*/ { '9', 1, 0, 1, 0 }, + /* 2*/ { 'A', 1, 1, 1, 0 }, + /* 3*/ { 'F', 1, 1, 1, 0 }, + /* 4*/ { 'a', 1, 1, 1, 0 }, + /* 5*/ { 'f', 1, 1, 1, 0 }, + /* 6*/ { '\177', 0, 0, 1, 1 }, /* DEL */ + /* 7*/ { '\200', 0, 0, 0, 0 }, + /* 8*/ { '\377', 0, 0, 0, 0 }, + /* 9*/ { '\0', 0, 0, 1, 1 }, + /* 10*/ { '\001', 0, 0, 1, 1 }, /* SOH */ + /* 11*/ { '\t', 0, 0, 1, 1 }, + /* 12*/ { '\037', 0, 0, 1, 1 }, /* US */ + /* 13*/ { ' ', 0, 0, 1, 0 }, + /* 14*/ { '!', 0, 0, 1, 0 }, + /* 15*/ { '~', 0, 0, 1, 0 }, + /* 16*/ { '@', 0, 0, 1, 0 }, + /* 17*/ { 'G', 0, 1, 1, 0 }, + /* 18*/ { 'Z', 0, 1, 1, 0 }, + /* 19*/ { '[', 0, 0, 1, 0 }, + /* 20*/ { '`', 0, 0, 1, 0 }, + /* 21*/ { 'g', 0, 1, 1, 0 }, + /* 22*/ { 'z', 0, 1, 1, 0 }, + /* 23*/ { '{', 0, 0, 1, 0 }, }; const int data_size = ARRAY_SIZE(data); int i, ret; @@ -79,6 +96,9 @@ static void test_isXXX(const testCtx *const p_ctx) { if (testContinue(p_ctx, i)) continue; + ret = z_isxdigit(data[i].ch); + assert_equal(ret, data[i].ret_isxdigit, "i:%d isxdigit ret %d != %d\n", i, ret, data[i].ret_isxdigit); + ret = z_isascii(data[i].ch); assert_equal(ret, data[i].ret_isascii, "i:%d isascii ret %d != %d\n", i, ret, data[i].ret_isascii); @@ -1196,6 +1216,35 @@ static void test_hrt_conv_gs1_brackets_nochk(const testCtx *const p_ctx) { testFinish(); } +static void test_ct_init_segs(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + int ret; + + struct zint_symbol s_symbol = {0}; + struct zint_symbol *symbol = &s_symbol; + + testStart(p_ctx->func_name); + + symbol->debug = debug; + + ret = z_ct_init_segs(symbol, 1); + assert_zero(ret, "z_ct_init_segs %d != 0\n", ret); + ZBarcode_Clear(symbol); + + ret = z_ct_init_segs(symbol, 1); + assert_zero(ret, "z_ct_init_segs %d != 0\n", ret); + ret = z_ct_init_segs(symbol, 2); + assert_zero(ret, "z_ct_init_segs %d != 0\n", ret); + ZBarcode_Clear(symbol); + + zint_test_ct_set_fail(Z_CT_FAIL_ID_INIT_SEGS, 1); + ret = z_ct_init_segs(symbol, 1); + assert_equal(ret, ZINT_ERROR_MEMORY, "z_ct_init_segs %d != 0, ZINT_ERROR_MEMORY\n", ret); + zint_test_ct_set_fail(0, 0); + + testFinish(); +} + static void test_ct_cpy_segs(const testCtx *const p_ctx) { int debug = p_ctx->debug; @@ -1678,6 +1727,7 @@ int main(int argc, char *argv[]) { { "test_hrt_cpy_cat_nochk", test_hrt_cpy_cat_nochk }, { "test_hrt_printf_nochk", test_hrt_printf_nochk }, { "test_hrt_conv_gs1_brackets_nochk", test_hrt_conv_gs1_brackets_nochk }, + { "test_ct_init_segs", test_ct_init_segs }, { "test_ct_cpy_segs", test_ct_cpy_segs }, { "test_ct_set_seg_extra_escapes_eci", test_ct_set_seg_extra_escapes_eci }, { "test_ct_cpy", test_ct_cpy }, diff --git a/backend/tests/test_composite.c b/backend/tests/test_composite.c index 64091db9..a834a271 100644 --- a/backend/tests/test_composite.c +++ b/backend/tests/test_composite.c @@ -4088,6 +4088,8 @@ static void test_input(const testCtx *const p_ctx) { int option_1; int option_2; int option_3; + int output_options; + float height; const char *data; const char *composite; @@ -4101,150 +4103,164 @@ static void test_input(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, "1234567", "[20]12", 0, 8, 72, "", 1, 0, 0 }, - /* 1*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "1234567", "[20]12", 0, 8, 72, "", 1, 0, 0 }, /* EAN-8 */ - /* 2*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, "123456A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 7 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, - /* 3*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "123456A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 7 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, /* EAN-8 */ - /* 4*/ { BARCODE_EAN8_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 7 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /* 5*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 7 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /* 6*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, "1234567", "[20]1A", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, - /* 7*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "1234567", "[20]1A", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, - /* 8*/ { BARCODE_EAN8_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567", "[20]1A", 0, 8, 72, "", 1, 0, 0 }, - /* 9*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567", "[20]1A", 0, 8, 72, "", 1, 0, 0 }, - /* 10*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, "1234567", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /* 11*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "1234567", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /* 12*/ { BARCODE_EAN8_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567", "[02]12345678901234", 0, 8, 72, "", 1, 0, 0 }, - /* 13*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567", "[02]12345678901234", 0, 8, 72, "", 1, 0, 0 }, - /* 14*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, "12345670", "[20]12", 0, 8, 72, "", 1, 0, 0 }, - /* 15*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "12345670", "[20]12", 0, 7, 99, "", 1, 0, 0 }, - /* 16*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "12345670", "[20]12", 0, 7, 99, "", 1, 0, 0 }, /* EAN-13 for EANX_CC as length 8 only EAN-8 for EANX_CHK */ - /* 17*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "123456789012", "[20]12", 0, 7, 99, "", 1, 0, 0 }, - /* 18*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "123456789012", "[20]12", 0, 7, 99, "", 1, 0, 0 }, /* EAN-13 */ - /* 19*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "1234567890128", "[20]12", 0, 7, 99, "", 1, 0, 0 }, - /* 20*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "1234567890128", "[20]12", 0, 7, 99, "", 1, 0, 0 }, /* EAN-13 */ - /* 21*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "1234567890123", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 275: Invalid check digit '3', expecting '8' (linear component)", 1, 0, 0 }, - /* 22*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "1234567890123", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 275: Invalid check digit '3', expecting '8' (linear component)", 1, 0, 0 }, - /* 23*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890123", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 275: Invalid check digit '3', expecting '8' (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /* 24*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890123", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 275: Invalid check digit '3', expecting '8' (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /* 25*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "12345678901234", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 294: Input length 14 too long (maximum 13) (linear component)", -1, 0, 0 }, - /* 26*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "12345678901234", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 294: Input length 14 too long (maximum 13) (linear component)", -1, 0, 0 }, - /* 27*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901234", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 294: Input length 14 too long (maximum 13) (linear component)", -1, 0, 0 }, - /* 28*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901234", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 294: Input length 14 too long (maximum 13) (linear component)", -1, 0, 0 }, - /* 29*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "123456789012A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 13 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, - /* 30*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "123456789012A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 13 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, - /* 31*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456789012A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 13 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, - /* 32*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456789012A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 13 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, - /* 33*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "1234567890128", "[20]1A", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ - /* 34*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "1234567890128", "[20]1A", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ - /* 35*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890128", "[20]1A", 0, 7, 99, "", 1, 0, 0 }, - /* 36*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890128", "[20]1A", 0, 7, 99, "", 1, 0, 0 }, - /* 37*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "1234567890128", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /* 38*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "1234567890128", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /* 39*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890128", "[02]12345678901234", 0, 7, 99, "", 1, 0, 0 }, - /* 40*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890128", "[02]12345678901234", 0, 7, 99, "", 1, 0, 0 }, - /* 41*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "1234567890128", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567", 0, 48, 99, "", 2, 0, 0 }, /* Max CC-B for EAN-13 */ - /* 42*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "1234567890128", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567", 0, 48, 99, "", 2, 0, 0 }, /* Max CC-B for EAN-13 */ - /* 43*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "1234567890128", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]1234567890123456789012345678901234567890123456789012345678", ZINT_ERROR_TOO_LONG, -1, -1, "Error 444: Input too long (2D component)", -1, 0, 0 }, - /* 44*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "1234567890128", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]1234567890123456789012345678901234567890123456789012345678", ZINT_ERROR_TOO_LONG, -1, -1, "Error 444: Input too long (2D component)", -1, 0, 0 }, - /* 45*/ { BARCODE_EAN13_CC, -1, 3, -1, -1, "1234567890128", "[20]12", ZINT_ERROR_INVALID_OPTION, -1, -1, "Error 447: Invalid mode (CC-C only valid with GS1-128 linear component)", 3, 0, 0 }, - /* 46*/ { BARCODE_EANX_CC, -1, 3, -1, -1, "1234567890128", "[20]12", ZINT_ERROR_INVALID_OPTION, -1, -1, "Error 447: Invalid mode (CC-C only valid with GS1-128 linear component)", 3, 0, 0 }, - /* 47*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, "123456789012345678901", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 449: Input length 21 wrong (linear component)", -1, 0, 0 }, - /* 48*/ { BARCODE_EANX_CC, -1, -1, -1, -1, "123456789012345678901", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 449: Input length 21 wrong (linear component)", -1, 0, 0 }, - /* 49*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, "1234567890123", "[20]12", 0, 5, 100, "", 1, 0, 0 }, - /* 50*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, "12345678901231", "[20]12", 0, 5, 100, "", 1, 0, 0 }, - /* 51*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, - /* 52*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /* 53*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, "123456789012312", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, - /* 54*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456789012312", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, - /* 55*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, - /* 56*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, - /* 57*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 5, 100, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ - /* 58*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901231", "[20]1A", 0, 5, 100, "", 1, 0, 0 }, - /* 59*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, "12345678901231", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 5, 100, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /* 60*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901231", "[02]12345678901234", 0, 5, 100, "", 1, 0, 0 }, - /* 61*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, "1234567890123", "[20]12", 0, 6, 79, "", 1, 0, 0 }, - /* 62*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, "12345678901231", "[20]12", 0, 6, 79, "", 1, 0, 0 }, - /* 63*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 389: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, - /* 64*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 389: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /* 65*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, "123456789012345", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, - /* 66*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456789012345", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, - /* 67*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, "A1234567890123", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 383: Invalid character at position 1 in input (digits only) (linear component)", 1, 0, 0 }, - /* 68*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, "A1234567890123", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 383: Invalid character at position 1 in input (digits only) (linear component)", 1, 0, 0 }, - /* 69*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 6, 79, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ - /* 70*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901231", "[20]1A", 0, 6, 79, "", 1, 0, 0 }, - /* 71*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, "12345678901231", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 6, 79, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /* 72*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901231", "[02]12345678901234", 0, 6, 79, "", 1, 0, 0 }, - /* 73*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, "12345678901", "[20]12", 0, 7, 99, "", 1, 0, 0 }, - /* 74*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, "123456789012", "[20]12", 0, 7, 99, "", 1, 0, 0 }, - /* 75*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, "123456789013", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 270: Invalid check digit '3', expecting '2' (linear component)", 1, 0, 0 }, - /* 76*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456789013", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 270: Invalid check digit '3', expecting '2' (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /* 77*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, "1234567890123", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 289: Input length 13 too long (maximum 12) (linear component)", 1, 0, 0 }, - /* 78*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890123", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 289: Input length 13 too long (maximum 12) (linear component)", 1, 0, 0 }, - /* 79*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, "12345678901A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 12 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, - /* 80*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 12 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, - /* 81*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, "123456789012", "[20]1A", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ - /* 82*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456789012", "[20]1A", 0, 7, 99, "", 1, 0, 0 }, - /* 83*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, "123456789012", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /* 84*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456789012", "[02]12345678901234", 0, 7, 99, "", 1, 0, 0 }, - /* 85*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, "123456", "[20]12", 0, 9, 55, "", 1, 0, 0 }, - /* 86*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, "1234567", "[20]12", 0, 9, 55, "", 1, 0, 0 }, - /* 87*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, "12345670", "[20]12", 0, 9, 55, "", 1, 0, 0 }, /* Check digit can now be given for UPCE_CC, like UPCA_CC */ - /* 88*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, "12345671", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 274: Invalid check digit '1', expecting '0' (linear component)", 1, 0, 0 }, - /* 89*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345671", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 274: Invalid check digit '1', expecting '0' (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /* 90*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, "123456712", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 291: Input length 9 too long (maximum 8) (linear component)", 1, 0, 0 }, - /* 91*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456712", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 291: Input length 9 too long (maximum 8) (linear component)", 1, 0, 0 }, - /* 92*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, "1234567A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 8 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, - /* 93*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 8 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, - /* 94*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, "1234567", "[20]1A", ZINT_WARN_NONCOMPLIANT, 9, 55, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ - /* 95*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567", "[20]1A", 0, 9, 55, "", 1, 0, 0 }, - /* 96*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, "1234567", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 9, 55, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /* 97*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567", "[02]12345678901234", 0, 9, 55, "", 1, 0, 0 }, - /* 98*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, "1234567890123", "[20]12", 0, 9, 56, "", 1, 0, 0 }, - /* 99*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, "12345678901231", "[20]12", 0, 9, 56, "", 1, 0, 0 }, - /*100*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, - /*101*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /*102*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, "123456789012323", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, - /*103*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456789012323", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, - /*104*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, - /*105*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, - /*106*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 9, 56, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ - /*107*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901231", "[20]1A", 0, 9, 56, "", 1, 0, 0 }, - /*108*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, "12345678901231", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 9, 56, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /*109*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901231", "[02]12345678901234", 0, 9, 56, "", 1, 0, 0 }, - /*110*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, "1234567890123", "[20]12", 0, 11, 56, "", 1, 0, 0 }, - /*111*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, "12345678901231", "[20]12", 0, 11, 56, "", 1, 0, 0 }, - /*112*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, - /*113*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, /* Linear component still checked */ - /*114*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, "123456789012312", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, - /*115*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, "123456789012312", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, - /*116*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, - /*117*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, - /*118*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 11, 56, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ - /*119*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901231", "[20]1A", 0, 11, 56, "", 1, 0, 0 }, - /*120*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, "12345678901231", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 11, 56, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, - /*121*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, "12345678901231", "[02]12345678901234", 0, 11, 56, "", 1, 0, 0 }, - /*122*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, "", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 445: No primary (linear component)", -1, 0, 0 }, - /*123*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, "[01]12345678901231", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[95]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[96]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[97]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[98]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[99]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, 31, 273, "", 3, 0, 0 }, /* Tries CC-A then CC-B then CC-C - ensure errtxt empty */ - /*124*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, "[01]12345678901231[90]123456789012345678901234567890[91]1234567890123456789012345678901234567890123456789012345678901234", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[95]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[96]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[97]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[98]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[99]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[95]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[96]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[97]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[98]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[99]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567890123", ZINT_WARN_NONCOMPLIANT, 29, 702, "Warning 843: Input too long, requires 115 characters (maximum 48) (linear component)", 3, 0, 0 }, /* Overlarge linear and CC-C input */ - /*125*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, "[01]12345678901231[90]123456789012345678901234567890[91]1234567890123456789012345678901234567890123456789012345678901234", "[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[94]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[95]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[96]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[97]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[98]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[99]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[94]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[95]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[96]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL", ZINT_ERROR_TOO_LONG, -1, -1, "Error 442: Input too long (2D component)", -1, 0, 0 }, /* Overlarge linear and oversized CC-C input */ - /*126*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, "[01]12345678901231", "[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[94]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[95]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[96]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[97]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[98]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[99]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[94]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[95]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[96]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHI" "JKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLM", ZINT_ERROR_TOO_LONG, -1, -1, "Error 446: 2D component input too long, requires 2991 characters (maximum 2990)", -1, 0, 0 }, /* Reduced length 2291 */ - /*127*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, "[01]12345678901231", "[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012" "345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[11]121212[20]12", 0, 32, 579, "", 3, 0, 0 }, /* Reduced length 2372 digits (no FNC1s) with not recommended ECC 4 > 2361 digit limit given in ISO/IEC 24723:2010 4.1 (d)(2)(iii) */ - /*128*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, "[90]ABCDEFGHIJKLMNOPQRSTUVWXYXABCD[91]ABCDEFGHIJKLMNOPQRSTUVWXYABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLM", "[20]12", ZINT_WARN_NONCOMPLIANT, 5, 1146, "Warning 843: Input too long, requires 99 characters (maximum 48) (linear component)", 1, 0, 0 }, - /*129*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, "[90]ABCDEFGHIJKLMNOPQRSTUVWXYXABCD[91]ABCDEFGHIJKLMNOPQRSTUVWXYABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMN", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 344: Input too long, requires 103 symbol characters (maximum 102) (linear component)", -1, 0, 0 }, - /*130*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, -1, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 0, 0 }, - /*131*/ { BARCODE_DBAR_EXPSTK_CC, -1, 1, -1, -1, "[91]1234567890123456789012345678901234", "[91]123456789012345678901234567890123456789012345678901234", 0, 17, 102, "", 1, 0, 0 }, - /*132*/ { BARCODE_DBAR_EXPSTK_CC, -1, 1, -1, -1, "[91]1234567890123456789012345678901234", "[91]1234567890123456789012345678901234567890123456789012345", ZINT_WARN_INVALID_OPTION, 20, 102, "Warning 443: Composite type changed from CC-A to CC-B", 2, 0, 0 }, - /*133*/ { BARCODE_GS1_128_CC, -1, 1, -1, -1, "[01]12345678901231", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]1234567890123456789012345678901234567890123456789012345678", ZINT_WARN_INVALID_OPTION, 31, 154, "Warning 443: Composite type changed from CC-A to CC-C", 3, 0, 0 }, - /*134*/ { BARCODE_GS1_128_CC, -1, 2, -1, -1, "[01]12345678901231", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]1234567890123456789012345678901234567890123456789012345678", ZINT_WARN_INVALID_OPTION, 31, 154, "Warning 443: Composite type changed from CC-B to CC-C", 3, 0, 0 }, - /*135*/ { BARCODE_GS1_128_CC, -1, 1, -1, -1, "[90]ABCDEFGHIJKLMNOPQRSTUVWXYXABCD[91]ABCDEFGHIJKLM", "[91]1234567890123456789012345678901234567890123456789012345", ZINT_WARN_INVALID_OPTION, 12, 585, "Warning 443: Composite type changed from CC-A to CC-B", 2, 0, 0 }, - /*136*/ { BARCODE_GS1_128_CC, -1, 1, -1, -1, "[90]ABCDEFGHIJKLMNOPQRSTUVWXYXABCD[91]ABCDEFGHIJKLMN", "[91]1234567890123456789012345678901234567890123456789012345", ZINT_WARN_NONCOMPLIANT, 12, 596, "Warning 843: Input too long, requires 49 characters (maximum 48) (linear component)", 2, 0, 0 }, /* Other warnings trump CC type change */ - /*137*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 1, -1, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 1, 0 }, - /*138*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 2, -1, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 2, 0 }, - /*139*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 3, -1, "[91]1234567890123456789012345678901234", "[20]12", 0, 9, 151, "", 1, 3, 0 }, - /*140*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 4, -1, "[91]1234567890123456789012345678901234", "[20]12", 0, 9, 200, "", 1, 4, 0 }, - /*141*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, 2, "[91]1234567890123456789012345678901234", "[20]12", 0, 9, 151, "", 1, 0, 2 }, - /*142*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, 3, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 0, 3 }, - /*143*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, 4, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 0, 4 }, + /* 0*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, -1, 0.0f, "1234567", "[20]12", 0, 8, 72, "", 1, 0, 0 }, + /* 1*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "1234567", "[20]12", 0, 8, 72, "", 1, 0, 0 }, /* EAN-8 */ + /* 2*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, -1, 0.0f, "123456A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 7 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, + /* 3*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "123456A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 7 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, /* EAN-8 */ + /* 4*/ { BARCODE_EAN8_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 7 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /* 5*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 7 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /* 6*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, -1, 0.0f, "1234567", "[20]1A", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, + /* 7*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "1234567", "[20]1A", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, + /* 8*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "1234567", "[20]1A", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, + /* 9*/ { BARCODE_EAN8_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567", "[20]1A", 0, 8, 72, "", 1, 0, 0 }, + /* 10*/ { BARCODE_EAN8_CC, GS1NOCHECK_MODE, -1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "1234567", "[20]1A", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 247: Height not compliant with standards (too small)", 1, 0, 0 }, + /* 11*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567", "[20]1A", 0, 8, 72, "", 1, 0, 0 }, + /* 12*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, -1, 0.0f, "1234567", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /* 13*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "1234567", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 8, 72, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /* 14*/ { BARCODE_EAN8_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567", "[02]12345678901234", 0, 8, 72, "", 1, 0, 0 }, + /* 15*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567", "[02]12345678901234", 0, 8, 72, "", 1, 0, 0 }, + /* 16*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, -1, 0.0f, "12345670", "[20]12", 0, 8, 72, "", 1, 0, 0 }, + /* 17*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "12345670", "[20]12", 0, 7, 99, "", 1, 0, 0 }, + /* 18*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "12345670", "[20]12", 0, 7, 99, "", 1, 0, 0 }, /* EAN-13 for EANX_CC as length 8 only EAN-8 for EANX_CHK */ + /* 19*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012", "[20]12", 0, 7, 99, "", 1, 0, 0 }, + /* 20*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012", "[20]12", 0, 7, 99, "", 1, 0, 0 }, /* EAN-13 */ + /* 21*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[20]12", 0, 7, 99, "", 1, 0, 0 }, + /* 22*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[20]12", 0, 7, 99, "", 1, 0, 0 }, /* EAN-13 */ + /* 23*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 275: Invalid check digit '3', expecting '8' (linear component)", 1, 0, 0 }, + /* 24*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 275: Invalid check digit '3', expecting '8' (linear component)", 1, 0, 0 }, + /* 25*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 275: Invalid check digit '3', expecting '8' (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /* 26*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 275: Invalid check digit '3', expecting '8' (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /* 27*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901234", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 294: Input length 14 too long (maximum 13) (linear component)", -1, 0, 0 }, + /* 28*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901234", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 294: Input length 14 too long (maximum 13) (linear component)", -1, 0, 0 }, + /* 29*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901234", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 294: Input length 14 too long (maximum 13) (linear component)", -1, 0, 0 }, + /* 30*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901234", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 294: Input length 14 too long (maximum 13) (linear component)", -1, 0, 0 }, + /* 31*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 13 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, + /* 32*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 13 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, + /* 33*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456789012A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 13 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, + /* 34*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456789012A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 13 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, + /* 35*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[20]1A", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ + /* 36*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[20]1A", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ + /* 37*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890128", "[20]1A", 0, 7, 99, "", 1, 0, 0 }, + /* 38*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890128", "[20]1A", 0, 7, 99, "", 1, 0, 0 }, + /* 39*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /* 40*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /* 41*/ { BARCODE_EAN13_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890128", "[02]12345678901234", 0, 7, 99, "", 1, 0, 0 }, + /* 42*/ { BARCODE_EANX_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890128", "[02]12345678901234", 0, 7, 99, "", 1, 0, 0 }, + /* 43*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567", 0, 48, 99, "", 2, 0, 0 }, /* Max CC-B for EAN-13 */ + /* 44*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567", 0, 48, 99, "", 2, 0, 0 }, /* Max CC-B for EAN-13 */ + /* 45*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]1234567890123456789012345678901234567890123456789012345678", ZINT_ERROR_TOO_LONG, -1, -1, "Error 444: Input too long (2D component)", -1, 0, 0 }, + /* 46*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890128", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]1234567890123456789012345678901234567890123456789012345678", ZINT_ERROR_TOO_LONG, -1, -1, "Error 444: Input too long (2D component)", -1, 0, 0 }, + /* 47*/ { BARCODE_EAN13_CC, -1, 3, -1, -1, -1, 0.0f, "1234567890128", "[20]12", ZINT_ERROR_INVALID_OPTION, -1, -1, "Error 447: Invalid mode (CC-C only valid with GS1-128 linear component)", 3, 0, 0 }, + /* 48*/ { BARCODE_EANX_CC, -1, 3, -1, -1, -1, 0.0f, "1234567890128", "[20]12", ZINT_ERROR_INVALID_OPTION, -1, -1, "Error 447: Invalid mode (CC-C only valid with GS1-128 linear component)", 3, 0, 0 }, + /* 49*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012345678901", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 449: Input length 21 wrong (linear component)", -1, 0, 0 }, + /* 50*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012345678901", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 449: Input length 21 wrong (linear component)", -1, 0, 0 }, + /* 51*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", 0, 5, 100, "", 1, 0, 0 }, + /* 52*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]12", 0, 5, 100, "", 1, 0, 0 }, + /* 53*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, + /* 54*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /* 55*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012312", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, + /* 56*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456789012312", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, + /* 57*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, + /* 58*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, + /* 59*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 5, 100, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ + /* 60*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]1A", 0, 5, 100, "", 1, 0, 0 }, + /* 61*/ { BARCODE_DBAR_OMN_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 5, 100, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /* 62*/ { BARCODE_DBAR_OMN_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901231", "[02]12345678901234", 0, 5, 100, "", 1, 0, 0 }, + /* 63*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", 0, 6, 79, "", 1, 0, 0 }, + /* 64*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]12", 0, 6, 79, "", 1, 0, 0 }, + /* 65*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 389: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, + /* 66*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 389: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /* 67*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012345", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, + /* 68*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456789012345", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, + /* 69*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, -1, 0.0f, "A1234567890123", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 383: Invalid character at position 1 in input (digits only) (linear component)", 1, 0, 0 }, + /* 70*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "A1234567890123", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 383: Invalid character at position 1 in input (digits only) (linear component)", 1, 0, 0 }, + /* 71*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 6, 79, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ + /* 72*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]1A", 0, 6, 79, "", 1, 0, 0 }, + /* 73*/ { BARCODE_DBAR_LTD_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 6, 79, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /* 74*/ { BARCODE_DBAR_LTD_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901231", "[02]12345678901234", 0, 6, 79, "", 1, 0, 0 }, + /* 75*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901", "[20]12", 0, 7, 99, "", 1, 0, 0 }, + /* 76*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012", "[20]12", 0, 7, 99, "", 1, 0, 0 }, + /* 77*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, 0.0f, "123456789013", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 270: Invalid check digit '3', expecting '2' (linear component)", 1, 0, 0 }, + /* 78*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456789013", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 270: Invalid check digit '3', expecting '2' (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /* 79*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 289: Input length 13 too long (maximum 12) (linear component)", 1, 0, 0 }, + /* 80*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 289: Input length 13 too long (maximum 12) (linear component)", 1, 0, 0 }, + /* 81*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 12 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, + /* 82*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 12 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, + /* 83*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012", "[20]1A", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ + /* 84*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456789012", "[20]1A", 0, 7, 99, "", 1, 0, 0 }, + /* 85*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 7, 99, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /* 86*/ { BARCODE_UPCA_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456789012", "[02]12345678901234", 0, 7, 99, "", 1, 0, 0 }, + /* 87*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0.0f, "123456", "[20]12", 0, 9, 55, "", 1, 0, 0 }, + /* 88*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0.0f, "1234567", "[20]12", 0, 9, 55, "", 1, 0, 0 }, + /* 89*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0.0f, "12345670", "[20]12", 0, 9, 55, "", 1, 0, 0 }, /* Check digit can now be given for UPCE_CC, like UPCA_CC */ + /* 90*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0.0f, "12345671", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 274: Invalid check digit '1', expecting '0' (linear component)", 1, 0, 0 }, + /* 91*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345671", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 274: Invalid check digit '1', expecting '0' (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /* 92*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0.0f, "123456712", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 291: Input length 9 too long (maximum 8) (linear component)", 1, 0, 0 }, + /* 93*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456712", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 291: Input length 9 too long (maximum 8) (linear component)", 1, 0, 0 }, + /* 94*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0.0f, "1234567A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 8 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, + /* 95*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 284: Invalid character at position 8 in input (digits and \"+\" or space only) (linear component)", 1, 0, 0 }, + /* 96*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0.0f, "1234567", "[20]1A", ZINT_WARN_NONCOMPLIANT, 9, 55, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ + /* 97*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567", "[20]1A", 0, 9, 55, "", 1, 0, 0 }, + /* 98*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0.0f, "1234567", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 9, 55, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /* 99*/ { BARCODE_UPCE_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567", "[02]12345678901234", 0, 9, 55, "", 1, 0, 0 }, + /*100*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", 0, 9, 56, "", 1, 0, 0 }, + /*101*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]12", 0, 9, 56, "", 1, 0, 0 }, + /*102*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, + /*103*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /*104*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012323", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, + /*105*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456789012323", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, + /*106*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, + /*107*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, + /*108*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 9, 56, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ + /*109*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]1A", 0, 9, 56, "", 1, 0, 0 }, + /*110*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 9, 56, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ + /*111*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 9, 56, "Warning 379: Height not compliant with standards", 1, 0, 0 }, + /*112*/ { BARCODE_DBAR_STK_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 9, 56, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /*113*/ { BARCODE_DBAR_STK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901231", "[02]12345678901234", 0, 9, 56, "", 1, 0, 0 }, + /*114*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123", "[20]12", 0, 11, 56, "", 1, 0, 0 }, + /*115*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]12", 0, 11, 56, "", 1, 0, 0 }, + /*116*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, + /*117*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901232", "[20]12", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '2', expecting '1' (linear component)", 1, 0, 0 }, /* Linear component still checked */ + /*118*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, -1, 0.0f, "123456789012312", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, + /*119*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "123456789012312", "[20]12", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14) (linear component)", 1, 0, 0 }, + /*120*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, -1, 0.0f, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, + /*121*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "1234567890123A", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 14 in input (digits only) (linear component)", 1, 0, 0 }, + /*122*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, 11, 56, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, /* AI (20) should be 2 nos. */ + /*123*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901231", "[20]1A", 0, 11, 56, "", 1, 0, 0 }, + /*124*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, -1, -1, -1, 0.0f, "12345678901231", "[02]12345678901234", ZINT_WARN_NONCOMPLIANT, 11, 56, "Warning 261: AI (02) data position 14: Bad checksum '4', expected '1' (2D component)", 1, 0, 0 }, + /*125*/ { BARCODE_DBAR_OMNSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "12345678901231", "[02]12345678901234", 0, 11, 56, "", 1, 0, 0 }, + /*126*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, 0.0f, "", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 445: No primary (linear component)", -1, 0, 0 }, + /*127*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, 0.0f, "[01]12345678901231", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[95]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[96]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[97]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[98]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[99]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, 31, 273, "", 3, 0, 0 }, /* Tries CC-A then CC-B then CC-C - ensure errtxt empty */ + /*128*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, 0.0f, "[01]12345678901231[90]123456789012345678901234567890[91]1234567890123456789012345678901234567890123456789012345678901234", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[95]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[96]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[97]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[98]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[99]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[95]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[96]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[97]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[98]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[99]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]123456789012345678901234567890123456789012345678901234567890123", ZINT_WARN_NONCOMPLIANT, 29, 702, "Warning 843: Input too long, requires 115 characters (maximum 48) (linear component)", 3, 0, 0 }, /* Overlarge linear and CC-C input */ + /*129*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, 0.0f, "[01]12345678901231[90]123456789012345678901234567890[91]1234567890123456789012345678901234567890123456789012345678901234", "[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[94]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[95]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[96]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[97]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[98]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[99]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[94]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[95]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[96]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL", ZINT_ERROR_TOO_LONG, -1, -1, "Error 442: Input too long (2D component)", -1, 0, 0 }, /* Overlarge linear and oversized CC-C input */ + /*130*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, 0.0f, "[01]12345678901231", "[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[94]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[95]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[96]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[97]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[98]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[99]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[94]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[95]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[96]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[91]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[92]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHI" "JKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL[93]ABCDEFGHIJKLM", ZINT_ERROR_TOO_LONG, -1, -1, "Error 446: 2D component input too long, requires 2991 characters (maximum 2990)", -1, 0, 0 }, /* Reduced length 2291 */ + /*131*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, 0.0f, "[01]12345678901231", "[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012" "345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[00]123456789012345675[11]121212[20]12", 0, 32, 579, "", 3, 0, 0 }, /* Reduced length 2372 digits (no FNC1s) with not recommended ECC 4 > 2361 digit limit given in ISO/IEC 24723:2010 4.1 (d)(2)(iii) */ + /*132*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, 0.0f, "[90]ABCDEFGHIJKLMNOPQRSTUVWXYXABCD[91]ABCDEFGHIJKLMNOPQRSTUVWXYABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLM", "[20]12", ZINT_WARN_NONCOMPLIANT, 5, 1146, "Warning 843: Input too long, requires 99 characters (maximum 48) (linear component)", 1, 0, 0 }, + /*133*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, 0.0f, "[90]ABCDEFGHIJKLMNOPQRSTUVWXYXABCD[91]ABCDEFGHIJKLMNOPQRSTUVWXYABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMN", "[20]12", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 344: Input too long, requires 103 symbol characters (maximum 102) (linear component)", -1, 0, 0 }, + /*134*/ { BARCODE_DBAR_EXP_CC, -1, -1, -1, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]12", 0, 5, 298, "", 1, 0, 0 }, + /*135*/ { BARCODE_DBAR_EXP_CC, -1, -1, -1, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]1A", ZINT_WARN_NONCOMPLIANT, 5, 298, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, + /*136*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]1A", 0, 5, 298, "", 1, 0, 0 }, + /*137*/ { BARCODE_DBAR_EXP_CC, -1, -1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "[91]1234567890123456789012345678901234", "[20]1A", ZINT_WARN_NONCOMPLIANT, 5, 298, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)", 1, 0, 0 }, + /*138*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "[91]1234567890123456789012345678901234", "[20]1A", ZINT_WARN_NONCOMPLIANT, 5, 298, "Warning 247: Height not compliant with standards (too small)", 1, 0, 0 }, + /*139*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 0, 0 }, + /*140*/ { BARCODE_DBAR_EXPSTK_CC, -1, 1, -1, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[91]123456789012345678901234567890123456789012345678901234", 0, 17, 102, "", 1, 0, 0 }, + /*141*/ { BARCODE_DBAR_EXPSTK_CC, -1, 1, -1, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[91]1234567890123456789012345678901234567890123456789012345", ZINT_WARN_INVALID_OPTION, 20, 102, "Warning 443: Composite type changed from CC-A to CC-B", 2, 0, 0 }, + /*142*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, -1, -1, 0.0f, "[01]12345678901234", "[20]12", ZINT_WARN_NONCOMPLIANT, 9, 102, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1' (linear component)", 1, 0, 0 }, + /*143*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, -1, 0.0f, "[01]12345678901231", "[20]12", 0, 9, 102, "", 1, 0, 0 }, + /*144*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "[01]12345678901234", "[20]12", ZINT_WARN_NONCOMPLIANT, 9, 102, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1' (linear component)", 1, 0, 0 }, + /*145*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "[01]12345678901234", "[20]12", ZINT_WARN_NONCOMPLIANT, 9, 102, "Warning 247: Height not compliant with standards (too small)", 1, 0, 0 }, + /*146*/ { BARCODE_GS1_128_CC, -1, 1, -1, -1, -1, 0.0f, "[01]12345678901231", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]1234567890123456789012345678901234567890123456789012345678", ZINT_WARN_INVALID_OPTION, 31, 154, "Warning 443: Composite type changed from CC-A to CC-C", 3, 0, 0 }, + /*147*/ { BARCODE_GS1_128_CC, -1, 2, -1, -1, -1, 0.0f, "[01]12345678901231", "[91]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[93]123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[94]1234567890123456789012345678901234567890123456789012345678", ZINT_WARN_INVALID_OPTION, 31, 154, "Warning 443: Composite type changed from CC-B to CC-C", 3, 0, 0 }, + /*148*/ { BARCODE_GS1_128_CC, -1, 1, -1, -1, -1, 0.0f, "[90]ABCDEFGHIJKLMNOPQRSTUVWXYXABCD[91]ABCDEFGHIJKLM", "[91]1234567890123456789012345678901234567890123456789012345", ZINT_WARN_INVALID_OPTION, 12, 585, "Warning 443: Composite type changed from CC-A to CC-B", 2, 0, 0 }, + /*149*/ { BARCODE_GS1_128_CC, -1, 1, -1, -1, -1, 0.0f, "[90]ABCDEFGHIJKLMNOPQRSTUVWXYXABCD[91]ABCDEFGHIJKLMN", "[91]1234567890123456789012345678901234567890123456789012345", ZINT_WARN_NONCOMPLIANT, 12, 596, "Warning 843: Input too long, requires 49 characters (maximum 48) (linear component)", 2, 0, 0 }, /* Other warnings trump CC type change */ + /*150*/ { BARCODE_GS1_128_CC, -1, 1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "[90]ABCDEFGHIJKLMNOPQRSTUVWXYXABCD[91]ABCDEFGHIJKLM", "[91]1234567890123456789012345678901234567890123456789012345", ZINT_WARN_INVALID_OPTION, 12, 585, "Warning 443: Composite type changed from CC-A to CC-B", 2, 0, 0 }, + /*151*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 1, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 1, 0 }, + /*152*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 2, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 2, 0 }, + /*153*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 3, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]12", 0, 9, 151, "", 1, 3, 0 }, + /*154*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 4, -1, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]12", 0, 9, 200, "", 1, 4, 0 }, + /*155*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, 2, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]12", 0, 9, 151, "", 1, 0, 2 }, + /*156*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, 3, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 0, 3 }, + /*157*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, -1, 4, -1, 0.0f, "[91]1234567890123456789012345678901234", "[20]12", 0, 13, 102, "", 1, 0, 4 }, }; const int data_size = ARRAY_SIZE(data); int i, length, composite_length, ret; @@ -4260,10 +4276,13 @@ static void test_input(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data[i].option_1, data[i].option_2, data[i].option_3, data[i].output_options, data[i].data, -1, debug); assert_zero(length >= 128, "i:%d length %d >= 128\n", i, length); strcpy(symbol->primary, data[i].data); + if (data[i].height) { + symbol->height = data[i].height; + } composite_length = (int) strlen(data[i].composite); diff --git a/backend/tests/test_eci.c b/backend/tests/test_eci.c index b4f9c9a8..dd91dfc5 100644 --- a/backend/tests/test_eci.c +++ b/backend/tests/test_eci.c @@ -698,6 +698,7 @@ static void test_utf8_to_eci_sb(const testCtx *const p_ctx) { unsigned char source[5]; unsigned char dest[2] = {0}; + const unsigned char source0x012c[] = "\xC4\xAC"; /* 0x012c not in any single-byte tables */ testStart(p_ctx->func_name); @@ -738,6 +739,12 @@ static void test_utf8_to_eci_sb(const testCtx *const p_ctx) { } } } + j = 0x012c; + length = 2; + ret = zint_utf8_to_eci(data[i].eci, source0x012c, dest, &length); + assert_equal(ret, ZINT_ERROR_INVALID_DATA, + "i:%d eci:%d codepoint:0x%x source:%s zint_utf8_to_eci ret %d != ZINT_ERROR_INVALID_DATA\n", + i, data[i].eci, j, source0x012c, ret); } testFinish(); @@ -1397,6 +1404,7 @@ static void test_utf8_to_eci_binary(const testCtx *const p_ctx) { /* 3*/ { "\302\220\302\221\302\222\302\223\302\224\302\225\302\226\302\227\302\230\302\231\302\232\302\233\302\234\302\235\302\236\302\237", 32, 0, 16 }, /* 4*/ { "\303\200\303\201\303\202\303\203\303\204\303\205\303\206\303\207\303\210\303\211\303\212\303\213\303\214\303\215\303\216\303\217", 32, 0, 16 }, /* 5*/ { "\303\220\303\221\303\222\303\223\303\224\303\225\303\226\303\227\303\230\303\231\303\232\303\233\303\234\303\235\303\236\303\237", 32, 0, 16 }, + /* 6*/ { "\304\242", 2, ZINT_ERROR_INVALID_DATA, -1 }, }; int data_size = ARRAY_SIZE(data); int i, length, ret; diff --git a/backend/tests/test_emf.c b/backend/tests/test_emf.c index a7eb0964..19b690be 100644 --- a/backend/tests/test_emf.c +++ b/backend/tests/test_emf.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020-2025 Robin Stuart + Copyright (C) 2020-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -167,7 +167,7 @@ static void test_print(const testCtx *const p_ctx) { strcpy(symbol->bgcolour, data[i].bgcolour); } - ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); @@ -284,11 +284,70 @@ static void test_outfile(const testCtx *const p_ctx) { testFinish(); } +#include "filemem.h" + +static void test_fm(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + const char *data; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_ACCESS, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_OPEN }, + /* 1*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 5, 11, 0, 0, 0 }, 2, FM_FAIL_ID_WRITE }, + /* 2*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, "out.emf"); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_fm_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ { "test_print", test_print }, { "test_outfile", test_outfile }, + { "test_fm", test_fm }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_filemem.c b/backend/tests/test_filemem.c index 31fa5702..9d0853e7 100644 --- a/backend/tests/test_filemem.c +++ b/backend/tests/test_filemem.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2023-2025 Robin Stuart + Copyright (C) 2023-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -204,7 +204,8 @@ static void test_putsf(const testCtx *const p_ctx) { zint_fm_putsf(data[i].prefix, data[i].dp, data[i].arg, fmp); - assert_nonzero(zint_fm_close(fmp, symbol), "i:%d: zint_fm_close fail (%d, %s)\n", i, fmp->err, strerror(fmp->err)); + assert_nonzero(zint_fm_close(fmp, symbol), "i:%d: zint_fm_close fail (%d, %s)\n", + i, fmp->err, strerror(fmp->err)); if (locale) { assert_nonnull(setlocale(LC_ALL, locale), "i:%d: setlocale(%s) restore fail (%d, %s)\n", @@ -274,6 +275,9 @@ static void test_printf(const testCtx *const p_ctx) { ret = zint_fm_printf(fmp, fmt1, "gosh", 123, "gee"); assert_equal(ret, 1, "zint_fm_printf ret %d != 1\n", ret); + ret = zint_fm_flush(fmp); + assert_equal(ret, 1, "zint_fm_flush ret %d != 1\n", ret); + ret = zint_fm_close(fmp, symbol); assert_equal(ret, 1, "zint_fm_close ret %d != 1\n", ret); @@ -340,6 +344,92 @@ static void test_printf(const testCtx *const p_ctx) { testFinish(); } +static void test_write(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + const char *data; + size_t size; + size_t nitems; + const char *expected; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + struct item data[] = { + /* 0*/ { "123", 3, 1, "123" }, + /* 1*/ { "123", 3, 0, "" }, + /* 2*/ { "", 0, 1, "" }, + }; + int data_size = ARRAY_SIZE(data); + int i, j; + + struct zint_symbol symbol_data = {0}; + struct zint_symbol *const symbol = &symbol_data; + struct filemem fm = {0}; /* Suppress clang -fsanitize=memory false positive */ + struct filemem *const fmp = &fm; +#ifndef ZINT_TEST_NO_FMEMOPEN + FILE *fp; + char buf[512] = {0}; /* Suppress clang-16/17 run-time exception MemorySanitizer: use-of-uninitialized-value */ +#endif + + (void)debug; + + testStart(p_ctx->func_name); + + for (j = 0; j < 2; j++) { /* 1st `memfile`, then file */ +#ifdef ZINT_TEST_NO_FMEMOPEN + if (j == 1) break; /* Skip file test on Windows/Solaris */ +#endif + for (i = 0; i < data_size; i++) { + int expected_size; + + if (testContinue(p_ctx, i)) continue; + + ZBarcode_Reset(symbol); + if (j == 1) { +#ifndef ZINT_TEST_NO_FMEMOPEN + buf[0] = '\0'; + fp = fmemopen(buf, sizeof(buf), "w"); + assert_nonnull(fp, "%d: fmemopen fail (%d, %s)\n", i, errno, strerror(errno)); +#endif + } else { + symbol->output_options |= BARCODE_MEMORY_FILE; + } + assert_nonzero(zint_fm_open(fmp, symbol, "w"), "i:%d: zint_fm_open fail (%d, %s)\n", + i, fmp->err, strerror(fmp->err)); + if (j == 1) { +#ifndef ZINT_TEST_NO_FMEMOPEN + /* Hack in `fmemopen()` fp */ + assert_zero(fclose(fmp->fp), "i:%d fclose(fmp->fp) fail (%d, %s)\n", i, errno, strerror(errno)); + fmp->fp = fp; +#endif + } + + zint_fm_write(data[i].data, data[i].size, data[i].nitems, fmp); + + assert_nonzero(zint_fm_close(fmp, symbol), "i:%d: zint_fm_close fail (%d, %s)\n", + i, fmp->err, strerror(fmp->err)); + + if (j == 1) { +#ifndef ZINT_TEST_NO_FMEMOPEN + assert_zero(strcmp(buf, data[i].expected), "%d: strcmp(%s, %s) != 0\n", i, buf, data[i].expected); +#endif + } else { + expected_size = (int) strlen(data[i].expected); + assert_equal(symbol->memfile_size, expected_size, "i:%d: memfile_size %d != expected_size %d\n", + i, symbol->memfile_size, expected_size); + assert_nonnull(symbol->memfile, "i:%d memfile NULL\n", i); + assert_zero(memcmp(symbol->memfile, data[i].expected, expected_size), + "i:%d: memcmp(%.*s, %.*s) != 0\n", + i, symbol->memfile_size, symbol->memfile, expected_size, data[i].expected); + } + + ZBarcode_Clear(symbol); + } + } + + testFinish(); +} + static void test_seek(const testCtx *const p_ctx) { int debug = p_ctx->debug; @@ -469,14 +559,83 @@ static void test_large(const testCtx *const p_ctx) { testFinish(); } +static void test_alloc(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int option_2; + int output_options; + const char *outfile; + const char *fgcolour; + float scale; + const char *data; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_CODE128, -1, BARCODE_MEMORY_FILE, "out.pcx", "FEDCBA98", 0.0f, "12345", ZINT_ERROR_FILE_ACCESS, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_MALLOC }, + /* 1*/ { BARCODE_CODE128, -1, BARCODE_MEMORY_FILE, "out.pcx", "FEDCBA98", 0.0f, "12345", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_REALLOC }, + /* 2*/ { BARCODE_QRCODE, 34, BARCODE_MEMORY_FILE, "out.gif", NULL, 2.5f, "12345", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_REALLOC }, + /* 3*/ { BARCODE_MAXICODE, -1, BARCODE_MEMORY_FILE, "out.svg", "FEDCBA98", 101.43f, "12345", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_REALLOC }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, data[i].outfile); + if (data[i].fgcolour) { + strcpy(symbol->fgcolour, data[i].fgcolour); + } + if (data[i].scale) { + symbol->scale = data[i].scale; + } + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_fm_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ { "test_file", test_file }, { "test_putsf", test_putsf }, { "test_printf", test_printf }, + { "test_write", test_write }, { "test_seek", test_seek }, { "test_large", test_large }, + { "test_alloc", test_alloc }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); @@ -487,4 +646,3 @@ int main(int argc, char *argv[]) { } /* vim: set ts=4 sw=4 et : */ - diff --git a/backend/tests/test_gif.c b/backend/tests/test_gif.c index cbcc19e2..f1afceea 100644 --- a/backend/tests/test_gif.c +++ b/backend/tests/test_gif.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020-2025 Robin Stuart + Copyright (C) 2020-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -183,7 +183,8 @@ static void test_print(const testCtx *const p_ctx) { /* 33*/ { BARCODE_CODE16K, -1, -1, 3, 5, -1, -1, 1.5, 0, 0, { 0, 0, "" }, "", "", "1234567890", "code16k_height1.5_wsp3_vwsp5.gif", "" }, /* 34*/ { BARCODE_DATAMATRIX, -1, -1, -1, -1, -1, -1, 0, 0, 0, { 2, 9, "001002" }, "", "", "1234567890", "datamatrix_seq2of9.gif", "" }, /* 35*/ { BARCODE_ULTRA, -1, -1, 1, -1, -1, 2, 0, 0, 0, { 0, 0, "" }, "", "", "12", "ultra_rev2.gif", "Revision 2" }, - /* 36*/ { BARCODE_DPD, -1, BARCODE_QUIET_ZONES | COMPLIANT_HEIGHT, -1, -1, -1, -1, 0, 0, 0, { 0, 0, "" }, "", "", "008182709980000020028101276", "dpd_compliant.gif", "Now with bind top 3X default" }, + /* 36*/ { BARCODE_ULTRA, 1, BARCODE_BOX | BARCODE_QUIET_ZONES | BARCODE_NO_QUIET_ZONES, -1, -1, -1, -1, 0, 0, 0, { 0, 0, "" }, "", "", "12", "ultra_box.gif", "NO_QUIET_ZONES trumps QUIET_ZONES" }, + /* 37*/ { BARCODE_DPD, -1, BARCODE_QUIET_ZONES | COMPLIANT_HEIGHT, -1, -1, -1, -1, 0, 0, 0, { 0, 0, "" }, "", "", "008182709980000020028101276", "dpd_compliant.gif", "Now with bind top 3X default" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -417,6 +418,67 @@ static void test_too_big(const testCtx *const p_ctx) { testFinish(); } +#include "filemem.h" + +static void test_fm(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + const char *data; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_ACCESS, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_OPEN }, + /* 1*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 3, 5, 0, 0 }, 3, FM_FAIL_ID_WRITE }, + /* 2*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_PUTC }, + /* 3*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + (void)p_ctx; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, "out.gif"); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_fm_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -425,6 +487,7 @@ int main(int argc, char *argv[]) { { "test_outfile", test_outfile }, { "test_large_scale", test_large_scale }, { "test_too_big", test_too_big }, + { "test_fm", test_fm }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_gridmtx.c b/backend/tests/test_gridmtx.c index fb1adbbc..38fa35f4 100644 --- a/backend/tests/test_gridmtx.c +++ b/backend/tests/test_gridmtx.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2019-2025 Robin Stuart + Copyright (C) 2019-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -35,6 +35,7 @@ static void test_large(const testCtx *const p_ctx) { int debug = p_ctx->debug; struct item { + int option_1; int option_2; int option_3; const char *pattern; @@ -46,48 +47,49 @@ static void test_large(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { -1, -1, "1", 2751, 0, 162, 162, "" }, - /* 1*/ { -1, -1, "1", 2752, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, - /* 2*/ { -1, -1, "1", 2755, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, /* Triggers buffer > 9191 */ - /* 3*/ { -1, -1, "A", 1836, 0, 162, 162, "" }, - /* 4*/ { -1, -1, "A", 1837, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, - /* 5*/ { -1, -1, "A1", 1529, 0, 162, 162, "" }, - /* 6*/ { -1, -1, "A1", 1530, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, - /* 7*/ { -1, -1, "\200", 1143, 0, 162, 162, "" }, - /* 8*/ { -1, -1, "\200", 1144, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, - /* 9*/ { -1, ZINT_FULL_MULTIBYTE, "\241", 1410, 0, 162, 162, "" }, - /* 10*/ { -1, ZINT_FULL_MULTIBYTE, "\241", 1412, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, - /* 11*/ { 1, -1, "1", 18, 0, 18, 18, "" }, - /* 12*/ { 1, -1, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 1, requires 13 codewords (maximum 11)" }, - /* 13*/ { 1, -1, "A", 13, 0, 18, 18, "" }, - /* 14*/ { 1, -1, "A", 14, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 1, requires 12 codewords (maximum 11)" }, - /* 15*/ { 1, -1, "\200", 7, 0, 18, 18, "" }, - /* 16*/ { 1, -1, "\200", 8, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 1, requires 12 codewords (maximum 11)" }, - /* 17*/ { 1, ZINT_FULL_MULTIBYTE, "\241", 8, 0, 18, 18, "" }, - /* 18*/ { 1, ZINT_FULL_MULTIBYTE, "\241", 10, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 1, requires 12 codewords (maximum 11)" }, - /* 19*/ { 2, ZINT_FULL_MULTIBYTE, "\241", 40, 0, 30, 30, "" }, - /* 20*/ { 2, ZINT_FULL_MULTIBYTE, "\241", 41, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 2, requires 42 codewords (maximum 40)" }, - /* 21*/ { 3, -1, "A", 108, 0, 42, 42, "" }, - /* 22*/ { 3, -1, "A", 109, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 3, requires 80 codewords (maximum 79)" }, - /* 23*/ { 4, -1, "A", 202, 0, 54, 54, "" }, - /* 24*/ { 4, -1, "A", 203, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 4, requires 147 codewords (maximum 146)" }, - /* 25*/ { 5, -1, "1", 453, 0, 66, 66, "" }, - /* 26*/ { 5, -1, "1", 454, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 5, requires 220 codewords (maximum 218)" }, - /* 27*/ { 6, -1, "1", 633, 0, 78, 78, "" }, - /* 28*/ { 6, -1, "1", 634, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 6, requires 306 codewords (maximum 305)" }, - /* 29*/ { 7, -1, "\200", 352, 0, 90, 90, "" }, - /* 30*/ { 7, -1, "\200", 353, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 7, requires 406 codewords (maximum 405)" }, - /* 31*/ { 8, -1, "A", 727, 0, 102, 102, "" }, - /* 32*/ { 8, -1, "A", 728, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 8, requires 522 codewords (maximum 521)" }, - /* 33*/ { 9, -1, "A", 908, 0, 114, 114, "" }, - /* 34*/ { 9, -1, "A", 909, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 9, requires 651 codewords (maximum 650)" }, - /* 35*/ { 10, -1, "1", 1662, 0, 126, 126, "" }, - /* 36*/ { 10, -1, "1", 1663, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 10, requires 796 codewords (maximum 794)" }, - /* 37*/ { 11, -1, "1", 1995, 0, 138, 138, "" }, - /* 38*/ { 11, -1, "1", 1996, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 11, requires 954 codewords (maximum 953)" }, - /* 39*/ { 11, -1, "1", 2748, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 11, requires 1311 codewords (maximum 953)" }, - /* 40*/ { 12, -1, "1", 2355, 0, 150, 150, "" }, - /* 41*/ { 12, -1, "1", 2356, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 12, requires 1126 codewords (maximum 1125)" }, + /* 0*/ { -1, -1, -1, "1", 2751, 0, 162, 162, "" }, + /* 1*/ { -1, -1, -1, "1", 2752, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, + /* 2*/ { -1, -1, -1, "1", 2755, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, /* Triggers buffer > 9191 */ + /* 3*/ { -1, -1, -1, "A", 1836, 0, 162, 162, "" }, + /* 4*/ { -1, -1, -1, "A", 1837, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, + /* 5*/ { -1, -1, -1, "A1", 1529, 0, 162, 162, "" }, + /* 6*/ { -1, -1, -1, "A1", 1530, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, + /* 7*/ { -1, -1, -1, "\200", 1143, 0, 162, 162, "" }, + /* 8*/ { -1, -1, -1, "\200", 1144, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, + /* 9*/ { -1, -1, ZINT_FULL_MULTIBYTE, "\241", 1410, 0, 162, 162, "" }, + /* 10*/ { -1, -1, ZINT_FULL_MULTIBYTE, "\241", 1412, ZINT_ERROR_TOO_LONG, -1, -1, "Error 531: Input too long, requires too many codewords (maximum 1313)" }, + /* 11*/ { -1, 1, -1, "1", 18, 0, 18, 18, "" }, + /* 12*/ { -1, 1, -1, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 1, requires 13 codewords (maximum 11)" }, + /* 13*/ { -1, 1, -1, "A", 13, 0, 18, 18, "" }, + /* 14*/ { -1, 1, -1, "A", 14, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 1, requires 12 codewords (maximum 11)" }, + /* 15*/ { -1, 1, -1, "\200", 7, 0, 18, 18, "" }, + /* 16*/ { -1, 1, -1, "\200", 8, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 1, requires 12 codewords (maximum 11)" }, + /* 17*/ { -1, 1, ZINT_FULL_MULTIBYTE, "\241", 8, 0, 18, 18, "" }, + /* 18*/ { -1, 1, ZINT_FULL_MULTIBYTE, "\241", 10, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 1, requires 12 codewords (maximum 11)" }, + /* 19*/ { -1, 2, ZINT_FULL_MULTIBYTE, "\241", 40, 0, 30, 30, "" }, + /* 20*/ { -1, 2, ZINT_FULL_MULTIBYTE, "\241", 41, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 2, requires 42 codewords (maximum 40)" }, + /* 21*/ { -1, 3, -1, "A", 108, 0, 42, 42, "" }, + /* 22*/ { -1, 3, -1, "A", 109, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 3, requires 80 codewords (maximum 79)" }, + /* 23*/ { -1, 4, -1, "A", 202, 0, 54, 54, "" }, + /* 24*/ { -1, 4, -1, "A", 203, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 4, requires 147 codewords (maximum 146)" }, + /* 25*/ { -1, 5, -1, "1", 453, 0, 66, 66, "" }, + /* 26*/ { -1, 5, -1, "1", 454, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 5, requires 220 codewords (maximum 218)" }, + /* 27*/ { -1, 6, -1, "1", 633, 0, 78, 78, "" }, + /* 28*/ { -1, 6, -1, "1", 634, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 6, requires 306 codewords (maximum 305)" }, + /* 29*/ { -1, 7, -1, "\200", 352, 0, 90, 90, "" }, + /* 30*/ { -1, 7, -1, "\200", 353, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 7, requires 406 codewords (maximum 405)" }, + /* 31*/ { -1, 8, -1, "A", 727, 0, 102, 102, "" }, + /* 32*/ { -1, 8, -1, "A", 728, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 8, requires 522 codewords (maximum 521)" }, + /* 33*/ { -1, 9, -1, "A", 908, 0, 114, 114, "" }, + /* 34*/ { -1, 9, -1, "A", 909, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 9, requires 651 codewords (maximum 650)" }, + /* 35*/ { -1, 10, -1, "1", 1662, 0, 126, 126, "" }, + /* 36*/ { -1, 10, -1, "1", 1663, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 10, requires 796 codewords (maximum 794)" }, + /* 37*/ { -1, 11, -1, "1", 1995, 0, 138, 138, "" }, + /* 38*/ { -1, 11, -1, "1", 1996, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 11, requires 954 codewords (maximum 953)" }, + /* 39*/ { -1, 11, -1, "1", 2748, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 11, requires 1311 codewords (maximum 953)" }, + /* 40*/ { -1, 12, -1, "1", 2355, 0, 150, 150, "" }, + /* 41*/ { -1, 12, -1, "1", 2356, ZINT_ERROR_TOO_LONG, -1, -1, "Error 534: Input too long for Version 12, requires 1126 codewords (maximum 1125)" }, + /* 42*/ { 2, 12, -1, "1", 2355, 0, 150, 150, "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -105,18 +107,26 @@ static void test_large(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", + i, data[i].length, (int) strlen(data_buf)); - length = testUtilSetSymbol(symbol, BARCODE_GRIDMATRIX, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, data[i].option_3, -1 /*output_options*/, data_buf, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_GRIDMATRIX, -1 /*input_mode*/, -1 /*eci*/, + data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } ZBarcode_Delete(symbol); diff --git a/backend/tests/test_gs1.c b/backend/tests/test_gs1.c index b06e8883..54507439 100644 --- a/backend/tests/test_gs1.c +++ b/backend/tests/test_gs1.c @@ -2910,6 +2910,8 @@ static void test_gs1nocheck_mode(const testCtx *const p_ctx) { struct item { int symbology; int input_mode; + int output_options; + float height; const char *data; const char *composite; int ret; @@ -2917,261 +2919,263 @@ static void test_gs1nocheck_mode(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { BARCODE_GS1_128, -1, "[01]12345678901231", "", 0, "" }, - /* 1*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]12345678901231", "", 0, "" }, - /* 2*/ { BARCODE_GS1_128, -1, "[01]12345678901234", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'" }, - /* 3*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]12345678901234", "", 0, "" }, - /* 4*/ { BARCODE_GS1_128, -1, "^0112345678901234", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'" }, - /* 5*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^0112345678901234", "", 0, "" }, - /* 6*/ { BARCODE_GS1_128, GS1RAW_MODE, "0112345678901234", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'" }, - /* 7*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "0112345678901234", "", 0, "" }, - /* 8*/ { BARCODE_GS1_128, -1, "[01]123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1" }, - /* 9*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]123456789012345", "", 0, "" }, - /* 10*/ { BARCODE_GS1_128, -1, "^01123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 859: Invalid data length for AI (01) at position 2" }, - /* 11*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^01123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 859: Invalid data length for AI (01) at position 2" }, /* Raw/caret need underlong data lengths to work - also new so no need for backward-compatibility */ - /* 12*/ { BARCODE_GS1_128, GS1RAW_MODE, "01123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 859: Invalid data length for AI (01) at position 1" }, - /* 13*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "01123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 859: Invalid data length for AI (01) at position 1" }, - /* 14*/ { BARCODE_GS1_128, -1, "[01]1234567890123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1" }, - /* 15*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]1234567890123", "", 0, "" }, - /* 16*/ { BARCODE_GS1_128, -1, "^011234567890123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 2" }, - /* 17*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^011234567890123", "", 0, "" }, /* Raw/caret too short data lengths ok */ - /* 18*/ { BARCODE_GS1_128, GS1RAW_MODE, "011234567890123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1" }, - /* 19*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "011234567890123", "", 0, "" }, - /* 20*/ { BARCODE_GS1_128, -1, "^011234567890123^", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 2" }, - /* 21*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^011234567890123^", "", 0, "" }, - /* 22*/ { BARCODE_GS1_128, GS1RAW_MODE, "011234567890123\035", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1" }, - /* 23*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "011234567890123\035", "", 0, "" }, - /* 24*/ { BARCODE_GS1_128, -1, "[01]12345678901231[20]1", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 19" }, - /* 25*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]12345678901231[20]1", "", 0, "" }, - /* 26*/ { BARCODE_GS1_128, -1, "^0112345678901231201", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 18" }, - /* 27*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^0112345678901231201", "", 0, "" }, - /* 28*/ { BARCODE_GS1_128, GS1RAW_MODE, "0112345678901231201", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 17" }, - /* 29*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "0112345678901231201", "", 0, "" }, - /* 30*/ { BARCODE_GS1_128, -1, "^0112345678901231201^", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 18" }, - /* 31*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^0112345678901231201^", "", 0, "" }, - /* 32*/ { BARCODE_GS1_128, GS1RAW_MODE, "0112345678901231201\035", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 17" }, - /* 33*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "0112345678901231201\035", "", 0, "" }, - /* 34*/ { BARCODE_GS1_128, -1, "^0112345678901231^201", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 19" }, - /* 35*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^0112345678901231^201", "", 0, "" }, - /* 36*/ { BARCODE_GS1_128, GS1RAW_MODE, "0112345678901231\035201", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 18" }, - /* 37*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "0112345678901231\035201", "", 0, "" }, - /* 38*/ { BARCODE_GS1_128, -1, "[03]123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (03) at position 1" }, - /* 39*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[03]123", "", 0, "" }, - /* 40*/ { BARCODE_GS1_128, -1, "^03123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (03) at position 2" }, - /* 41*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^03123", "", 0, "" }, - /* 42*/ { BARCODE_GS1_128, GS1RAW_MODE, "03123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (03) at position 1" }, - /* 43*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "03123", "", 0, "" }, - /* 44*/ { BARCODE_GS1_128, -1, "[04]1234[05]12345[06]123456", "", ZINT_ERROR_INVALID_DATA, "Error 260: Invalid AI (04) at position 1" }, - /* 45*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[04]1234[05]12345[06]123456", "", 0, "" }, - /* 46*/ { BARCODE_GS1_128, -1, "^041234^0512345^06123456", "", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (04) at position 2" }, - /* 47*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^041234^0512345^06123456", "", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (04) at position 2" }, /* Raw/caret mode needs valid AIs to work */ - /* 48*/ { BARCODE_GS1_128, GS1RAW_MODE, "041234\0350512345\03506123456", "", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (04) at position 1" }, - /* 49*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "041234\0350512345\03506123456", "", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (04) at position 1" }, - /* 50*/ { BARCODE_GS1_128, -1, "[01]1234567890123A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Non-numeric character 'A'" }, - /* 51*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]1234567890123A", "", 0, "" }, - /* 52*/ { BARCODE_GS1_128, -1, "^011234567890123A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Non-numeric character 'A'" }, - /* 53*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^011234567890123A", "", 0, "" }, - /* 54*/ { BARCODE_GS1_128, GS1RAW_MODE, "011234567890123A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Non-numeric character 'A'" }, - /* 55*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "011234567890123A", "", 0, "" }, - /* 56*/ { BARCODE_GS1_128, -1, "[01]1234567890123.", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Non-numeric character '.'" }, - /* 57*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]1234567890123.", "", 0, "" }, - /* 58*/ { BARCODE_GS1_128, -1, "[01]1234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, - /* 59*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]1234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, /* Nonprintable ASCII still checked */ - /* 60*/ { BARCODE_GS1_128, -1, "^011234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, - /* 61*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^011234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, - /* 62*/ { BARCODE_GS1_128, GS1RAW_MODE, "011234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, - /* 63*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "011234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, - /* 64*/ { BARCODE_GS1_128, -1, "[01]1234567890123\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, - /* 65*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]1234567890123\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, /* Extended ASCII still checked */ - /* 66*/ { BARCODE_GS1_128, -1, "0112345678901231", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, - /* 67*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "0112345678901231", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, /* Format still checked */ - /* 68*/ { BARCODE_GS1_128, -1, "[01]", "", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (01) at position 1" }, - /* 69*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]", "", 0, "" }, /* Zero-length data not checked */ - /* 70*/ { BARCODE_GS1_128, -1, "^01", "", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (01) at position 2" }, - /* 71*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^01", "", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (01) at position 2" }, /* Raw/caret mode needs valid data_lengths to work */ - /* 72*/ { BARCODE_GS1_128, GS1RAW_MODE, "01", "", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (01) at position 1" }, - /* 73*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, "01", "", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (01) at position 1" }, - /* 74*/ { BARCODE_GS1_128, -1, "[01][20]12", "", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (01) at position 1" }, - /* 75*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01][20]12", "", 0, "" }, /* Zero-length data not checked */ - /* 76*/ { BARCODE_GS1_128, -1, "[0]123", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /* 77*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[0]123", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 1 AI with no data still checked */ - /* 78*/ { BARCODE_GS1_128, -1, "[0]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /* 79*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[0]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 1 AI with no data still checked */ - /* 80*/ { BARCODE_GS1_128, -1, "^0", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 2" }, - /* 81*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^0", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 2" }, - /* 82*/ { BARCODE_GS1_128, -1, "[]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /* 83*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[]12", "", 0, "" }, /* Length 0 AI with data not checked */ - /* 84*/ { BARCODE_GS1_128, -1, "[]12[01]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /* 85*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[]12[01]", "", 0, "" }, /* Length 0 AI with data not checked, non-short AI with zero-length data not checked */ - /* 86*/ { BARCODE_GS1_128, -1, "[01][]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short)" }, - /* 87*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01][]12", "", 0, "" }, /* Length 0 AI with data not checked, non-short AI with zero-length data not checked */ - /* 88*/ { BARCODE_GS1_128, -1, "[1]1[]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short)" }, - /* 89*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[1]1[]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short)" }, /* Length 1 AI with data still checked */ - /* 90*/ { BARCODE_GS1_128, -1, "[]12[1]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /* 91*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[]12[1]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 1 AI with data still checked */ - /* 92*/ { BARCODE_GS1_128, -1, "[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /* 93*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 0 AI with no data still checked */ - /* 94*/ { BARCODE_GS1_128, -1, "^", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 1" }, - /* 95*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "^", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 1" }, - /* 96*/ { BARCODE_GS1_128, -1, "[01]12345678901231[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, - /* 97*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]12345678901231[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, /* Length 0 AI with no data still checked */ - /* 98*/ { BARCODE_GS1_128, -1, "[01]12345678901231[][20]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, - /* 99*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]12345678901231[][20]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, /* Length 0 AI with no data still checked */ - /*100*/ { BARCODE_GS1_128, -1, "[01]12345678901231[]1[20]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, - /*101*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[01]12345678901231[]1[20]12", "", 0, "" }, /* Length 0 AI with data not checked */ - /*102*/ { BARCODE_GS1_128, -1, "[1234567890]123", "", ZINT_ERROR_INVALID_DATA, "Error 255: Invalid AI at position 1 in input (AI too long)" }, - /*103*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[1234567890]123", "", ZINT_ERROR_INVALID_DATA, "Error 255: Invalid AI at position 1 in input (AI too long)" }, /* Too long still checked */ - /*104*/ { BARCODE_GS1_128, -1, "[12345]123", "", ZINT_ERROR_INVALID_DATA, "Error 255: Invalid AI at position 1 in input (AI too long)" }, - /*105*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, "[12345]123", "", ZINT_ERROR_INVALID_DATA, "Error 255: Invalid AI at position 1 in input (AI too long)" }, /* Too long still checked */ - /*106*/ { BARCODE_GS1_128, GS1PARENS_MODE, "(91)AB[", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (91) data position 3: Invalid CSET 82 character '['" }, - /*107*/ { BARCODE_GS1_128, GS1PARENS_MODE | GS1NOCHECK_MODE, "(91)AB[", "", 0, "" }, - /*108*/ { BARCODE_GS1_128_CC, -1, "[01]12345678901231", "[20]12", 0, "" }, - /*109*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]12345678901231", "[20]12", 0, "" }, - /*110*/ { BARCODE_GS1_128_CC, -1, "[01]12345678901234", "[20]12", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1' (linear component)" }, - /*111*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]12345678901234", "[20]12", 0, "" }, - /*112*/ { BARCODE_GS1_128_CC, -1, "[01]123456789012345", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1 (linear component)" }, - /*113*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]123456789012345", "[20]12", 0, "" }, - /*114*/ { BARCODE_GS1_128_CC, -1, "[01]12345678901231", "[20]123", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 1 (2D component)" }, - /*115*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]12345678901231", "[20]123", 0, "" }, - /*116*/ { BARCODE_GS1_128_CC, -1, "[01]12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)" }, - /*117*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]12345678901231", "[20]1A", 0, "" }, - /*118*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121\177", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (linear component)" }, - /*119*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121\177", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (linear component)" }, /* Nonprintable ASCII still checked */ - /*120*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, - /*121*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, /* Nonprintable ASCII still checked */ - /*122*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121\200", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (linear component)" }, - /*123*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121\200", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (linear component)" }, - /*124*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, - /*125*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, /* Extended ASCII still checked */ - /*126*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, - /*127*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, /* Format still checked */ - /*128*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "[20]", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (20) at position 1 (2D component)" }, - /*129*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[20]", 0, "" }, /* Zero-length data not checked */ - /*130*/ { BARCODE_GS1_128_CC, -1, "^011234567890121", "^20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 2 (2D component)" }, - /*131*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "^011234567890121", "^20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 2 (2D component)" }, - /*132*/ { BARCODE_GS1_128_CC, GS1RAW_MODE, "011234567890121", "20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 1 (2D component)" }, - /*133*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE | GS1RAW_MODE, "011234567890121", "20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 1 (2D component)" }, - /*134*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "^011234567890121", "^20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 2 (2D component)" }, - /*135*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "[2]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, - /*136*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[2]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 1 AI still checked */ - /*137*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "[]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, - /*138*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[]12", 0, "" }, /* Length 0 AI with data not checked */ - /*139*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "[1]2[]1", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short) (2D component)" }, - /*140*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[1]2[]1", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short) (2D component)" }, /* Length 1 AI still checked */ - /*141*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, - /*142*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ - /*143*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "[][20]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, - /*144*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[][20]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ - /*145*/ { BARCODE_GS1_128_CC, -1, "[01]1234567890121", "[20]12[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short) (2D component)" }, - /*146*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[20]12[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ - /*147*/ { BARCODE_GS1_128_CC, -1, "[01]12345678901231", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, - /*148*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, "[01]12345678901231", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, /* Non-CSET 82 always checked for composite data */ - /*149*/ { BARCODE_DBAR_EXP, -1, "[01]12345678901231", "", 0, "" }, - /*150*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[01]12345678901231", "", 0, "" }, - /*151*/ { BARCODE_DBAR_EXP, -1, "[01]12345678901231[10]123[11]1234", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26" }, - /*152*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]1234", "", 0, "" }, - /*153*/ { BARCODE_DBAR_EXP, -1, "^011234567890123110123^111234", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 24" }, - /*154*/ { BARCODE_DBAR_EXP, GS1RAW_MODE, "011234567890123110123\035111234", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 23" }, - /*155*/ { BARCODE_DBAR_EXP, -1, "[01]12345678901231[10]123[11]1234A", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26" }, - /*156*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]1234A", "", 0, "" }, - /*157*/ { BARCODE_DBAR_EXP, -1, "[01]12345678901231[10]123[11]12345A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 6: Non-numeric character 'A'" }, - /*158*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]12345A", "", 0, "" }, - /*159*/ { BARCODE_DBAR_EXP, -1, "[01]1234567890121\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, - /*160*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[01]1234567890121\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, /* Nonprintable ASCII still checked */ - /*161*/ { BARCODE_DBAR_EXP, -1, "[01]1234567890121\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, - /*162*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[01]1234567890121\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, /* Extended ASCII still checked */ - /*163*/ { BARCODE_DBAR_EXP, -1, "011234567890121", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, - /*164*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "011234567890121", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, /* Format still checked */ - /*165*/ { BARCODE_DBAR_EXP, -1, "[10]", "", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (10) at position 1" }, - /*166*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[10]", "", 0, "" }, /* Zero-length data not checked */ - /*167*/ { BARCODE_DBAR_EXP, -1, "[2]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /*168*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[2]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 1 AI still checked */ - /*169*/ { BARCODE_DBAR_EXP, -1, "[]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /*170*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[]1", "", 0, "" }, /* Length 0 AI with data not checked */ - /*171*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE | GS1RAW_MODE, "1", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 1" }, /* Checked as AI */ - /*172*/ { BARCODE_DBAR_EXP, -1, "[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /*173*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 0 AI with no data still checked */ - /*174*/ { BARCODE_DBAR_EXP, -1, "[20]12[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short)" }, - /*175*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[20]12[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short)" }, /* Length 0 AI with no data still checked */ - /*176*/ { BARCODE_DBAR_EXP, -1, "[90]12]34", "", ZINT_ERROR_INVALID_DATA, "Error 386: Invalid character in General Field data" }, - /*177*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[90]12]34", "", ZINT_ERROR_INVALID_DATA, "Error 386: Invalid character in General Field data" }, /* Non-CSET 82 always checked for DBAR_EXP */ - /*178*/ { BARCODE_DBAR_EXP, -1, "[]01914190S5(60)1239322", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, - /*179*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "[]019000000000000039302", "", 0, "" }, /* Encoding method 6 */ - /*180*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, "^019000000000000039302", "", 0, "" }, - /*181*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE | GS1RAW_MODE, "019000000000000039302", "", 0, "" }, - /*182*/ { BARCODE_DBAR_EXP_CC, -1, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345", 0, "" }, - /*183*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345", 0, "" }, - /*184*/ { BARCODE_DBAR_EXP_CC, -1, "[01]12345678901231[10]123[11]1234", "[21]ABC123[22]12345", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26 (linear component)" }, - /*185*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]1234", "[21]ABC123[22]12345", 0, "" }, - /*186*/ { BARCODE_DBAR_EXP_CC, -1, "[01]12345678901231[10]123[11]123456", "[21]ABC123[22]12345", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 3: Invalid month '34' (linear component)" }, - /*187*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]123456", "[21]ABC123[22]12345", 0, "" }, - /*188*/ { BARCODE_DBAR_EXP_CC, -1, "^011234567890123110123^11123456", "^21ABC123^2212345", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 3: Invalid month '34' (linear component)" }, - /*189*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "^011234567890123110123^11123456", "^21ABC123^2212345", 0, "" }, - /*190*/ { BARCODE_DBAR_EXP_CC, GS1RAW_MODE, "011234567890123110123\03511123456", "21ABC123\0352212345", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 3: Invalid month '34' (linear component)" }, - /*191*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE | GS1RAW_MODE, "011234567890123110123\03511123456", "21ABC123\0352212345", 0, "" }, - /*192*/ { BARCODE_DBAR_EXP_CC, -1, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]123456789", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (30) at position 20 (2D component)" }, - /*193*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]123456789", 0, "" }, - /*194*/ { BARCODE_DBAR_EXP_CC, -1, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]1234567A", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (30) data position 8: Non-numeric character 'A' (2D component)" }, - /*195*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]1234567A", 0, "" }, - /*196*/ { BARCODE_DBAR_EXP_CC, -1, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, - /*197*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, /* Nonprintable ASCII still checked */ - /*198*/ { BARCODE_DBAR_EXP_CC, -1, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, - /*199*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, /* Extended ASCII still checked */ - /*200*/ { BARCODE_DBAR_EXP_CC, -1, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, - /*201*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, /* Format still checked */ - /*202*/ { BARCODE_DBAR_EXP_CC, -1, "[01]1234567890121", "[10]", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (10) at position 1 (2D component)" }, - /*203*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[10]", 0, "" }, /* Zero-length data not checked */ - /*204*/ { BARCODE_DBAR_EXP_CC, -1, "[01]1234567890121", "[2]1", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, - /*205*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[2]1", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 1 AI still checked */ - /*206*/ { BARCODE_DBAR_EXP_CC, -1, "[01]1234567890121", "[]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, - /*207*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[]12", 0, "" }, /* Length 0 AI with data not checked */ - /*208*/ { BARCODE_DBAR_EXP_CC, -1, "[01]1234567890121", "[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, - /*209*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ - /*210*/ { BARCODE_DBAR_EXP_CC, -1, "[01]1234567890121", "[20]12[][10]123", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short) (2D component)" }, - /*211*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[20]12[][10]123", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ - /*212*/ { BARCODE_DBAR_EXP_CC, -1, "[01]1234567890121", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, - /*213*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, /* Non-CSET 82 always checked for composite */ - /*214*/ { BARCODE_DBAR_EXPSTK, -1, "[01]12345678901231", "", 0, "" }, - /*215*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, "[01]12345678901231", "", 0, "" }, - /*216*/ { BARCODE_DBAR_EXPSTK, -1, "[01]12345678901231[10]123[11]1234", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26" }, - /*217*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]1234", "", 0, "" }, - /*218*/ { BARCODE_DBAR_EXPSTK, -1, "[01]12345678901231[10]123[11]1234A", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26" }, - /*219*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]1234A", "", 0, "" }, - /*220*/ { BARCODE_DBAR_EXPSTK, -1, "[01]12345678901231[10]123[11]12345A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 6: Non-numeric character 'A'" }, - /*221*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]12345A", "", 0, "" }, - /*222*/ { BARCODE_DBAR_EXPSTK, -1, "[01]1234567890121\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, - /*223*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, "[01]1234567890121\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, /* Nonprintable ASCII still checked */ - /*224*/ { BARCODE_DBAR_EXPSTK, -1, "[01]1234567890121\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, - /*225*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, "[01]1234567890121\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, /* Extended ASCII still checked */ - /*226*/ { BARCODE_DBAR_EXPSTK, -1, "011234567890121", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, - /*227*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, "011234567890121", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, /* Format still checked */ - /*228*/ { BARCODE_DBAR_EXPSTK, -1, "[01]", "", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (01) at position 1" }, - /*229*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, "[01]", "", 0, "" }, /* Zero-length data not checked */ - /*230*/ { BARCODE_DBAR_EXPSTK, -1, "[90]12]34", "", ZINT_ERROR_INVALID_DATA, "Error 386: Invalid character in General Field data" }, - /*231*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, "[90]12]34", "", ZINT_ERROR_INVALID_DATA, "Error 386: Invalid character in General Field data" }, /* Non-CSET 82 always checked for DBAR_EXPSTK */ - /*232*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345", 0, "" }, - /*233*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345", 0, "" }, - /*234*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]12345678901231[10]123[11]1234", "[21]ABC123[22]12345", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26 (linear component)" }, - /*235*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]1234", "[21]ABC123[22]12345", 0, "" }, - /*236*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]12345678901231[10]123[11]123456", "[21]ABC123[22]12345", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 3: Invalid month '34' (linear component)" }, - /*237*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]12345678901231[10]123[11]123456", "[21]ABC123[22]12345", 0, "" }, - /*238*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]123456789", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (30) at position 20 (2D component)" }, - /*239*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]123456789", 0, "" }, - /*240*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]1234567A", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (30) data position 8: Non-numeric character 'A' (2D component)" }, - /*241*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]1234567A", 0, "" }, - /*242*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, - /*243*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, /* Nonprintable ASCII still checked */ - /*244*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, - /*245*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, /* Extended ASCII still checked */ - /*246*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, - /*247*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, /* Format still checked */ - /*248*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]1234567890121", "[235]", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (235) at position 1 (2D component)" }, - /*249*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[235]", 0, "" }, /* Zero-length data not checked */ - /*250*/ { BARCODE_DBAR_EXPSTK_CC, -1, "^011234567890121", "^235", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (23) at position 2 (2D component)" }, - /*251*/ { BARCODE_DBAR_EXPSTK_CC, GS1RAW_MODE, "011234567890121", "235", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (23) at position 1 (2D component)" }, - /*252*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]1234567890121", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, - /*253*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, "[01]1234567890121", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, /* Non-CSET 82 always checked for composite */ - /*254*/ { BARCODE_DBAR_EXPSTK_CC, -1, "^011234567890121", "^", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 1 (2D component)" }, + /* 0*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]12345678901231", "", 0, "" }, + /* 1*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231", "", 0, "" }, + /* 2*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]12345678901234", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'" }, + /* 3*/ { BARCODE_GS1_128, -1, COMPLIANT_HEIGHT, 1.0f, "[01]12345678901234", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'" }, + /* 4*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901234", "", 0, "" }, + /* 5*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, COMPLIANT_HEIGHT, 1.0f, "[01]12345678901234", "", ZINT_WARN_NONCOMPLIANT, "Warning 247: Height not compliant with standards (too small)" }, + /* 6*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^0112345678901234", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'" }, + /* 7*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^0112345678901234", "", 0, "" }, + /* 8*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "0112345678901234", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'" }, + /* 9*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "0112345678901234", "", 0, "" }, + /* 10*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1" }, + /* 11*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]123456789012345", "", 0, "" }, + /* 12*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^01123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 859: Invalid data length for AI (01) at position 2" }, + /* 13*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^01123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 859: Invalid data length for AI (01) at position 2" }, /* Raw/caret need underlong data lengths to work - also new so no need for backward-compatibility */ + /* 14*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "01123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 859: Invalid data length for AI (01) at position 1" }, + /* 15*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "01123456789012345", "", ZINT_ERROR_INVALID_DATA, "Error 859: Invalid data length for AI (01) at position 1" }, + /* 16*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]1234567890123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1" }, + /* 17*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890123", "", 0, "" }, + /* 18*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^011234567890123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 2" }, + /* 19*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^011234567890123", "", 0, "" }, /* Raw/caret too short data lengths ok */ + /* 20*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "011234567890123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1" }, + /* 21*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "011234567890123", "", 0, "" }, + /* 22*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^011234567890123^", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 2" }, + /* 23*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^011234567890123^", "", 0, "" }, + /* 24*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "011234567890123\035", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1" }, + /* 25*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "011234567890123\035", "", 0, "" }, + /* 26*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]12345678901231[20]1", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 19" }, + /* 27*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[20]1", "", 0, "" }, + /* 28*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^0112345678901231201", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 18" }, + /* 29*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^0112345678901231201", "", 0, "" }, + /* 30*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "0112345678901231201", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 17" }, + /* 31*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "0112345678901231201", "", 0, "" }, + /* 32*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^0112345678901231201^", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 18" }, + /* 33*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^0112345678901231201^", "", 0, "" }, + /* 34*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "0112345678901231201\035", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 17" }, + /* 35*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "0112345678901231201\035", "", 0, "" }, + /* 36*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^0112345678901231^201", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 19" }, + /* 37*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^0112345678901231^201", "", 0, "" }, + /* 38*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "0112345678901231\035201", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 18" }, + /* 39*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "0112345678901231\035201", "", 0, "" }, + /* 40*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[03]123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (03) at position 1" }, + /* 41*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[03]123", "", 0, "" }, + /* 42*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^03123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (03) at position 2" }, + /* 43*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^03123", "", 0, "" }, + /* 44*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "03123", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (03) at position 1" }, + /* 45*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "03123", "", 0, "" }, + /* 46*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[04]1234[05]12345[06]123456", "", ZINT_ERROR_INVALID_DATA, "Error 260: Invalid AI (04) at position 1" }, + /* 47*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[04]1234[05]12345[06]123456", "", 0, "" }, + /* 48*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^041234^0512345^06123456", "", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (04) at position 2" }, + /* 49*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^041234^0512345^06123456", "", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (04) at position 2" }, /* Raw/caret mode needs valid AIs to work */ + /* 50*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "041234\0350512345\03506123456", "", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (04) at position 1" }, + /* 51*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "041234\0350512345\03506123456", "", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (04) at position 1" }, + /* 52*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]1234567890123A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Non-numeric character 'A'" }, + /* 53*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890123A", "", 0, "" }, + /* 54*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^011234567890123A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Non-numeric character 'A'" }, + /* 55*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^011234567890123A", "", 0, "" }, + /* 56*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "011234567890123A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Non-numeric character 'A'" }, + /* 57*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "011234567890123A", "", 0, "" }, + /* 58*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]1234567890123.", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Non-numeric character '.'" }, + /* 59*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890123.", "", 0, "" }, + /* 60*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]1234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, + /* 61*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, /* Nonprintable ASCII still checked */ + /* 62*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^011234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, + /* 63*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^011234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, + /* 64*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "011234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, + /* 65*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "011234567890123\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, + /* 66*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]1234567890123\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, + /* 67*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890123\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, /* Extended ASCII still checked */ + /* 68*/ { BARCODE_GS1_128, -1, -1, 0.0f, "0112345678901231", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, + /* 69*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "0112345678901231", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, /* Format still checked */ + /* 70*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]", "", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (01) at position 1" }, + /* 71*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]", "", 0, "" }, /* Zero-length data not checked */ + /* 72*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^01", "", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (01) at position 2" }, + /* 73*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^01", "", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (01) at position 2" }, /* Raw/caret mode needs valid data_lengths to work */ + /* 74*/ { BARCODE_GS1_128, GS1RAW_MODE, -1, 0.0f, "01", "", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (01) at position 1" }, + /* 75*/ { BARCODE_GS1_128, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "01", "", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (01) at position 1" }, + /* 76*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01][20]12", "", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (01) at position 1" }, + /* 77*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01][20]12", "", 0, "" }, /* Zero-length data not checked */ + /* 78*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[0]123", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /* 79*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[0]123", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 1 AI with no data still checked */ + /* 80*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[0]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /* 81*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[0]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 1 AI with no data still checked */ + /* 82*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^0", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 2" }, + /* 83*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^0", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 2" }, + /* 84*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /* 85*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[]12", "", 0, "" }, /* Length 0 AI with data not checked */ + /* 86*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[]12[01]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /* 87*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[]12[01]", "", 0, "" }, /* Length 0 AI with data not checked, non-short AI with zero-length data not checked */ + /* 88*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01][]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short)" }, + /* 89*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01][]12", "", 0, "" }, /* Length 0 AI with data not checked, non-short AI with zero-length data not checked */ + /* 90*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[1]1[]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short)" }, + /* 91*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[1]1[]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short)" }, /* Length 1 AI with data still checked */ + /* 92*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[]12[1]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /* 93*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[]12[1]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 1 AI with data still checked */ + /* 94*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /* 95*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 0 AI with no data still checked */ + /* 96*/ { BARCODE_GS1_128, -1, -1, 0.0f, "^", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 1" }, + /* 97*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "^", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 1" }, + /* 98*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]12345678901231[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, + /* 99*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, /* Length 0 AI with no data still checked */ + /*100*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]12345678901231[][20]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, + /*101*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[][20]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, /* Length 0 AI with no data still checked */ + /*102*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[01]12345678901231[]1[20]12", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 19 in input (AI too short)" }, + /*103*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[]1[20]12", "", 0, "" }, /* Length 0 AI with data not checked */ + /*104*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[1234567890]123", "", ZINT_ERROR_INVALID_DATA, "Error 255: Invalid AI at position 1 in input (AI too long)" }, + /*105*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[1234567890]123", "", ZINT_ERROR_INVALID_DATA, "Error 255: Invalid AI at position 1 in input (AI too long)" }, /* Too long still checked */ + /*106*/ { BARCODE_GS1_128, -1, -1, 0.0f, "[12345]123", "", ZINT_ERROR_INVALID_DATA, "Error 255: Invalid AI at position 1 in input (AI too long)" }, + /*107*/ { BARCODE_GS1_128, GS1NOCHECK_MODE, -1, 0.0f, "[12345]123", "", ZINT_ERROR_INVALID_DATA, "Error 255: Invalid AI at position 1 in input (AI too long)" }, /* Too long still checked */ + /*108*/ { BARCODE_GS1_128, GS1PARENS_MODE, -1, 0.0f, "(91)AB[", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (91) data position 3: Invalid CSET 82 character '['" }, + /*109*/ { BARCODE_GS1_128, GS1PARENS_MODE | GS1NOCHECK_MODE, -1, 0.0f, "(91)AB[", "", 0, "" }, + /*110*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]12345678901231", "[20]12", 0, "" }, + /*111*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231", "[20]12", 0, "" }, + /*112*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]12345678901234", "[20]12", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1' (linear component)" }, + /*113*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901234", "[20]12", 0, "" }, + /*114*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]123456789012345", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (01) at position 1 (linear component)" }, + /*115*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]123456789012345", "[20]12", 0, "" }, + /*116*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]12345678901231", "[20]123", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (20) at position 1 (2D component)" }, + /*117*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231", "[20]123", 0, "" }, + /*118*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]12345678901231", "[20]1A", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (20) data position 2: Non-numeric character 'A' (2D component)" }, + /*119*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231", "[20]1A", 0, "" }, + /*120*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121\177", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (linear component)" }, + /*121*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121\177", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (linear component)" }, /* Nonprintable ASCII still checked */ + /*122*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, + /*123*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, /* Nonprintable ASCII still checked */ + /*124*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121\200", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (linear component)" }, + /*125*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121\200", "[20]12", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (linear component)" }, + /*126*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, + /*127*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, /* Extended ASCII still checked */ + /*128*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, + /*129*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, /* Format still checked */ + /*130*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "[20]", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (20) at position 1 (2D component)" }, + /*131*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[20]", 0, "" }, /* Zero-length data not checked */ + /*132*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "^011234567890121", "^20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 2 (2D component)" }, + /*133*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "^011234567890121", "^20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 2 (2D component)" }, + /*134*/ { BARCODE_GS1_128_CC, GS1RAW_MODE, -1, 0.0f, "011234567890121", "20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 1 (2D component)" }, + /*135*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "011234567890121", "20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 1 (2D component)" }, + /*136*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "^011234567890121", "^20", ZINT_ERROR_INVALID_DATA, "Error 858: Empty data field for AI (20) at position 2 (2D component)" }, + /*137*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "[2]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, + /*138*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[2]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 1 AI still checked */ + /*139*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "[]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, + /*140*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[]12", 0, "" }, /* Length 0 AI with data not checked */ + /*141*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "[1]2[]1", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short) (2D component)" }, + /*142*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[1]2[]1", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 5 in input (AI too short) (2D component)" }, /* Length 1 AI still checked */ + /*143*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, + /*144*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ + /*145*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "[][20]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, + /*146*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[][20]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ + /*147*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]1234567890121", "[20]12[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short) (2D component)" }, + /*148*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[20]12[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ + /*149*/ { BARCODE_GS1_128_CC, -1, -1, 0.0f, "[01]12345678901231", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, + /*150*/ { BARCODE_GS1_128_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, /* Non-CSET 82 always checked for composite data */ + /*151*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[01]12345678901231", "", 0, "" }, + /*152*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231", "", 0, "" }, + /*153*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[01]12345678901231[10]123[11]1234", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26" }, + /*154*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]1234", "", 0, "" }, + /*155*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "^011234567890123110123^111234", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 24" }, + /*156*/ { BARCODE_DBAR_EXP, GS1RAW_MODE, -1, 0.0f, "011234567890123110123\035111234", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 23" }, + /*157*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[01]12345678901231[10]123[11]1234A", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26" }, + /*158*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]1234A", "", 0, "" }, + /*159*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[01]12345678901231[10]123[11]12345A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 6: Non-numeric character 'A'" }, + /*160*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]12345A", "", 0, "" }, + /*161*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[01]1234567890121\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, + /*162*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, /* Nonprintable ASCII still checked */ + /*163*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[01]1234567890121\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, + /*164*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, /* Extended ASCII still checked */ + /*165*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "011234567890121", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, + /*166*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "011234567890121", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, /* Format still checked */ + /*167*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[10]", "", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (10) at position 1" }, + /*168*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[10]", "", 0, "" }, /* Zero-length data not checked */ + /*169*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[2]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /*170*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[2]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 1 AI still checked */ + /*171*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[]1", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /*172*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[]1", "", 0, "" }, /* Length 0 AI with data not checked */ + /*173*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "1", "", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 1" }, /* Checked as AI */ + /*174*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /*175*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, /* Length 0 AI with no data still checked */ + /*176*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[20]12[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short)" }, + /*177*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[20]12[]", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short)" }, /* Length 0 AI with no data still checked */ + /*178*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[90]12]34", "", ZINT_ERROR_INVALID_DATA, "Error 386: Invalid character in General Field data" }, + /*179*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[90]12]34", "", ZINT_ERROR_INVALID_DATA, "Error 386: Invalid character in General Field data" }, /* Non-CSET 82 always checked for DBAR_EXP */ + /*180*/ { BARCODE_DBAR_EXP, -1, -1, 0.0f, "[]01914190S5(60)1239322", "", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short)" }, + /*181*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "[]019000000000000039302", "", 0, "" }, /* Encoding method 6 */ + /*182*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, 0.0f, "^019000000000000039302", "", 0, "" }, + /*183*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "019000000000000039302", "", 0, "" }, + /*184*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345", 0, "" }, + /*185*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345", 0, "" }, + /*186*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]1234", "[21]ABC123[22]12345", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26 (linear component)" }, + /*187*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]1234", "[21]ABC123[22]12345", 0, "" }, + /*188*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]123456", "[21]ABC123[22]12345", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 3: Invalid month '34' (linear component)" }, + /*189*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]123456", "[21]ABC123[22]12345", 0, "" }, + /*190*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "^011234567890123110123^11123456", "^21ABC123^2212345", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 3: Invalid month '34' (linear component)" }, + /*191*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "^011234567890123110123^11123456", "^21ABC123^2212345", 0, "" }, + /*192*/ { BARCODE_DBAR_EXP_CC, GS1RAW_MODE, -1, 0.0f, "011234567890123110123\03511123456", "21ABC123\0352212345", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 3: Invalid month '34' (linear component)" }, + /*193*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE | GS1RAW_MODE, -1, 0.0f, "011234567890123110123\03511123456", "21ABC123\0352212345", 0, "" }, + /*194*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]123456789", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (30) at position 20 (2D component)" }, + /*195*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]123456789", 0, "" }, + /*196*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]1234567A", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (30) data position 8: Non-numeric character 'A' (2D component)" }, + /*197*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]1234567A", 0, "" }, + /*198*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, + /*199*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, /* Nonprintable ASCII still checked */ + /*200*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, + /*201*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, /* Extended ASCII still checked */ + /*202*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, + /*203*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, /* Format still checked */ + /*204*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]1234567890121", "[10]", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (10) at position 1 (2D component)" }, + /*205*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[10]", 0, "" }, /* Zero-length data not checked */ + /*206*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]1234567890121", "[2]1", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, + /*207*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[2]1", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 1 AI still checked */ + /*208*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]1234567890121", "[]12", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, + /*209*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[]12", 0, "" }, /* Length 0 AI with data not checked */ + /*210*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]1234567890121", "[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, + /*211*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[]", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 1 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ + /*212*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]1234567890121", "[20]12[][10]123", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short) (2D component)" }, + /*213*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[20]12[][10]123", ZINT_ERROR_INVALID_DATA, "Error 256: Invalid AI at position 7 in input (AI too short) (2D component)" }, /* Length 0 AI with no data still checked */ + /*214*/ { BARCODE_DBAR_EXP_CC, -1, -1, 0.0f, "[01]1234567890121", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, + /*215*/ { BARCODE_DBAR_EXP_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, /* Non-CSET 82 always checked for composite */ + /*216*/ { BARCODE_DBAR_EXPSTK, -1, -1, 0.0f, "[01]12345678901231", "", 0, "" }, + /*217*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231", "", 0, "" }, + /*218*/ { BARCODE_DBAR_EXPSTK, -1, -1, 0.0f, "[01]12345678901231[10]123[11]1234", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26" }, + /*219*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]1234", "", 0, "" }, + /*220*/ { BARCODE_DBAR_EXPSTK, -1, -1, 0.0f, "[01]12345678901231[10]123[11]1234A", "", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26" }, + /*221*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]1234A", "", 0, "" }, + /*222*/ { BARCODE_DBAR_EXPSTK, -1, -1, 0.0f, "[01]12345678901231[10]123[11]12345A", "", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 6: Non-numeric character 'A'" }, + /*223*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]12345A", "", 0, "" }, + /*224*/ { BARCODE_DBAR_EXPSTK, -1, -1, 0.0f, "[01]1234567890121\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, + /*225*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121\177", "", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1" }, /* Nonprintable ASCII still checked */ + /*226*/ { BARCODE_DBAR_EXPSTK, -1, -1, 0.0f, "[01]1234567890121\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, + /*227*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121\200", "", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1" }, /* Extended ASCII still checked */ + /*228*/ { BARCODE_DBAR_EXPSTK, -1, -1, 0.0f, "011234567890121", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, + /*229*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, 0.0f, "011234567890121", "", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI" }, /* Format still checked */ + /*230*/ { BARCODE_DBAR_EXPSTK, -1, -1, 0.0f, "[01]", "", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (01) at position 1" }, + /*231*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, 0.0f, "[01]", "", 0, "" }, /* Zero-length data not checked */ + /*232*/ { BARCODE_DBAR_EXPSTK, -1, -1, 0.0f, "[90]12]34", "", ZINT_ERROR_INVALID_DATA, "Error 386: Invalid character in General Field data" }, + /*233*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, 0.0f, "[90]12]34", "", ZINT_ERROR_INVALID_DATA, "Error 386: Invalid character in General Field data" }, /* Non-CSET 82 always checked for DBAR_EXPSTK */ + /*234*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345", 0, "" }, + /*235*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345", 0, "" }, + /*236*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]1234", "[21]ABC123[22]12345", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (11) at position 26 (linear component)" }, + /*237*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]1234", "[21]ABC123[22]12345", 0, "" }, + /*238*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]123456", "[21]ABC123[22]12345", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (11) data position 3: Invalid month '34' (linear component)" }, + /*239*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]12345678901231[10]123[11]123456", "[21]ABC123[22]12345", 0, "" }, + /*240*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]123456789", ZINT_ERROR_INVALID_DATA, "Error 259: Invalid data length for AI (30) at position 20 (2D component)" }, + /*241*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]123456789", 0, "" }, + /*242*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]1234567A", ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (30) data position 8: Non-numeric character 'A' (2D component)" }, + /*243*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]123456789012[01]12345678901231[10]123[11]121212", "[21]ABC123[22]12345[30]1234567A", 0, "" }, + /*244*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, + /*245*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[20]1\177", ZINT_ERROR_INVALID_DATA, "Error 263: DEL characters are not supported by GS1 (2D component)" }, /* Nonprintable ASCII still checked */ + /*246*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, + /*247*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[20]1\200", ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1 (2D component)" }, /* Extended ASCII still checked */ + /*248*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, + /*249*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "2012", ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI (2D component)" }, /* Format still checked */ + /*250*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]1234567890121", "[235]", ZINT_ERROR_INVALID_DATA, "Error 258: Empty data field for AI (235) at position 1 (2D component)" }, + /*251*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[235]", 0, "" }, /* Zero-length data not checked */ + /*252*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "^011234567890121", "^235", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (23) at position 2 (2D component)" }, + /*253*/ { BARCODE_DBAR_EXPSTK_CC, GS1RAW_MODE, -1, 0.0f, "011234567890121", "235", ZINT_ERROR_INVALID_DATA, "Error 856: Invalid AI (23) at position 1 (2D component)" }, + /*254*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "[01]1234567890121", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, + /*255*/ { BARCODE_DBAR_EXPSTK_CC, GS1NOCHECK_MODE, -1, 0.0f, "[01]1234567890121", "[90]12]34", ZINT_ERROR_INVALID_DATA, "Error 441: Invalid character in input (2D component)" }, /* Non-CSET 82 always checked for composite */ + /*256*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, 0.0f, "^011234567890121", "^", ZINT_ERROR_INVALID_DATA, "Error 857: Invalid AI at position 1 (2D component)" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -3195,8 +3199,11 @@ static void test_gs1nocheck_mode(const testCtx *const p_ctx) { text = data[i].data; } length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, text, -1, debug); + if (data[i].height) { + symbol->height = data[i].height; + } ret = ZBarcode_Encode(symbol, TCU(text), length); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", @@ -3429,6 +3436,26 @@ static void test_gs1_lint_parse_raw_caret(const testCtx *const p_ctx) { /* 47*/ { "1012345678901234567890211", 0, 0, { 10, 0, 0, 0 }, { 0, 0, 0, 0 }, { 2, 0, 0, 0 }, { 20, 0, 0, 0 }, 2, 1 }, /* Ticket #352, props Simon Resch */ /* 48*/ { "^1012345678901234567890^211", 1, 2, { 10, 21, 0, 0 }, { 1, 24, 0, 0 }, { 3, 26, 0, 0 }, { 20, 1, 0, 0 }, 0, 0 }, /* 49*/ { "1012345678901234567890\035211", 1, 2, { 10, 21, 0, 0 }, { 0, 23, 0, 0 }, { 2, 25, 0, 0 }, { 20, 1, 0, 0 }, 0, 0 }, + /* 50*/ { "^243a^400b^40213131313131313130^420a", 1, 4, { 243, 400, 402, 420 }, { 1, 6, 11, 32 }, { 4, 9, 14, 35 }, { 1, 1, 17, 1 }, 0, 0 }, + /* 51*/ { "^421434a^423470^427a^710a", 1, 4, { 421, 423, 427, 710 }, { 1, 9, 16, 21 }, { 4, 12, 19, 24 }, { 4, 3, 1, 1 }, 0, 0 }, + /* 52*/ { "^3240123456^3270123456^3305123456^3340123456", 1, 4, { 3240, 3270, 3305, 3340 }, { 1, 12, 23, 34 }, { 5, 16, 27, 38 }, { 6, 6, 6, 6 }, 0, 0 }, + /* 53*/ { "^3570123456^3605123456^3640123456^3670123456", 1, 4, { 3570, 3605, 3640, 3670 }, { 1, 12, 23, 34 }, { 5, 16, 27, 38 }, { 6, 6, 6, 6 }, 0, 0 }, + /* 54*/ { "^3370123456^3470123456^4300a^7008%12", 1, 4, { 3370, 3470, 4300, 7008 }, { 1, 12, 23, 29 }, { 5, 16, 27, 33 }, { 6, 6, 1, 3 }, 0, 0 }, + /* 55*/ { "^3950123456^4302a^4307DE^4308a", 1, 4, { 3950, 4302, 4307, 4308 }, { 1, 12, 18, 25 }, { 5, 16, 22, 29 }, { 6, 1, 2, 1 }, 0, 0 }, + /* 56*/ { "^430912345678901234567890^4318a^43210^43240101010000", 1, 4, { 4309, 4318, 4321, 4324 }, { 1, 26, 32, 38 }, { 5, 30, 36, 42 }, { 20, 1, 1, 10 }, 0, 0 }, + /* 57*/ { "^4326010101^4330123456^70011234567890123^7002a", 1, 4, { 4326, 4330, 7001, 7002 }, { 1, 12, 23, 41 }, { 5, 16, 27, 45 }, { 6, 6, 13, 1 }, 0, 0 }, + /* 58*/ { "^70030101010000^70040^7005a^7007010101", 1, 4, { 7003, 7004, 7005, 7007 }, { 1, 16, 22, 28 }, { 5, 20, 26, 32 }, { 10, 1, 1, 6 }, 0, 0 }, + /* 59*/ { "^7009a^7010a^7011010101^7010a", 1, 4, { 7009, 7010, 7011, 7010 }, { 1, 7, 13, 24 }, { 5, 11, 17, 28 }, { 1, 1, 6, 1 }, 0, 0 }, + /* 60*/ { "^7011010101^7020a^70231234^7030004a", 1, 4, { 7011, 7020, 7023, 7030 }, { 1, 12, 18, 27 }, { 5, 16, 22, 31 }, { 6, 1, 4, 4 }, 0, 0 }, + /* 61*/ { "^70401xyz^70419^7230abc^7240a", 1, 4, { 7040, 7041, 7230, 7240 }, { 1, 10, 16, 24 }, { 5, 14, 20, 28 }, { 4, 1, 3, 1 }, 0, 0 }, + /* 62*/ { "^724109^7242a^725020000101^7251190406160800", 1, 4, { 7241, 7242, 7250, 7251 }, { 1, 8, 14, 27 }, { 5, 12, 18, 31 }, { 2, 1, 8, 12 }, 0, 0 }, + /* 63*/ { "^72520^7253a^7255a^7256a", 1, 4, { 7252, 7253, 7255, 7256 }, { 1, 7, 13, 19 }, { 5, 11, 17, 23 }, { 1, 1, 1, 1 }, 0, 0 }, + /* 64*/ { "^7257a^72582/3^8002a^800301234567890128a", 1, 4, { 7257, 7258, 8002, 8003 }, { 1, 7, 15, 21 }, { 5, 11, 19, 25 }, { 1, 3, 1, 15 }, 0, 0 }, + /* 65*/ { "^80041234^8005123456^8007AD^8009a", 1, 4, { 8004, 8005, 8007, 8009 }, { 1, 10, 21, 28 }, { 5, 14, 25, 32 }, { 4, 6, 2, 1 }, 0, 0 }, + /* 66*/ { "^8011a^8013a^8014a^8017313131313131313131", 1, 4, { 8011, 8013, 8014, 8017 }, { 1, 7, 13, 19 }, { 5, 11, 17, 23 }, { 1, 1, 1, 18 }, 0, 0 }, + /* 67*/ { "^8019a^8020a^8030a^8040123456789012345", 1, 4, { 8019, 8020, 8030, 8040 }, { 1, 7, 13, 19 }, { 5, 11, 17, 23 }, { 1, 1, 1, 15 }, 0, 0 }, + /* 68*/ { "^804212345678901234567890123456789012^8043123456789012345678^8110a^81111234", 1, 4, { 8042, 8043, 8110, 8111 }, { 1, 38, 61, 67 }, { 5, 42, 65, 71 }, { 32, 18, 1, 4 }, 0, 0 }, + /* 69*/ { "^8112a^8006123456789012310101", 1, 2, { 8112, 8006, 0, 0 }, { 1, 7, 0, 0 }, { 5, 11, 0, 0 }, { 1, 18, 0, 0 }, 0, 0 }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -3456,22 +3483,22 @@ static void test_gs1_lint_parse_raw_caret(const testCtx *const p_ctx) { assert_equal(ai_count, data[i].expected_ai_count, "i:%d ai_count %d != %d\n", i, ai_count, data[i].expected_ai_count); assert_zero(memcmp(ai_vals, data[i].expected_ai_vals, sizeof(int) * ARRAY_SIZE(ai_vals)), - "i:%d ai_vals %d,%d,%d,%d != %d,%d,%d,%d\n", i, + "i:%d ai_vals %d, %d, %d, %d != %d, %d, %d, %d\n", i, ai_vals[0], ai_vals[1], ai_vals[2], ai_vals[3], data[i].expected_ai_vals[0], data[i].expected_ai_vals[1], data[i].expected_ai_vals[2], data[i].expected_ai_vals[3]); assert_zero(memcmp(ai_locs, data[i].expected_ai_locs, sizeof(int) * ARRAY_SIZE(ai_locs)), - "i:%d ai_locs %d,%d,%d,%d != %d,%d,%d,%d\n", i, + "i:%d ai_locs %d, %d, %d, %d != %d, %d, %d, %d\n", i, ai_locs[0], ai_locs[1], ai_locs[2], ai_locs[3], data[i].expected_ai_locs[0], data[i].expected_ai_locs[1], data[i].expected_ai_locs[2], data[i].expected_ai_locs[3]); assert_zero(memcmp(data_locs, data[i].expected_data_locs, sizeof(int) * ARRAY_SIZE(data_locs)), - "i:%d data_locs %d,%d,%d,%d != %d,%d,%d,%d\n", i, + "i:%d data_locs %d, %d, %d, %d != %d, %d, %d, %d\n", i, data_locs[0], data_locs[1], data_locs[2], data_locs[3], data[i].expected_data_locs[0], data[i].expected_data_locs[1], data[i].expected_data_locs[2], data[i].expected_data_locs[3]); assert_zero(memcmp(data_lens, data[i].expected_data_lens, sizeof(int) * ARRAY_SIZE(data_lens)), - "i:%d data_lens %d,%d,%d,%d != %d,%d,%d,%d\n", i, + "i:%d data_lens %d, %d, %d, %d != %d, %d, %d, %d\n", i, data_lens[0], data_lens[1], data_lens[2], data_lens[3], data[i].expected_data_lens[0], data[i].expected_data_lens[1], data[i].expected_data_lens[2], data[i].expected_data_lens[3]); diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c index e1cc88df..2be3c01e 100644 --- a/backend/tests/test_library.c +++ b/backend/tests/test_library.c @@ -53,6 +53,7 @@ static void test_checks(const testCtx *const p_ctx) { float dot_size; float text_gap; float guard_descent; + int rows; int warn_level; int ret; @@ -61,156 +62,156 @@ static void test_checks(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { BARCODE_CODE128, -1, "1234", -1, -1, 3, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", -1 }, - /* 1*/ { BARCODE_CODE128, -1, "1234", -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", -1 }, - /* 2*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 3, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", -1 }, - /* 3*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 999999 + 1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 218: ECI code '1000000' out of range (0 to 999999, excluding 1, 2, 14 and 19)", -1 }, - /* 4*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 0.009, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 227: Scale out of range (0.01 to 200)", -1 }, - /* 5*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 200.01, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 227: Scale out of range (0.01 to 200)", -1 }, - /* 6*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, -1, 20.1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Dot size out of range (0.01 to 20)", -1 }, - /* 7*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 0.01, 0.009, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Dot size out of range (0.01 to 20)", -1 }, - /* 8*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, -0.1, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 765: Height out of range (0 to 2000)", -1 }, - /* 9*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 2000.01, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 765: Height out of range (0 to 2000)", -1 }, - /* 10*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 766: Whitespace width out of range (0 to 100)", -1 }, - /* 11*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 101, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 766: Whitespace width out of range (0 to 100)", -1 }, - /* 12*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 767: Whitespace height out of range (0 to 100)", -1 }, - /* 13*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 101, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 767: Whitespace height out of range (0 to 100)", -1 }, - /* 14*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, -1, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 768: Border width out of range (0 to 100)", -1 }, - /* 15*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 768: Border width out of range (0 to 100)", -1 }, - /* 16*/ { BARCODE_CODE128, -1, "1234", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 220: Selected symbology does not support GS1 mode", -1 }, - /* 17*/ { BARCODE_EAN13, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, -5.1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 219: Text gap out of range (-5 to 10)", -1 }, - /* 18*/ { BARCODE_EANX, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, -5.1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 219: Text gap out of range (-5 to 10)", -1 }, - /* 19*/ { BARCODE_EAN13, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 10.1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 219: Text gap out of range (-5 to 10)", -1 }, - /* 20*/ { BARCODE_EANX, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 10.1, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 219: Text gap out of range (-5 to 10)", -1 }, - /* 21*/ { BARCODE_EAN13, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, -0.5, -1, ZINT_ERROR_INVALID_OPTION, "Error 769: Guard bar descent out of range (0 to 50)", -1 }, - /* 22*/ { BARCODE_EANX, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, -0.5, -1, ZINT_ERROR_INVALID_OPTION, "Error 769: Guard bar descent out of range (0 to 50)", -1 }, - /* 23*/ { BARCODE_EAN13, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, 50.1, -1, ZINT_ERROR_INVALID_OPTION, "Error 769: Guard bar descent out of range (0 to 50)", -1 }, - /* 24*/ { BARCODE_EANX, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, 50.1, -1, ZINT_ERROR_INVALID_OPTION, "Error 769: Guard bar descent out of range (0 to 50)", -1 }, - /* 25*/ { BARCODE_GS1_128, -1, "[21]12\0004", 8, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 262: NUL characters not permitted in GS1 mode", -1 }, - /* 26*/ { BARCODE_GS1_128, -1, "[21]12é4", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1", -1 }, - /* 27*/ { BARCODE_GS1_128, -1, "[21]12\0074", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 251: Control characters are not supported by GS1", -1 }, - /* 28*/ { BARCODE_GS1_128, -1, "[21]1234", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", -1 }, - /* 29*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /* 30*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /* 31*/ { 0, -1, "1", -1, -1, 1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", BARCODE_CODE128 }, /* Not supporting beats invalid ECI */ - /* 32*/ { 0, -1, "1", -1, -1, 1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /* 33*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, 0.009, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Dot size out of range (0.01 to 20)", BARCODE_CODE128 }, - /* 34*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, 0.009, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /* 35*/ { 0, -1, "1", -1, -1, 1, 0, 0, 0, 0, -1, 0.009, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", BARCODE_CODE128 }, /* Invalid dot size no longer beats invalid ECI */ - /* 36*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, 0.009, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /* 37*/ { 5, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_C25STANDARD }, - /* 38*/ { 5, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_C25STANDARD }, - /* 39*/ { 17, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_UPCA }, - /* 40*/ { 17, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCA }, - /* 41*/ { 19, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_TOO_LONG, "Error 362: Input length 1 too short (minimum 3)", BARCODE_CODABAR }, - /* 42*/ { 19, -1, "A1B", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 207: Codabar 18 not supported", BARCODE_CODABAR }, - /* 43*/ { 19, -1, "A1B", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 207: Codabar 18 not supported", -1 }, - /* 44*/ { 26, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_UPCA }, - /* 45*/ { 26, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCA }, - /* 46*/ { 27, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_OPTION, "Error 208: UPCD1 not supported", 27 }, - /* 47*/ { 33, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI", BARCODE_GS1_128 }, - /* 48*/ { 33, -1, "[10]23", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_GS1_128 }, - /* 49*/ { 33, -1, "[10]23", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_GS1_128 }, - /* 50*/ { 36, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_UPCA }, - /* 51*/ { 36, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCA }, - /* 52*/ { 39, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_UPCE }, - /* 53*/ { 39, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_UPCE }, - /* 54*/ { 41, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_NONCOMPLIANT, "Warning 479: Input length 1 is not standard (should be 5, 9 or 11 digits)", BARCODE_POSTNET }, - /* 55*/ { 41, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_POSTNET }, - /* 56*/ { 41, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, - /* 57*/ { 42, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_POSTNET }, - /* 58*/ { 42, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, - /* 59*/ { 43, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_POSTNET }, - /* 60*/ { 43, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, - /* 61*/ { 44, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_POSTNET }, - /* 62*/ { 44, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, - /* 63*/ { 45, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_POSTNET }, - /* 64*/ { 45, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, - /* 65*/ { 46, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_PLESSEY }, - /* 66*/ { 46, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_PLESSEY }, - /* 67*/ { 48, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_NVE18 }, - /* 68*/ { 48, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_NVE18 }, - /* 69*/ { 59, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_CODE128 }, - /* 70*/ { 59, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_CODE128 }, - /* 71*/ { 61, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_CODE128 }, - /* 72*/ { 61, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_CODE128 }, - /* 73*/ { 62, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_CODE93 }, - /* 74*/ { 62, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_CODE93 }, - /* 75*/ { 64, -1, "12345678", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_AUSPOST }, - /* 76*/ { 64, -1, "12345678", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_AUSPOST }, - /* 77*/ { 65, -1, "12345678", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_AUSPOST }, - /* 78*/ { 65, -1, "12345678", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_AUSPOST }, - /* 79*/ { 78, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_DBAR_OMN }, - /* 80*/ { 78, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_DBAR_OMN }, - /* 81*/ { 83, -1, "12345678901", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_PLANET }, - /* 82*/ { 83, -1, "12345678901", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_PLANET }, - /* 83*/ { 88, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI", BARCODE_GS1_128 }, - /* 84*/ { 88, -1, "[10]12", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_GS1_128 }, - /* 85*/ { 88, -1, "[10]12", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_GS1_128 }, - /* 86*/ { 91, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /* 87*/ { 91, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /* 88*/ { 94, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /* 89*/ { 94, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /* 90*/ { 95, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /* 91*/ { 95, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /* 92*/ { 100, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_HIBC_128 }, - /* 93*/ { 100, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_128 }, - /* 94*/ { 101, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_HIBC_39 }, - /* 95*/ { 101, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_39 }, - /* 96*/ { 103, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_HIBC_DM }, - /* 97*/ { 103, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_DM }, - /* 98*/ { 105, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_HIBC_QR }, - /* 99*/ { 105, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_QR }, - /*100*/ { 107, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_HIBC_PDF }, - /*101*/ { 107, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_PDF }, - /*102*/ { 109, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_HIBC_MICPDF }, - /*103*/ { 109, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_MICPDF }, - /*104*/ { 111, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", BARCODE_HIBC_BLOCKF }, - /*105*/ { 111, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_BLOCKF }, - /*106*/ { 113, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*107*/ { 113, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*108*/ { 114, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*109*/ { 114, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*110*/ { 117, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*111*/ { 117, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*112*/ { 118, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*113*/ { 118, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*114*/ { 122, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*115*/ { 122, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*116*/ { 123, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*117*/ { 123, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*118*/ { 124, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*119*/ { 124, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*120*/ { 125, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*121*/ { 125, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*122*/ { 126, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*123*/ { 126, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*124*/ { 127, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*125*/ { 127, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*126*/ { 150, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*127*/ { 150, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*128*/ { BARCODE_LAST + 1, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, - /*129*/ { BARCODE_LAST + 1, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, - /*130*/ { BARCODE_CODE128, -1, "\200", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 215: Invalid UTF-8 in input", -1 }, - /*131*/ { BARCODE_CODE128, -1, "\\o200", -1, UNICODE_MODE | ESCAPE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 215: Invalid UTF-8 in input", -1 }, - /*132*/ { BARCODE_MAXICODE, -1, "\200", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 215: Invalid UTF-8 in input", -1 }, - /*133*/ { BARCODE_MAXICODE, -1, "\\o200", -1, UNICODE_MODE | ESCAPE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_ERROR_INVALID_DATA, "Error 215: Invalid UTF-8 in input", -1 }, - /*134*/ { BARCODE_GS1_128, -1, "[01]12345678901234", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'", -1 }, - /*135*/ { BARCODE_GS1_128, -1, "[01]12345678901234", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_NONCOMPLIANT, "Error 261: AI (01) data position 14: Bad checksum '4', expected '1'", -1 }, - /*136*/ { BARCODE_QRCODE, -1, "ก", -1, UNICODE_MODE, 13, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", -1 }, - /*137*/ { BARCODE_QRCODE, -1, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_USES_ECI, "Warning 222: Encoded data includes ECI 13", -1 }, - /*138*/ { BARCODE_QRCODE, -1, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_USES_ECI, "Error 222: Encoded data includes ECI 13", -1 }, - /*139*/ { BARCODE_CODEONE, -1, "[01]12345678901231", -1, GS1_MODE, 3, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 512: ECI ignored for GS1 mode", -1 }, - /*140*/ { BARCODE_CODEONE, -1, "[01]12345678901231", -1, GS1_MODE, 3, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 512: ECI ignored for GS1 mode", -1 }, - /*141*/ { BARCODE_CODEONE, -1, "[01]12345678901234", -1, GS1_MODE, 3, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 512: ECI ignored for GS1 mode", -1 }, /* Warning in encoder overrides library warnings */ - /*142*/ { BARCODE_CODEONE, -1, "[01]12345678901234", -1, GS1_MODE, 3, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_NONCOMPLIANT, "Error 261: AI (01) data position 14: Bad checksum '4', expected '1'", -1 }, /* But not errors */ - /*143*/ { BARCODE_AZTEC, -1, "ก", -1, UNICODE_MODE, 13, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, "", -1 }, - /*144*/ { BARCODE_AZTEC, -1, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_USES_ECI, "Warning 222: Encoded data includes ECI 13", -1 }, - /*145*/ { BARCODE_AZTEC, -1, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_USES_ECI, "Error 222: Encoded data includes ECI 13", -1 }, - /*146*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, 13, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_INVALID_OPTION, "Warning 503: Error correction level '6' out of range (1 to 4), ignoring", -1 }, - /*147*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, 13, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 503: Error correction level '6' out of range (1 to 4)", -1 }, - /*148*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, ZINT_WARN_USES_ECI, "Warning 222: Encoded data includes ECI 13", -1 }, /* ECI warning trumps all other warnings */ - /*149*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 503: Error correction level '6' out of range (1 to 4)", -1 }, /* But not errors */ + /* 0*/ { BARCODE_CODE128, -1, "1234", -1, -1, 3, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", -1 }, + /* 1*/ { BARCODE_CODE128, -1, "1234", -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, "", -1 }, /* Silently ignore rows < 0 */ + /* 2*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 3, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", -1 }, + /* 3*/ { BARCODE_QRCODE, -1, "1234", -1, -1, 999999 + 1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 218: ECI code '1000000' out of range (0 to 999999, excluding 1, 2, 14 and 19)", -1 }, + /* 4*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 0.009, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 227: Scale out of range (0.01 to 200)", -1 }, + /* 5*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 200.01, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 227: Scale out of range (0.01 to 200)", -1 }, + /* 6*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, -1, 20.1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Dot size out of range (0.01 to 20)", -1 }, + /* 7*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 0, 0.01, 0.009, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Dot size out of range (0.01 to 20)", -1 }, + /* 8*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, -0.1, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 765: Height out of range (0 to 2000)", -1 }, + /* 9*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 2000.01, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 765: Height out of range (0 to 2000)", -1 }, + /* 10*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 766: Whitespace width out of range (0 to 100)", -1 }, + /* 11*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 101, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 766: Whitespace width out of range (0 to 100)", -1 }, + /* 12*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 767: Whitespace height out of range (0 to 100)", -1 }, + /* 13*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 101, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 767: Whitespace height out of range (0 to 100)", -1 }, + /* 14*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, -1, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 768: Border width out of range (0 to 100)", -1 }, + /* 15*/ { BARCODE_CODE128, -1, "1234", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 768: Border width out of range (0 to 100)", -1 }, + /* 16*/ { BARCODE_CODE128, -1, "1234", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 220: Selected symbology does not support GS1 mode", -1 }, + /* 17*/ { BARCODE_EAN13, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, -5.1, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 219: Text gap out of range (-5 to 10)", -1 }, + /* 18*/ { BARCODE_EANX, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, -5.1, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 219: Text gap out of range (-5 to 10)", -1 }, + /* 19*/ { BARCODE_EAN13, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 10.1, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 219: Text gap out of range (-5 to 10)", -1 }, + /* 20*/ { BARCODE_EANX, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 10.1, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 219: Text gap out of range (-5 to 10)", -1 }, + /* 21*/ { BARCODE_EAN13, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, -0.5, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 769: Guard bar descent out of range (0 to 50)", -1 }, + /* 22*/ { BARCODE_EANX, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, -0.5, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 769: Guard bar descent out of range (0 to 50)", -1 }, + /* 23*/ { BARCODE_EAN13, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, 50.1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 769: Guard bar descent out of range (0 to 50)", -1 }, + /* 24*/ { BARCODE_EANX, -1, "123456789012", -1, -1, -1, 0, 0, 0, 101, -1, -1, 0, 50.1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 769: Guard bar descent out of range (0 to 50)", -1 }, + /* 25*/ { BARCODE_GS1_128, -1, "[21]12\0004", 8, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_DATA, "Error 262: NUL characters not permitted in GS1 mode", -1 }, + /* 26*/ { BARCODE_GS1_128, -1, "[21]12é4", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_DATA, "Error 250: Extended ASCII characters are not supported by GS1", -1 }, + /* 27*/ { BARCODE_GS1_128, -1, "[21]12\0074", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_DATA, "Error 251: Control characters are not supported by GS1", -1 }, + /* 28*/ { BARCODE_GS1_128, -1, "[21]1234", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", -1 }, + /* 29*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /* 30*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /* 31*/ { 0, -1, "1", -1, -1, 1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", BARCODE_CODE128 }, /* Not supporting beats invalid ECI */ + /* 32*/ { 0, -1, "1", -1, -1, 1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /* 33*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, 0.009, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 221: Dot size out of range (0.01 to 20)", BARCODE_CODE128 }, + /* 34*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, 0.009, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /* 35*/ { 0, -1, "1", -1, -1, 1, 0, 0, 0, 0, -1, 0.009, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 217: Symbology does not support ECI switching", BARCODE_CODE128 }, /* Invalid dot size no longer beats invalid ECI */ + /* 36*/ { 0, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, 0.009, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /* 37*/ { 5, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_C25STANDARD }, + /* 38*/ { 5, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_C25STANDARD }, + /* 39*/ { 17, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_UPCA }, + /* 40*/ { 17, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_UPCA }, + /* 41*/ { 19, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_TOO_LONG, "Error 362: Input length 1 too short (minimum 3)", BARCODE_CODABAR }, + /* 42*/ { 19, -1, "A1B", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 207: Codabar 18 not supported", BARCODE_CODABAR }, + /* 43*/ { 19, -1, "A1B", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 207: Codabar 18 not supported", -1 }, + /* 44*/ { 26, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_UPCA }, + /* 45*/ { 26, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_UPCA }, + /* 46*/ { 27, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_OPTION, "Error 208: UPCD1 not supported", 27 }, + /* 47*/ { 33, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI", BARCODE_GS1_128 }, + /* 48*/ { 33, -1, "[10]23", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_GS1_128 }, + /* 49*/ { 33, -1, "[10]23", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_GS1_128 }, + /* 50*/ { 36, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_UPCA }, + /* 51*/ { 36, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_UPCA }, + /* 52*/ { 39, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_UPCE }, + /* 53*/ { 39, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_UPCE }, + /* 54*/ { 41, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_NONCOMPLIANT, "Warning 479: Input length 1 is not standard (should be 5, 9 or 11 digits)", BARCODE_POSTNET }, + /* 55*/ { 41, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_POSTNET }, + /* 56*/ { 41, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, + /* 57*/ { 42, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_POSTNET }, + /* 58*/ { 42, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, + /* 59*/ { 43, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_POSTNET }, + /* 60*/ { 43, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, + /* 61*/ { 44, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_POSTNET }, + /* 62*/ { 44, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, + /* 63*/ { 45, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_POSTNET }, + /* 64*/ { 45, -1, "12345", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_POSTNET }, + /* 65*/ { 46, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_PLESSEY }, + /* 66*/ { 46, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_PLESSEY }, + /* 67*/ { 48, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_NVE18 }, + /* 68*/ { 48, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_NVE18 }, + /* 69*/ { 59, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_CODE128 }, + /* 70*/ { 59, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_CODE128 }, + /* 71*/ { 61, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_CODE128 }, + /* 72*/ { 61, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_CODE128 }, + /* 73*/ { 62, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_CODE93 }, + /* 74*/ { 62, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_CODE93 }, + /* 75*/ { 64, -1, "12345678", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_AUSPOST }, + /* 76*/ { 64, -1, "12345678", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_AUSPOST }, + /* 77*/ { 65, -1, "12345678", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_AUSPOST }, + /* 78*/ { 65, -1, "12345678", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_AUSPOST }, + /* 79*/ { 78, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_DBAR_OMN }, + /* 80*/ { 78, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_DBAR_OMN }, + /* 81*/ { 83, -1, "12345678901", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_PLANET }, + /* 82*/ { 83, -1, "12345678901", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_PLANET }, + /* 83*/ { 88, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_DATA, "Error 252: Data does not start with an AI", BARCODE_GS1_128 }, + /* 84*/ { 88, -1, "[10]12", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_GS1_128 }, + /* 85*/ { 88, -1, "[10]12", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_GS1_128 }, + /* 86*/ { 91, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /* 87*/ { 91, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /* 88*/ { 94, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /* 89*/ { 94, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /* 90*/ { 95, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /* 91*/ { 95, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /* 92*/ { 100, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_HIBC_128 }, + /* 93*/ { 100, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_128 }, + /* 94*/ { 101, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_HIBC_39 }, + /* 95*/ { 101, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_39 }, + /* 96*/ { 103, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_HIBC_DM }, + /* 97*/ { 103, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_DM }, + /* 98*/ { 105, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_HIBC_QR }, + /* 99*/ { 105, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_QR }, + /*100*/ { 107, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_HIBC_PDF }, + /*101*/ { 107, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_PDF }, + /*102*/ { 109, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_HIBC_MICPDF }, + /*103*/ { 109, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_MICPDF }, + /*104*/ { 111, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", BARCODE_HIBC_BLOCKF }, + /*105*/ { 111, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, 0, "", BARCODE_HIBC_BLOCKF }, + /*106*/ { 113, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*107*/ { 113, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*108*/ { 114, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*109*/ { 114, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*110*/ { 117, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*111*/ { 117, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*112*/ { 118, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*113*/ { 118, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*114*/ { 122, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*115*/ { 122, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*116*/ { 123, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*117*/ { 123, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*118*/ { 124, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*119*/ { 124, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*120*/ { 125, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*121*/ { 125, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*122*/ { 126, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*123*/ { 126, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*124*/ { 127, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*125*/ { 127, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*126*/ { 150, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*127*/ { 150, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*128*/ { BARCODE_LAST + 1, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 206: Symbology out of range", BARCODE_CODE128 }, + /*129*/ { BARCODE_LAST + 1, -1, "1", -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 206: Symbology out of range", -1 }, + /*130*/ { BARCODE_CODE128, -1, "\200", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_DATA, "Error 215: Invalid UTF-8 in input", -1 }, + /*131*/ { BARCODE_CODE128, -1, "\\o200", -1, UNICODE_MODE | ESCAPE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_DATA, "Error 215: Invalid UTF-8 in input", -1 }, + /*132*/ { BARCODE_MAXICODE, -1, "\200", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_DATA, "Error 215: Invalid UTF-8 in input", -1 }, + /*133*/ { BARCODE_MAXICODE, -1, "\\o200", -1, UNICODE_MODE | ESCAPE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_ERROR_INVALID_DATA, "Error 215: Invalid UTF-8 in input", -1 }, + /*134*/ { BARCODE_GS1_128, -1, "[01]12345678901234", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_NONCOMPLIANT, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'", -1 }, + /*135*/ { BARCODE_GS1_128, -1, "[01]12345678901234", -1, GS1_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_NONCOMPLIANT, "Error 261: AI (01) data position 14: Bad checksum '4', expected '1'", -1 }, + /*136*/ { BARCODE_QRCODE, -1, "ก", -1, UNICODE_MODE, 13, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", -1 }, + /*137*/ { BARCODE_QRCODE, -1, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_USES_ECI, "Warning 222: Encoded data includes ECI 13", -1 }, + /*138*/ { BARCODE_QRCODE, -1, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_USES_ECI, "Error 222: Encoded data includes ECI 13", -1 }, + /*139*/ { BARCODE_CODEONE, -1, "[01]12345678901231", -1, GS1_MODE, 3, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 512: ECI ignored for GS1 mode", -1 }, + /*140*/ { BARCODE_CODEONE, -1, "[01]12345678901231", -1, GS1_MODE, 3, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 512: ECI ignored for GS1 mode", -1 }, + /*141*/ { BARCODE_CODEONE, -1, "[01]12345678901234", -1, GS1_MODE, 3, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 512: ECI ignored for GS1 mode", -1 }, /* Warning in encoder overrides library warnings */ + /*142*/ { BARCODE_CODEONE, -1, "[01]12345678901234", -1, GS1_MODE, 3, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_NONCOMPLIANT, "Error 261: AI (01) data position 14: Bad checksum '4', expected '1'", -1 }, /* But not errors */ + /*143*/ { BARCODE_AZTEC, -1, "ก", -1, UNICODE_MODE, 13, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, 0, "", -1 }, + /*144*/ { BARCODE_AZTEC, -1, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_USES_ECI, "Warning 222: Encoded data includes ECI 13", -1 }, + /*145*/ { BARCODE_AZTEC, -1, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_USES_ECI, "Error 222: Encoded data includes ECI 13", -1 }, + /*146*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, 13, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_INVALID_OPTION, "Warning 503: Error correction level '6' out of range (1 to 4), ignoring", -1 }, + /*147*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, 13, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 503: Error correction level '6' out of range (1 to 4)", -1 }, + /*148*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, -1, ZINT_WARN_USES_ECI, "Warning 222: Encoded data includes ECI 13", -1 }, /* ECI warning trumps all other warnings */ + /*149*/ { BARCODE_AZTEC, 6, "ก", -1, UNICODE_MODE, -1, 0, 0, 0, 0, -1, -1, 0, -1, 0, WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, "Error 503: Error correction level '6' out of range (1 to 4)", -1 }, /* But not errors */ }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -252,6 +253,9 @@ static void test_checks(const testCtx *const p_ctx) { if (data[i].guard_descent != -1) { symbol->guard_descent = data[i].guard_descent; } + if (data[i].rows) { + symbol->rows = data[i].rows; + } if (data[i].warn_level != -1) { symbol->warn_level = data[i].warn_level; } @@ -326,7 +330,9 @@ static void test_checks_segs(const testCtx *const p_ctx) { testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, data[i].option_1, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, - NULL, 0, debug); + NULL, 0, + /* Avoid OOB on printing non-existing data in `z_debug_print_escape()` */ + data[i].segs[0].length < ZINT_MAX_DATA_LEN ? debug : 0); if (data[i].warn_level != -1) { symbol->warn_level = data[i].warn_level; } @@ -645,6 +651,7 @@ static void test_input_mode(const testCtx *const p_ctx) { int input_mode; int eci; const char *data; + int warn_level; int ret; int expected_input_mode; @@ -652,27 +659,28 @@ static void test_input_mode(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { DATA_MODE, -1, "1234", 0, DATA_MODE, "" }, - /* 1*/ { DATA_MODE | ESCAPE_MODE, -1, "1234", 0, DATA_MODE | ESCAPE_MODE, "" }, - /* 2*/ { UNICODE_MODE, -1, "1234", 0, UNICODE_MODE, "" }, - /* 3*/ { UNICODE_MODE | ESCAPE_MODE, -1, "1234", 0, UNICODE_MODE | ESCAPE_MODE, "" }, - /* 4*/ { GS1_MODE, -1, "[01]12345678901231", 0, GS1_MODE, "" }, - /* 5*/ { GS1_MODE | ESCAPE_MODE, -1, "[01]12345678901231", 0, GS1_MODE | ESCAPE_MODE, "" }, - /* 6*/ { 4 | ESCAPE_MODE, -1, "1234", ZINT_WARN_INVALID_OPTION, DATA_MODE, "Warning 212: Invalid input mode - reset to DATA_MODE" }, /* Unknown mode reset to bare DATA_MODE. Note: now warns */ - /* 7*/ { -1, -1, "1234", 0, DATA_MODE, "" }, - /* 8*/ { DATA_MODE | 0x10, -1, "1234", 0, DATA_MODE | 0x10, "" }, /* Unknown flags kept (but ignored) */ - /* 9*/ { UNICODE_MODE | 0x10, -1, "1234", 0, UNICODE_MODE | 0x10, "" }, - /* 10*/ { GS1_MODE | 0x20, -1, "[01]12345678901231", 0, GS1_MODE | 0x20, "" }, - /* 11*/ { GS1_MODE, 3, "[01]12345678901231", 0, GS1_MODE, "" }, - /* 12*/ { GS1_MODE, 20, "[01]12345678901231", 0, GS1_MODE, "" }, /* Shift JIS (ok as backslash not in CSET82) */ - /* 12*/ { GS1_MODE, 24, "[01]12345678901231", 0, GS1_MODE, "" }, /* Windows 1256 - Arabic */ - /* 13*/ { GS1_MODE, 25, "[01]12345678901231", ZINT_ERROR_INVALID_OPTION, GS1_MODE, "Error 856: In GS1 mode ECI must be ASCII compatible" }, /* UTF-16BE */ - /* 12*/ { GS1_MODE, 26, "[01]12345678901231", 0, GS1_MODE, "" }, /* UTF-8*/ - /* 12*/ { GS1_MODE, 32, "[01]12345678901231", 0, GS1_MODE, "" }, /* GB 18030 */ - /* 14*/ { GS1_MODE, 33, "[01]12345678901231", ZINT_ERROR_INVALID_OPTION, GS1_MODE, "Error 856: In GS1 mode ECI must be ASCII compatible" }, /* UTF-16LE */ - /* 15*/ { GS1_MODE, 34, "[01]12345678901231", ZINT_ERROR_INVALID_OPTION, GS1_MODE, "Error 856: In GS1 mode ECI must be ASCII compatible" }, /* UTF-32BE */ - /* 16*/ { GS1_MODE, 35, "[01]12345678901231", ZINT_ERROR_INVALID_OPTION, GS1_MODE, "Error 856: In GS1 mode ECI must be ASCII compatible" }, /* UTF-32LE */ - /* 17*/ { GS1_MODE, 170, "[01]12345678901231", 0, GS1_MODE, "" }, /* ASCII Invariant */ + /* 0*/ { DATA_MODE, -1, "1234", -1, 0, DATA_MODE, "" }, + /* 1*/ { DATA_MODE | ESCAPE_MODE, -1, "1234", -1, 0, DATA_MODE | ESCAPE_MODE, "" }, + /* 2*/ { UNICODE_MODE, -1, "1234", -1, 0, UNICODE_MODE, "" }, + /* 3*/ { UNICODE_MODE | ESCAPE_MODE, -1, "1234", -1, 0, UNICODE_MODE | ESCAPE_MODE, "" }, + /* 4*/ { GS1_MODE, -1, "[01]12345678901231", -1, 0, GS1_MODE, "" }, + /* 5*/ { GS1_MODE | ESCAPE_MODE, -1, "[01]12345678901231", -1, 0, GS1_MODE | ESCAPE_MODE, "" }, + /* 6*/ { 4 | ESCAPE_MODE, -1, "1234", -1, ZINT_WARN_INVALID_OPTION, DATA_MODE, "Warning 212: Invalid input mode - reset to DATA_MODE" }, /* Unknown mode reset to bare DATA_MODE. Note: now warns */ + /* 7*/ { 4 | ESCAPE_MODE, -1, "1234", WARN_FAIL_ALL, ZINT_ERROR_INVALID_OPTION, DATA_MODE, "Error 212: Invalid input mode - reset to DATA_MODE" }, + /* 8*/ { -1, -1, "1234", -1, 0, DATA_MODE, "" }, + /* 9*/ { DATA_MODE | 0x10, -1, "1234", -1, 0, DATA_MODE | 0x10, "" }, /* Unknown flags kept (but ignored) */ + /* 10*/ { UNICODE_MODE | 0x10, -1, "1234", -1, 0, UNICODE_MODE | 0x10, "" }, + /* 11*/ { GS1_MODE | 0x20, -1, "[01]12345678901231", -1, 0, GS1_MODE | 0x20, "" }, + /* 12*/ { GS1_MODE, 3, "[01]12345678901231", -1, 0, GS1_MODE, "" }, + /* 13*/ { GS1_MODE, 20, "[01]12345678901231", -1, 0, GS1_MODE, "" }, /* Shift JIS (ok as backslash not in CSET82) */ + /* 14*/ { GS1_MODE, 24, "[01]12345678901231", -1, 0, GS1_MODE, "" }, /* Windows 1256 - Arabic */ + /* 15*/ { GS1_MODE, 25, "[01]12345678901231", -1, ZINT_ERROR_INVALID_OPTION, GS1_MODE, "Error 856: In GS1 mode ECI must be ASCII compatible" }, /* UTF-16BE */ + /* 16*/ { GS1_MODE, 26, "[01]12345678901231", -1, 0, GS1_MODE, "" }, /* UTF-8*/ + /* 17*/ { GS1_MODE, 32, "[01]12345678901231", -1, 0, GS1_MODE, "" }, /* GB 18030 */ + /* 18*/ { GS1_MODE, 33, "[01]12345678901231", -1, ZINT_ERROR_INVALID_OPTION, GS1_MODE, "Error 856: In GS1 mode ECI must be ASCII compatible" }, /* UTF-16LE */ + /* 19*/ { GS1_MODE, 34, "[01]12345678901231", -1, ZINT_ERROR_INVALID_OPTION, GS1_MODE, "Error 856: In GS1 mode ECI must be ASCII compatible" }, /* UTF-32BE */ + /* 20*/ { GS1_MODE, 35, "[01]12345678901231", -1, ZINT_ERROR_INVALID_OPTION, GS1_MODE, "Error 856: In GS1 mode ECI must be ASCII compatible" }, /* UTF-32LE */ + /* 21*/ { GS1_MODE, 170, "[01]12345678901231", -1, 0, GS1_MODE, "" }, /* ASCII Invariant */ }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -692,6 +700,9 @@ static void test_input_mode(const testCtx *const p_ctx) { length = testUtilSetSymbol(symbol, symbology, data[i].input_mode, data[i].eci, -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/, data[i].data, -1, debug); + if (data[i].warn_level != -1) { + symbol->warn_level = data[i].warn_level; + } ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", @@ -835,34 +846,37 @@ static void test_escape_char_process(const testCtx *const p_ctx) { /*109*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 35, "\\U10FFFF", "", 0, 14, "F1 24 EB 80 EB 80 11 01 17 BA C6 05 9F 4C EA E5 18 31", 0, "" }, /*110*/ { BARCODE_GS1_128_CC, GS1_MODE, -1, "[20]10", "[10]A", 0, 99, "(7) 105 102 20 10 100 59 106", 0, "" }, /*111*/ { BARCODE_GS1_128_CC, GS1_MODE, -1, "[2\\x30]1\\d048", "[\\x310]\\x41", 0, 99, "(7) 105 102 20 10 100 59 106", 1, "" }, - /*112*/ { BARCODE_AZTEC, DATA_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, - /*113*/ { BARCODE_AZTEC, GS1_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, - /*114*/ { BARCODE_AZTEC, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\^11", "", 0, 15, "(102) 31 31 30 30 31 31 30 31 31 31 30 30 31 31 30 30 31 31 30 31 30 30 31 30 30 30 30 30", 0, "" }, - /*115*/ { BARCODE_AZTEC, DATA_MODE, -1, "\\\\^11", "", 0, 15, "(102) 30 31 31 30 31 31 31 30 31 31 30 30 31 31 31 31 30 31 31 30 31 31 30 30 31 31 31 31", 0, "Note double-backslash caret passed thru as backslash caret but does not error in non-EXTRA_ESCAPE_MODE, treated literally" }, - /*116*/ { BARCODE_AZTEC, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^11", "", 0, 15, "(102) 31 31 30 30 31 31 30 31 31 31 30 30 31 31 30 30 31 31 30 31 30 30 31 30 30 30 30 30", 0, "Treated as backslash caret 1 (FNC1)" }, - /*117*/ { BARCODE_AZTEC, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^A1", "", ZINT_ERROR_INVALID_DATA, 0, "Error 717: Unrecognized extra escape \"\\^A\"", 0, "" }, - /*118*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, - /*119*/ { BARCODE_DATAMATRIX, GS1_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, - /*120*/ { BARCODE_DATAMATRIX, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\^11", "", 0, 10, "E8 32 81 98 94 7B 7F 6D", 0, "" }, - /*121*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, -1, "\\^A1", "", ZINT_ERROR_INVALID_DATA, 0, "Error 717: Unrecognized extra escape \"\\^A\"", 0, "" }, - /*122*/ { BARCODE_DATAMATRIX, GS1_MODE | EXTRA_ESCAPE_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 213: Extra escape '\\^' not valid for this symbology and/or input mode", 0, "Not allowed of DATAMATRIX in GS1_MODE" }, - /*123*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\\\^11", "", 0, 10, "5D 5F 8D 5C FB D1 69 3F", 0, "Note double-backslash caret passed thru as backslash caret but does not error in non-EXTRA_ESCAPE_MODE, treated literally" }, - /*124*/ { BARCODE_DATAMATRIX, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^11", "", 0, 10, "E8 32 81 98 94 7B 7F 6D", 0, "Treated as backslash caret 1 (FNC1)" }, - /*125*/ { BARCODE_DATAMATRIX, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^B2", "", ZINT_ERROR_INVALID_DATA, 0, "Error 717: Unrecognized extra escape \"\\^B\"", 0, "Passed thru as backslash caret B" }, - /*126*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 18, "A\\^1B", "", 0, 12, "42 E8 F1 13 43 F5 A4 26 80 68 7A AD", 0, "" }, - /*127*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 20, "A\\^1B", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, - /*128*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 20, "バ\\^1ーコ\\^1ード\\^1東京\\^1都", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, - /*129*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 25, "A\\^1B", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, - /*130*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 33, "A\\^1B", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, - /*131*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 170, "A\\^1B", "", ZINT_ERROR_INVALID_DATA, 0, "Error 244: Invalid character in input for ECI '170'", 0, "" }, - /*132*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 899, "A\\^1B", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, - /*133*/ { BARCODE_CODE128, DATA_MODE, -1, "\\^A1", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, - /*134*/ { BARCODE_CODE128, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\^A1", "", 0, 46, "(4) 103 17 17 106", 0, "" }, - /*135*/ { BARCODE_CODE128, EXTRA_ESCAPE_MODE, -1, "\\^", "", 0, 57, "(5) 104 60 62 82 106", 0, "Partial special escape '\\^' at end allowed" }, - /*136*/ { BARCODE_CODE128, EXTRA_ESCAPE_MODE, -1, "\\^D1", "", ZINT_ERROR_INVALID_DATA, 0, "Error 348: Unrecognized extra escape \"\\^D\"", 0, "" }, - /*137*/ { BARCODE_CODE128, DATA_MODE, -1, "\\\\^A1", "", 0, 79, "(7) 104 60 62 33 17 43 106", 0, "Treated as literal backslash caret A" }, - /*138*/ { BARCODE_CODE128, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^A1", "", 0, 46, "(4) 103 17 17 106", 0, "Treated as backslash caret A (manual Code Set A)" }, - /*139*/ { BARCODE_CODE128, DATA_MODE, -1, "\\c", "", ZINT_ERROR_INVALID_DATA, 0, "Error 234: Unrecognised escape character '\\c' in input", 0, "" }, + /*112*/ { BARCODE_GS1_128_CC, GS1_MODE | GS1PARENS_MODE, -1, "(90)\\(\\)", "(10)A", 0, 101, "(9) 105 102 90 100 8 9 101 31 106", 0, "" }, + /*113*/ { BARCODE_GS1_128_CC, GS1_MODE, -1, "[90]\\(\\)", "[10]A", ZINT_ERROR_INVALID_DATA, 0, "Error 853: Escaped parentheses only valid in GS1 mode with GS1 parentheses flag", 0, "" }, + /*114*/ { BARCODE_GS1_128_CC, GS1_MODE, -1, "[10]A", "[90]\\(\\)", ZINT_ERROR_INVALID_DATA, 0, "Error 853: Escaped parentheses only valid in GS1 mode with GS1 parentheses flag", 0, "" }, + /*115*/ { BARCODE_AZTEC, DATA_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, + /*116*/ { BARCODE_AZTEC, GS1_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, + /*117*/ { BARCODE_AZTEC, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\^11", "", 0, 15, "(102) 31 31 30 30 31 31 30 31 31 31 30 30 31 31 30 30 31 31 30 31 30 30 31 30 30 30 30 30", 0, "" }, + /*118*/ { BARCODE_AZTEC, DATA_MODE, -1, "\\\\^11", "", 0, 15, "(102) 30 31 31 30 31 31 31 30 31 31 30 30 31 31 31 31 30 31 31 30 31 31 30 30 31 31 31 31", 0, "Note double-backslash caret passed thru as backslash caret but does not error in non-EXTRA_ESCAPE_MODE, treated literally" }, + /*119*/ { BARCODE_AZTEC, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^11", "", 0, 15, "(102) 31 31 30 30 31 31 30 31 31 31 30 30 31 31 30 30 31 31 30 31 30 30 31 30 30 30 30 30", 0, "Treated as backslash caret 1 (FNC1)" }, + /*120*/ { BARCODE_AZTEC, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^A1", "", ZINT_ERROR_INVALID_DATA, 0, "Error 717: Unrecognized extra escape \"\\^A\"", 0, "" }, + /*121*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, + /*122*/ { BARCODE_DATAMATRIX, GS1_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, + /*123*/ { BARCODE_DATAMATRIX, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\^11", "", 0, 10, "E8 32 81 98 94 7B 7F 6D", 0, "" }, + /*124*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, -1, "\\^A1", "", ZINT_ERROR_INVALID_DATA, 0, "Error 717: Unrecognized extra escape \"\\^A\"", 0, "" }, + /*125*/ { BARCODE_DATAMATRIX, GS1_MODE | EXTRA_ESCAPE_MODE, -1, "\\^11", "", ZINT_ERROR_INVALID_DATA, 0, "Error 213: Extra escape '\\^' not valid for this symbology and/or input mode", 0, "Not allowed of DATAMATRIX in GS1_MODE" }, + /*126*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, "\\\\^11", "", 0, 10, "5D 5F 8D 5C FB D1 69 3F", 0, "Note double-backslash caret passed thru as backslash caret but does not error in non-EXTRA_ESCAPE_MODE, treated literally" }, + /*127*/ { BARCODE_DATAMATRIX, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^11", "", 0, 10, "E8 32 81 98 94 7B 7F 6D", 0, "Treated as backslash caret 1 (FNC1)" }, + /*128*/ { BARCODE_DATAMATRIX, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^B2", "", ZINT_ERROR_INVALID_DATA, 0, "Error 717: Unrecognized extra escape \"\\^B\"", 0, "Passed thru as backslash caret B" }, + /*129*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 18, "A\\^1B", "", 0, 12, "42 E8 F1 13 43 F5 A4 26 80 68 7A AD", 0, "" }, + /*130*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 20, "A\\^1B", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, + /*131*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 20, "バ\\^1ーコ\\^1ード\\^1東京\\^1都", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, + /*132*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 25, "A\\^1B", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, + /*133*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 33, "A\\^1B", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, + /*134*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 170, "A\\^1B", "", ZINT_ERROR_INVALID_DATA, 0, "Error 244: Invalid character in input for ECI '170'", 0, "" }, + /*135*/ { BARCODE_DATAMATRIX, UNICODE_MODE | EXTRA_ESCAPE_MODE, 899, "A\\^1B", "", ZINT_ERROR_INVALID_OPTION, 0, "Error 716: Extra Escape mode requires ASCII-compatible ECI", 0, "" }, + /*136*/ { BARCODE_CODE128, DATA_MODE, -1, "\\^A1", "", ZINT_ERROR_INVALID_DATA, 0, "Error 798: Escape '\\^' only valid in Extra Escape mode", 0, "" }, + /*137*/ { BARCODE_CODE128, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\^A1", "", 0, 46, "(4) 103 17 17 106", 0, "" }, + /*138*/ { BARCODE_CODE128, EXTRA_ESCAPE_MODE, -1, "\\^", "", 0, 57, "(5) 104 60 62 82 106", 0, "Partial special escape '\\^' at end allowed" }, + /*139*/ { BARCODE_CODE128, EXTRA_ESCAPE_MODE, -1, "\\^D1", "", ZINT_ERROR_INVALID_DATA, 0, "Error 348: Unrecognized extra escape \"\\^D\"", 0, "" }, + /*140*/ { BARCODE_CODE128, DATA_MODE, -1, "\\\\^A1", "", 0, 79, "(7) 104 60 62 33 17 43 106", 0, "Treated as literal backslash caret A" }, + /*141*/ { BARCODE_CODE128, DATA_MODE | EXTRA_ESCAPE_MODE, -1, "\\\\^A1", "", 0, 46, "(4) 103 17 17 106", 0, "Treated as backslash caret A (manual Code Set A)" }, + /*142*/ { BARCODE_CODE128, DATA_MODE, -1, "\\c", "", ZINT_ERROR_INVALID_DATA, 0, "Error 234: Unrecognised escape character '\\c' in input", 0, "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1044,12 +1058,12 @@ static void test_cap(const testCtx *const p_ctx) { /* 1*/ { BARCODE_CODE128, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_GS1 | ZINT_CAP_BINDABLE, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_BINDABLE }, /* 2*/ { BARCODE_PDF417, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_BINDABLE, ZINT_CAP_ECI | ZINT_CAP_READER_INIT }, /* 3*/ { BARCODE_QRCODE, ZINT_CAP_HRT | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK | ZINT_CAP_STRUCTAPP | ZINT_CAP_COMPLIANT_HEIGHT, ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK | ZINT_CAP_STRUCTAPP }, - /* 4*/ { BARCODE_EAN8_CC, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT }, - /* 5*/ { BARCODE_EANX_CC, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT }, - /* 6*/ { BARCODE_EAN13_CC, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EXTENDABLE | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT }, + /* 4*/ { BARCODE_EAN8_CC, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EANUPC | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EANUPC | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT }, + /* 5*/ { BARCODE_EANX_CC, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EANUPC | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EANUPC | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT }, + /* 6*/ { BARCODE_EAN13_CC, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EANUPC | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT, ZINT_CAP_HRT | ZINT_CAP_COMPOSITE | ZINT_CAP_EANUPC | ZINT_CAP_GS1 | ZINT_CAP_QUIET_ZONES | ZINT_CAP_COMPLIANT_HEIGHT }, /* 7*/ { BARCODE_HANXIN, ZINT_CAP_DOTTY | ZINT_CAP_QUIET_ZONES | ZINT_CAP_FIXED_RATIO | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK, ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK }, /* 8*/ { BARCODE_CODE11, ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_FIXED_RATIO | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_COMPLIANT_HEIGHT, 0 }, - /* 9*/ { BARCODE_POSTNET, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_EXTENDABLE | ZINT_CAP_COMPOSITE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK | ZINT_CAP_STRUCTAPP | ZINT_CAP_BINDABLE, 0 }, + /* 9*/ { BARCODE_POSTNET, ZINT_CAP_HRT | ZINT_CAP_STACKABLE | ZINT_CAP_EANUPC | ZINT_CAP_COMPOSITE | ZINT_CAP_ECI | ZINT_CAP_GS1 | ZINT_CAP_DOTTY | ZINT_CAP_FIXED_RATIO | ZINT_CAP_READER_INIT | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK | ZINT_CAP_STRUCTAPP | ZINT_CAP_BINDABLE, 0 }, /* 10*/ { 0, 0, 0 }, }; const int data_size = ARRAY_SIZE(data); @@ -1058,6 +1072,8 @@ static void test_cap(const testCtx *const p_ctx) { testStart(p_ctx->func_name); + assert_equal(ZINT_CAP_EXTENDABLE, ZINT_CAP_EANUPC, "0x%X != 0x%X\n", ZINT_CAP_EXTENDABLE, ZINT_CAP_EANUPC); + for (i = 0; i < data_size; i++) { if (testContinue(p_ctx, i)) continue; @@ -2632,6 +2648,50 @@ static void test_reset(const testCtx *const p_ctx) { testFinish(); } +static void test_default_xdim(const testCtx *const p_ctx) { + + struct item { + int symbology; + float expected; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_AUSPOST, 0.5f }, + /* 1*/ { BARCODE_CEPNET, 0.591f }, + /* 2*/ { BARCODE_RM4SCC, 0.638f }, + /* 3*/ { BARCODE_JAPANPOST, 0.6f }, + /* 4*/ { BARCODE_DXFILMEDGE, 0.403548f }, + /* 5*/ { BARCODE_BC412, 0.12f }, + /* 6*/ { BARCODE_CODABAR, 0.38f }, + /* 7*/ { BARCODE_CODE32, 0.25f }, + /* 8*/ { BARCODE_DPD, 0.375f }, + /* 9*/ { BARCODE_FIM, 0.79375f }, + /* 10*/ { BARCODE_LOGMARS, 0.34925f }, + /* 11*/ { BARCODE_MAILMARK_2D, 0.5f }, + /* 12*/ { BARCODE_PHARMA, 0.5f }, + /* 13*/ { BARCODE_PHARMA_TWO, 1.0f }, + /* 14*/ { BARCODE_PZN, 0.25f }, + /* 15*/ { BARCODE_CODE16K, 0.33f }, + /* 16*/ { BARCODE_LAST + 1, 0.0f }, + }; + const int data_size = ARRAY_SIZE(data); + int i; + float ret; + + testStart(p_ctx->func_name); + + for (i = 0; i < data_size; i++) { + + if (testContinue(p_ctx, i)) continue; + + ret = ZBarcode_Default_Xdim(data[i].symbology); + assert_equal(ret, data[i].expected, "i:%d ZBarcode_Default_Xdim(%s) %.8g != %.8g\n", + i, testUtilBarcodeName(data[i].symbology), ret, data[i].expected); + } + + testFinish(); +} + static void test_scale_from_xdimdp(const testCtx *const p_ctx) { struct item { @@ -2706,34 +2766,40 @@ static void test_scale_from_xdimdp(const testCtx *const p_ctx) { /* 59*/ { BARCODE_MAXICODE, 0.88f, 378, 9600, "gif", 33.264f }, /* 60*/ { BARCODE_MAXICODE, 0.88f, 378, 9600, "emf", 8.316f }, /* 61*/ { BARCODE_MAXICODE, 0.88f, 378, 9600, "svg", 166.31999f }, - /* 62*/ { BARCODE_PDF417, 0.27f, 2, 50, "gif", 0.5f }, - /* 63*/ { BARCODE_PDF417, 0.27f, 2, 50, "svg", 0.27000001f }, - /* 64*/ { BARCODE_PDF417, 0.27f, 6, 150, "gif", 1 }, - /* 65*/ { BARCODE_PDF417, 0.27f, 6, 150, "svg", 0.81000006f }, - /* 66*/ { BARCODE_PDF417, 0.27f, 12, 300, "gif", 1.5 }, - /* 67*/ { BARCODE_PDF417, 0.27f, 12, 300, "svg", 1.6200001f }, - /* 68*/ { BARCODE_PDF417, 0.27f, 24, 600, "gif", 3 }, - /* 69*/ { BARCODE_PDF417, 0.27f, 24, 600, "emf", 3.2400002f }, - /* 70*/ { BARCODE_PDF417, 0.27f, 24, 600, "svg", 3.2400002f }, - /* 71*/ { BARCODE_PHARMA_TWO, 1, 2, 50, "gif", 1 }, - /* 72*/ { BARCODE_PHARMA_TWO, 1, 2, 50, "svg", 1 }, - /* 73*/ { BARCODE_PHARMA_TWO, 1, 6, 150, "gif", 3 }, - /* 74*/ { BARCODE_PHARMA_TWO, 1, 6, 150, "svg", 3 }, - /* 75*/ { BARCODE_PHARMA_TWO, 1, 8, 200, "gif", 4 }, - /* 76*/ { BARCODE_PHARMA_TWO, 1, 8, 200, "svg", 4 }, - /* 77*/ { BARCODE_PHARMA_TWO, 1, 189, 4800, "gif", 94.5f }, - /* 78*/ { BARCODE_PHARMA_TWO, 1, 189, 4800, "svg", 94.5f }, - /* 79*/ { BARCODE_PHARMA_TWO, 1, 378, 9600, "gif", 189 }, - /* 80*/ { BARCODE_PHARMA_TWO, 1, 378, 9600, "svg", 189 }, - /* 81*/ { BARCODE_PHARMA_TWO, 1, 401, 10200, "gif", 200 }, /* NOTE scale capped to 200 so doesn't round trip */ - /* 82*/ { BARCODE_PHARMA_TWO, 1, 401, 10200, "svg", 200 }, - /* 83*/ { BARCODE_CODE128, 0.5, 12, 300, "gif", 3 }, - /* 84*/ { BARCODE_CODE128, 0, 12, -1, "gif", 0 }, /* x_dim zero */ - /* 85*/ { BARCODE_CODE128, 200.1f, 12, -1, "gif", 0 }, /* x_dim > 200 */ - /* 86*/ { BARCODE_CODE128, 0.5f, -0.1f, -1, "gif", 0 }, /* dpmm neg */ - /* 87*/ { BARCODE_CODE128, 0.5f, 1000.1, -1, "gif", 0 }, /* dpmm > 1000 */ - /* 88*/ { BARCODE_CODE128, 0.5f, 300, -1, "abcd", 0 }, /* filetype unknown */ - /* 89*/ { BARCODE_QRCODE, 10, 31, 800, "gif", 155 }, + /* 62*/ { BARCODE_MAXICODE, 1.0f, 2, 24, "gif", 0.2f }, + /* 63*/ { BARCODE_PDF417, 0.27f, 2, 50, "gif", 0.5f }, + /* 64*/ { BARCODE_PDF417, 0.27f, 2, 50, "svg", 0.27000001f }, + /* 65*/ { BARCODE_PDF417, 0.27f, 6, 150, "gif", 1 }, + /* 66*/ { BARCODE_PDF417, 0.27f, 6, 150, "svg", 0.81000006f }, + /* 67*/ { BARCODE_PDF417, 0.27f, 12, 300, "gif", 1.5 }, + /* 68*/ { BARCODE_PDF417, 0.27f, 12, 300, "svg", 1.6200001f }, + /* 69*/ { BARCODE_PDF417, 0.27f, 24, 600, "gif", 3 }, + /* 70*/ { BARCODE_PDF417, 0.27f, 24, 600, "emf", 3.2400002f }, + /* 71*/ { BARCODE_PDF417, 0.27f, 24, 600, "svg", 3.2400002f }, + /* 72*/ { BARCODE_PHARMA_TWO, 1, 2, 50, "gif", 1 }, + /* 73*/ { BARCODE_PHARMA_TWO, 1, 2, 50, "svg", 1 }, + /* 74*/ { BARCODE_PHARMA_TWO, 1, 6, 150, "gif", 3 }, + /* 75*/ { BARCODE_PHARMA_TWO, 1, 6, 150, "svg", 3 }, + /* 76*/ { BARCODE_PHARMA_TWO, 1, 8, 200, "gif", 4 }, + /* 77*/ { BARCODE_PHARMA_TWO, 1, 8, 200, "svg", 4 }, + /* 78*/ { BARCODE_PHARMA_TWO, 1, 189, 4800, "gif", 94.5f }, + /* 79*/ { BARCODE_PHARMA_TWO, 1, 189, 4800, "svg", 94.5f }, + /* 80*/ { BARCODE_PHARMA_TWO, 1, 378, 9600, "gif", 189 }, + /* 81*/ { BARCODE_PHARMA_TWO, 1, 378, 9600, "svg", 189 }, + /* 82*/ { BARCODE_PHARMA_TWO, 1, 401, 10200, "gif", 200 }, /* NOTE scale capped to 200 so doesn't round trip */ + /* 83*/ { BARCODE_PHARMA_TWO, 1, 401, 10200, "svg", 200 }, + /* 84*/ { BARCODE_CODE128, 0.5f, 12, 300, "gif", 3 }, + /* 85*/ { BARCODE_CODE128, 0.5f, 0, 300, "gif", 3 }, + /* 86*/ { BARCODE_CODE128, 0.5f, 12, 300, "", 3 }, + /* 87*/ { BARCODE_CODE128, 0.5f, 2, 50, "", 0.5 }, + /* 88*/ { BARCODE_CODE128, 0.5f, 0.5f, 24, "gif", 0.5 }, + /* 89*/ { BARCODE_CODE128, 0, 12, -1, "gif", 0 }, /* x_dim zero */ + /* 90*/ { BARCODE_CODE128, 200.1f, 12, -1, "gif", 0 }, /* x_dim > 200 */ + /* 91*/ { BARCODE_CODE128, 0.5f, -0.1f, -1, "gif", 0 }, /* dpmm neg */ + /* 92*/ { BARCODE_CODE128, 0.5f, 1000.1, -1, "gif", 0 }, /* dpmm > 1000 */ + /* 93*/ { BARCODE_CODE128, 0.5f, 300, -1, "abcd", 0 }, /* filetype unknown */ + /* 94*/ { BARCODE_QRCODE, 10, 31, 800, "gif", 155 }, + /* 95*/ { BARCODE_LAST + 1, 0, 12, 300, "gif", 0 }, }; const int data_size = ARRAY_SIZE(data); int i; @@ -2756,8 +2822,8 @@ static void test_scale_from_xdimdp(const testCtx *const p_ctx) { dpmm_from_dpi = z_stripf(roundf(data[i].dpi / 25.4f)); ret = ZBarcode_Scale_From_XdimDp(data[i].symbology, data[i].x_dim, dpmm_from_dpi, data[i].filetype); assert_equal(ret, data[i].expected, - "i:%d ZBarcode_Scale_From_XdimDp(%s, %g (dpi %d), %g, %s) %.8g != %.8g\n", - i, testUtilBarcodeName(data[i].symbology), dpmm_from_dpi, data[i].dpi, data[i].x_dim, + "i:%d ZBarcode_Scale_From_XdimDp(%s, %g, %g (dpi %d), %s) %.8g != %.8g\n", + i, testUtilBarcodeName(data[i].symbology), data[i].x_dim, dpmm_from_dpi, data[i].dpi, data[i].filetype, ret, data[i].expected); if (data[i].expected > 0.1f && data[i].expected < 200.0f /* Can't round trip scales <= 0.1 or >= 200.0 */ @@ -2766,8 +2832,8 @@ static void test_scale_from_xdimdp(const testCtx *const p_ctx) { x_dim_from_scale = ZBarcode_XdimDp_From_Scale(data[i].symbology, ret, data[i].dpmm, data[i].filetype); x_dim_from_scale = z_stripf(z_stripf(roundf(x_dim_from_scale * 100.0f)) / 100.0f); assert_equal(x_dim_from_scale, data[i].x_dim, - "i:%d ZBarcode_XdimDp_From_Scale(%s, %g, %g, %s) %.8g != x_dim %.8g\n", - i, testUtilBarcodeName(data[i].symbology), ret, data[i].x_dim, data[i].filetype, + "i:%d ZBarcode_XdimDp_From_Scale(%s, %g, %g, \"%s\") %.8g != x_dim %.8g\n", + i, testUtilBarcodeName(data[i].symbology), ret, data[i].dpmm, data[i].filetype, x_dim_from_scale, data[i].x_dim); } } @@ -2817,6 +2883,8 @@ static void test_xdimdp_from_scale(const testCtx *const p_ctx) { /* 26*/ { BARCODE_CODE128, 200.01f, 12, -1, "gif", 0 }, /* scale > 200 */ /* 27*/ { BARCODE_CODE128, 0.5f, 0, -1, "gif", 0 }, /* xdim_mm_or_dpmm zero */ /* 28*/ { BARCODE_CODE128, 0.5f, 1000.1f, -1, "gif", 0 }, /* xdim_mm_or_dpmm > 1000 */ + /* 29*/ { BARCODE_CODE128, 1, 12, -1, "txt", 0 }, + /* 30*/ { BARCODE_LAST + 1, 1, 12, -1, "gif", 0 }, }; const int data_size = ARRAY_SIZE(data); int i; @@ -2838,8 +2906,8 @@ static void test_xdimdp_from_scale(const testCtx *const p_ctx) { dpmm_from_dpi = z_stripf(roundf(data[i].dpi / 25.4f)); ret = ZBarcode_XdimDp_From_Scale(data[i].symbology, data[i].scale, dpmm_from_dpi, data[i].filetype); assert_equal(ret, data[i].expected, - "i:%d ZBarcode_XdimDp_From_Scale(%s, %g (dpi %d), %g, %s) %.8g != %.8g\n", - i, testUtilBarcodeName(data[i].symbology), dpmm_from_dpi, data[i].dpi, data[i].scale, + "i:%d ZBarcode_XdimDp_From_Scale(%s, %g, %g (dpi %d), %s) %.8g != %.8g\n", + i, testUtilBarcodeName(data[i].symbology), data[i].scale, dpmm_from_dpi, data[i].dpi, data[i].filetype, ret, data[i].expected); } } @@ -2899,19 +2967,20 @@ static void test_utf8_to_eci(const testCtx *const p_ctx) { /* 35*/ { 24, "1234پ", -1, 0, 6, 0, "1234\201", 5 }, /* Windows-1256 */ /* 36*/ { 25, "1234é", -1, 0, 10, 0, "\0001\0002\0003\0004\000\351", 10 }, /* UTF-16BE */ /* 37*/ { 26, "1234é", -1, 0, 6, 0, "1234é", 6 }, /* UTF-8 */ - /* 38*/ { 27, "1234é", -1, 0, 6, ZINT_ERROR_INVALID_DATA, "", -1 }, /* ASCII */ - /* 39*/ { 27, "1234", -1, 0, 4, 0, "1234", -1 }, /* ASCII */ - /* 40*/ { 28, "1234_", -1, 0, 7, 0, "1234\241\304", 6 }, /* Big5 */ - /* 41*/ { 29, "1234崂", -1, 0, 7, 0, "1234\341\300", 6 }, /* GB 2312 */ - /* 42*/ { 30, "1234가", -1, 0, 7, 0, "1234\260\241", 6 }, /* EUC-KR */ - /* 43*/ { 31, "1234郎", -1, 0, 7, 0, "1234\375\234", 6 }, /* GBK */ - /* 44*/ { 32, "1234崂", -1, 0, 14, 0, "1234\341\300", 6 }, /* GB 18030 */ - /* 45*/ { 33, "1234é", -1, 0, 10, 0, "1\0002\0003\0004\000\351\000", 10 }, /* UTF-16LE */ - /* 46*/ { 34, "1234é", -1, 0, 20, 0, "\000\000\0001\000\000\0002\000\000\0003\000\000\0004\000\000\000\351", 20 }, /* UTF-16BE */ - /* 47*/ { 35, "1234é", -1, 0, 20, 0, "1\000\000\0002\000\000\0003\000\000\0004\000\000\000\351\000\000\000", 20 }, /* UTF-16LE */ - /* 48*/ { 170, "1234", -1, 0, 4, 0, "1234", 4 }, /* ISO 646 Invariant */ - /* 49*/ { 170, "1234#", -1, 0, 5, ZINT_ERROR_INVALID_DATA, "", -1 }, /* ISO 646 Invariant */ - /* 50*/ { 899, "1234\000\127\302\200ÿ", 10, 0, 10, 0, "1234\000\127\200\377", 8 }, /* Binary */ + /* 38*/ { 26, "1234\200", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "", -1 }, + /* 39*/ { 27, "1234é", -1, 0, 6, ZINT_ERROR_INVALID_DATA, "", -1 }, /* ASCII */ + /* 40*/ { 27, "1234", -1, 0, 4, 0, "1234", -1 }, /* ASCII */ + /* 41*/ { 28, "1234_", -1, 0, 7, 0, "1234\241\304", 6 }, /* Big5 */ + /* 42*/ { 29, "1234崂", -1, 0, 7, 0, "1234\341\300", 6 }, /* GB 2312 */ + /* 43*/ { 30, "1234가", -1, 0, 7, 0, "1234\260\241", 6 }, /* EUC-KR */ + /* 44*/ { 31, "1234郎", -1, 0, 7, 0, "1234\375\234", 6 }, /* GBK */ + /* 45*/ { 32, "1234崂", -1, 0, 14, 0, "1234\341\300", 6 }, /* GB 18030 */ + /* 46*/ { 33, "1234é", -1, 0, 10, 0, "1\0002\0003\0004\000\351\000", 10 }, /* UTF-16LE */ + /* 47*/ { 34, "1234é", -1, 0, 20, 0, "\000\000\0001\000\000\0002\000\000\0003\000\000\0004\000\000\000\351", 20 }, /* UTF-16BE */ + /* 48*/ { 35, "1234é", -1, 0, 20, 0, "1\000\000\0002\000\000\0003\000\000\0004\000\000\000\351\000\000\000", 20 }, /* UTF-16LE */ + /* 49*/ { 170, "1234", -1, 0, 4, 0, "1234", 4 }, /* ISO 646 Invariant */ + /* 50*/ { 170, "1234#", -1, 0, 5, ZINT_ERROR_INVALID_DATA, "", -1 }, /* ISO 646 Invariant */ + /* 51*/ { 899, "1234\000\127\302\200ÿ", 10, 0, 10, 0, "1234\000\127\200\377", 8 }, /* Binary */ }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -2956,6 +3025,26 @@ static void test_utf8_to_eci(const testCtx *const p_ctx) { } } + { + /* Call `ZBarcode_UTF8_To_ECI()` without `ZBarcode_Dest_Len_ECI()` */ + unsigned char dest[32] ZINT_TESTUTIL_SANITIZEM_INIT; + int dest_length ZINT_TESTUTIL_SANITIZEM_INIT; + const char *text; + int eci; + + text = "ABC"; + eci = 14; + ret = ZBarcode_UTF8_To_ECI(eci, ZCUCP(text), -1, dest, &dest_length); + assert_equal(ret, ZINT_ERROR_INVALID_OPTION, "ZBarcode_UTF8_To_ECI(%d, %s) ret %d != %d\n", + eci, text, ret, ZINT_ERROR_INVALID_OPTION); + + text = "AB\200"; + eci = 26; + ret = ZBarcode_UTF8_To_ECI(eci, ZCUCP(text), -1, dest, &dest_length); + assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ZBarcode_UTF8_To_ECI(%d, %s) ret %d != %d\n", + eci, text, ret, ZINT_ERROR_INVALID_OPTION); + } + testFinish(); } @@ -2965,127 +3054,139 @@ static void test_content_segs(const testCtx *const p_ctx) { struct item { int symbology; int input_mode; + int option_2; const char *data; const char *expected; }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { BARCODE_CODE11, -1, "1234567890", "123456789019" }, - /* 1*/ { BARCODE_C25STANDARD, -1, "1234567890", "" }, - /* 2*/ { BARCODE_C25INTER, -1, "1234567890", "" }, - /* 3*/ { BARCODE_C25IATA, -1, "1234567890", "" }, - /* 4*/ { BARCODE_C25LOGIC, -1, "1234567890", "" }, - /* 5*/ { BARCODE_C25IND, -1, "1234567890", "" }, - /* 6*/ { BARCODE_CODE39, -1, "1234567890", "" }, - /* 7*/ { BARCODE_EXCODE39, -1, "1234567890", "" }, - /* 8*/ { BARCODE_EAN8, -1, "1234567", "12345670" }, - /* 9*/ { BARCODE_EANX, -1, "123456789012", "1234567890128" }, - /* 10*/ { BARCODE_EANX_CHK, -1, "1234567890128", "" }, - /* 11*/ { BARCODE_EAN13, -1, "123456789012", "1234567890128" }, - /* 12*/ { BARCODE_GS1_128, -1, "[01]12345678901231", "0112345678901231" }, - /* 13*/ { BARCODE_CODABAR, -1, "A00000000B", "" }, - /* 14*/ { BARCODE_CODE128, -1, "1234567890", "" }, - /* 15*/ { BARCODE_DPLEIT, -1, "1234567890123", "12345678901236" }, - /* 16*/ { BARCODE_DPIDENT, -1, "12345678901", "123456789016" }, - /* 17*/ { BARCODE_CODE16K, -1, "1234567890", "" }, - /* 18*/ { BARCODE_CODE16K, GS1_MODE, "[01]12345678901231", "0112345678901231" }, - /* 19*/ { BARCODE_CODE49, -1, "1234567890", "" }, - /* 20*/ { BARCODE_CODE49, GS1_MODE, "[01]12345678901231", "0112345678901231" }, - /* 21*/ { BARCODE_CODE93, -1, "1234567890", "1234567890M%" }, - /* 22*/ { BARCODE_FLAT, -1, "1234567890", "" }, - /* 23*/ { BARCODE_DBAR_OMN, -1, "1234567890123", "0112345678901231" }, - /* 24*/ { BARCODE_DBAR_LTD, -1, "1234567890123", "0112345678901231" }, - /* 25*/ { BARCODE_DBAR_EXP, -1, "[01]12345678901231", "0112345678901231" }, - /* 26*/ { BARCODE_TELEPEN, -1, "1234567890", "1234567890n" }, - /* 27*/ { BARCODE_UPCA, -1, "12345678901", "0123456789012" }, - /* 28*/ { BARCODE_UPCA_CHK, -1, "123456789012", "0123456789012" }, - /* 29*/ { BARCODE_UPCE, -1, "1234567", "0123456000070" }, - /* 30*/ { BARCODE_UPCE_CHK, -1, "12345670", "0123456000070" }, - /* 31*/ { BARCODE_POSTNET, -1, "12345678901", "123456789014" }, - /* 32*/ { BARCODE_MSI_PLESSEY, -1, "1234567890", "" }, - /* 33*/ { BARCODE_FIM, -1, "A", "" }, - /* 34*/ { BARCODE_LOGMARS, -1, "1234567890", "" }, - /* 35*/ { BARCODE_PHARMA, -1, "123456", "" }, - /* 36*/ { BARCODE_PZN, -1, "123456", "-01234562" }, - /* 37*/ { BARCODE_PHARMA_TWO, -1, "12345678", "" }, - /* 38*/ { BARCODE_CEPNET, -1, "12345678", "123456784" }, - /* 39*/ { BARCODE_PDF417, -1, "1234567890", "" }, - /* 40*/ { BARCODE_PDF417COMP, -1, "1234567890", "" }, - /* 41*/ { BARCODE_MAXICODE, -1, "1234567890", "" }, - /* 42*/ { BARCODE_QRCODE, -1, "1234567890", "" }, - /* 43*/ { BARCODE_QRCODE, UNICODE_MODE, "1234567890", "" }, - /* 44*/ { BARCODE_QRCODE, GS1_MODE, "[01]12345678901231", "0112345678901231" }, - /* 45*/ { BARCODE_CODE128AB, -1, "1234567890", "" }, - /* 46*/ { BARCODE_AUSPOST, -1, "12345678901234567890123", "6212345678901234567890123" }, - /* 47*/ { BARCODE_AUSREPLY, -1, "12345678", "4512345678" }, - /* 48*/ { BARCODE_AUSROUTE, -1, "12345678", "8712345678" }, - /* 49*/ { BARCODE_AUSREDIRECT, -1, "12345678", "9212345678" }, - /* 50*/ { BARCODE_ISBNX, -1, "123456789", "9780123456786" }, - /* 51*/ { BARCODE_RM4SCC, -1, "1234567890", "12345678906" }, - /* 52*/ { BARCODE_DATAMATRIX, -1, "ABC", "" }, - /* 53*/ { BARCODE_DATAMATRIX, GS1_MODE, "[01]12345678901231", "0112345678901231" }, - /* 54*/ { BARCODE_EAN14, -1, "1234567890123", "0112345678901231" }, - /* 55*/ { BARCODE_VIN, -1, "12345678701234567", "" }, - /* 56*/ { BARCODE_CODABLOCKF, -1, "1234567890", "" }, - /* 57*/ { BARCODE_NVE18, -1, "12345678901234567", "00123456789012345675" }, - /* 58*/ { BARCODE_JAPANPOST, -1, "1234567890", "" }, - /* 59*/ { BARCODE_KOREAPOST, -1, "123456", "1234569" }, - /* 60*/ { BARCODE_DBAR_STK, -1, "1234567890123", "0112345678901231" }, - /* 61*/ { BARCODE_DBAR_OMNSTK, -1, "1234567890123", "0112345678901231" }, - /* 62*/ { BARCODE_DBAR_EXPSTK, -1, "[01]12345678901231", "0112345678901231" }, - /* 63*/ { BARCODE_PLANET, -1, "12345678901", "123456789014" }, - /* 64*/ { BARCODE_MICROPDF417, -1, "1234567890", "" }, - /* 65*/ { BARCODE_USPS_IMAIL, -1, "12345678901234567890", "" }, - /* 66*/ { BARCODE_PLESSEY, -1, "1234567890", "12345678906E" }, - /* 67*/ { BARCODE_TELEPEN_NUM, -1, "1234567890", "1234567890g" }, - /* 68*/ { BARCODE_ITF14, -1, "1234567890", "00012345678905" }, - /* 69*/ { BARCODE_KIX, -1, "123456ABCDE", "" }, - /* 70*/ { BARCODE_AZTEC, -1, "1234567890AB", "" }, - /* 71*/ { BARCODE_DAFT, -1, "DAFTDAFTDAFTDAFT", "" }, - /* 72*/ { BARCODE_DPD, -1, "0123456789012345678901234567", "" }, - /* 73*/ { BARCODE_MICROQR, -1, "12345", "" }, - /* 74*/ { BARCODE_MICROQR, UNICODE_MODE, "12345", "" }, - /* 75*/ { BARCODE_HIBC_128, -1, "1234567890", "+12345678900" }, - /* 76*/ { BARCODE_HIBC_39, -1, "1234567890", "+12345678900" }, - /* 77*/ { BARCODE_HIBC_DM, -1, "ABC", "+ABCV" }, - /* 78*/ { BARCODE_HIBC_QR, -1, "1234567890AB", "+1234567890ABL" }, - /* 79*/ { BARCODE_HIBC_PDF, -1, "1234567890", "+12345678900" }, - /* 80*/ { BARCODE_HIBC_MICPDF, -1, "1234567890", "+12345678900" }, - /* 81*/ { BARCODE_HIBC_BLOCKF, -1, "1234567890", "+12345678900" }, - /* 82*/ { BARCODE_HIBC_AZTEC, -1, "1234567890AB", "+1234567890ABL" }, - /* 83*/ { BARCODE_DOTCODE, -1, "ABC", "" }, - /* 84*/ { BARCODE_HANXIN, -1, "1234567890AB", "" }, - /* 85*/ { BARCODE_HANXIN, UNICODE_MODE, "1234567890AB", "" }, - /* 86*/ { BARCODE_MAILMARK_2D, -1, "012100123412345678AB19XY1A 0", "JGB 012100123412345678AB19XY1A 0 " }, - /* 87*/ { BARCODE_UPU_S10, -1, "EE876543216CA", "" }, - /* 88*/ { BARCODE_MAILMARK_4S, -1, "01000000000000000AA00AA0A", "01000000000000000AA00AA0A " }, - /* 89*/ { BARCODE_AZRUNE, -1, "255", "" }, - /* 90*/ { BARCODE_CODE32, -1, "12345678", "3PRM8N" }, - /* 91*/ { BARCODE_EANX_CC, -1, "123456789012", "1234567890128|2001" }, - /* 92*/ { BARCODE_GS1_128_CC, -1, "[01]12345678901231", "0112345678901231|2001" }, - /* 93*/ { BARCODE_DBAR_OMN_CC, -1, "1234567890123", "0112345678901231|2001" }, - /* 94*/ { BARCODE_DBAR_LTD_CC, -1, "1234567890123", "0112345678901231|2001" }, - /* 95*/ { BARCODE_DBAR_EXP_CC, -1, "[01]12345678901231", "0112345678901231|2001" }, - /* 96*/ { BARCODE_UPCA_CC, -1, "12345678901", "0123456789012|2001" }, - /* 97*/ { BARCODE_UPCE_CC, -1, "1234567", "0123456000070|2001" }, - /* 98*/ { BARCODE_DBAR_STK_CC, -1, "1234567890123", "0112345678901231|2001" }, - /* 99*/ { BARCODE_DBAR_OMNSTK_CC, -1, "1234567890123", "0112345678901231|2001" }, - /*100*/ { BARCODE_DBAR_EXPSTK_CC, -1, "[01]12345678901231", "0112345678901231|2001" }, - /*101*/ { BARCODE_CHANNEL, -1, "01", "" }, - /*102*/ { BARCODE_CODEONE, -1, "12345678901234567890", "" }, - /*103*/ { BARCODE_CODEONE, GS1_MODE, "[01]12345678901231", "0112345678901231" }, - /*104*/ { BARCODE_GRIDMATRIX, -1, "ABC", "" }, - /*105*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, "ABC", "" }, - /*106*/ { BARCODE_UPNQR, -1, "1234567890AB", "" }, - /*107*/ { BARCODE_ULTRA, -1, "1234567890", "" }, - /*108*/ { BARCODE_ULTRA, GS1_MODE, "[01]12345678901231", "0112345678901231" }, - /*109*/ { BARCODE_RMQR, -1, "12345", "" }, - /*110*/ { BARCODE_RMQR, UNICODE_MODE, "12345", "" }, - /*111*/ { BARCODE_RMQR, GS1_MODE, "[01]12345678901231", "0112345678901231" }, - /*112*/ { BARCODE_BC412, -1, "1234567", "1U234567" }, - /*113*/ { BARCODE_DXFILMEDGE, -1, "120476", "127-15" }, - /*114*/ { BARCODE_EAN8_CC, -1, "12345670", "12345670|2001" }, - /*115*/ { BARCODE_EAN13_CC, -1, "123456789012", "1234567890128|2001" }, + /* 0*/ { BARCODE_CODE11, -1, -1, "1234567890", "123456789019" }, + /* 1*/ { BARCODE_C25STANDARD, -1, -1, "1234567890", "" }, + /* 2*/ { BARCODE_C25INTER, -1, -1, "1234567890", "" }, + /* 3*/ { BARCODE_C25IATA, -1, -1, "1234567890", "" }, + /* 4*/ { BARCODE_C25LOGIC, -1, -1, "1234567890", "" }, + /* 5*/ { BARCODE_C25IND, -1, -1, "1234567890", "" }, + /* 6*/ { BARCODE_CODE39, -1, -1, "1234567890", "" }, + /* 7*/ { BARCODE_EXCODE39, -1, -1, "1234567890", "" }, + /* 8*/ { BARCODE_EAN8, -1, -1, "1234567", "12345670" }, + /* 9*/ { BARCODE_EANX, -1, -1, "123456789012", "1234567890128" }, + /* 10*/ { BARCODE_EANX_CHK, -1, -1, "1234567890128", "" }, + /* 11*/ { BARCODE_EAN13, -1, -1, "123456789012", "1234567890128" }, + /* 12*/ { BARCODE_GS1_128, -1, -1, "[01]12345678901231", "0112345678901231" }, + /* 13*/ { BARCODE_CODABAR, -1, -1, "A00000000B", "" }, + /* 14*/ { BARCODE_CODE128, -1, -1, "1234567890", "" }, + /* 15*/ { BARCODE_CODE128, UNICODE_MODE, -1, "1234567890", "" }, + /* 16*/ { BARCODE_DPLEIT, -1, -1, "1234567890123", "12345678901236" }, + /* 17*/ { BARCODE_DPIDENT, -1, -1, "12345678901", "123456789016" }, + /* 18*/ { BARCODE_CODE16K, -1, -1, "1234567890", "" }, + /* 19*/ { BARCODE_CODE16K, UNICODE_MODE, -1, "1234567890", "" }, + /* 20*/ { BARCODE_CODE16K, GS1_MODE, -1, "[01]12345678901231", "0112345678901231" }, + /* 21*/ { BARCODE_CODE49, -1, -1, "1234567890", "" }, + /* 22*/ { BARCODE_CODE49, GS1_MODE, -1, "[01]12345678901231", "0112345678901231" }, + /* 23*/ { BARCODE_CODE93, -1, -1, "1234567890", "1234567890M%" }, + /* 24*/ { BARCODE_FLAT, -1, -1, "1234567890", "" }, + /* 25*/ { BARCODE_DBAR_OMN, -1, -1, "1234567890123", "0112345678901231" }, + /* 26*/ { BARCODE_DBAR_LTD, -1, -1, "1234567890123", "0112345678901231" }, + /* 27*/ { BARCODE_DBAR_EXP, -1, -1, "[01]12345678901231", "0112345678901231" }, + /* 28*/ { BARCODE_TELEPEN, -1, -1, "1234567890", "1234567890n" }, + /* 29*/ { BARCODE_TELEPEN, -1, 1, "ABC\0201234", "ABC\0201234C" }, + /* 30*/ { BARCODE_UPCA, -1, -1, "12345678901", "0123456789012" }, + /* 31*/ { BARCODE_UPCA_CHK, -1, -1, "123456789012", "0123456789012" }, + /* 32*/ { BARCODE_UPCE, -1, -1, "1234567", "0123456000070" }, + /* 33*/ { BARCODE_UPCE_CHK, -1, -1, "12345670", "0123456000070" }, + /* 34*/ { BARCODE_POSTNET, -1, -1, "12345678901", "123456789014" }, + /* 35*/ { BARCODE_MSI_PLESSEY, -1, -1, "1234567890", "" }, + /* 36*/ { BARCODE_MSI_PLESSEY, -1, 1, "1234567890", "12345678903" }, + /* 37*/ { BARCODE_MSI_PLESSEY, -1, 2, "1234567890", "123456789031" }, + /* 38*/ { BARCODE_MSI_PLESSEY, -1, 3, "1234567890", "12345678903" }, + /* 39*/ { BARCODE_MSI_PLESSEY, -1, 4, "1234567890", "123456789031" }, + /* 40*/ { BARCODE_MSI_PLESSEY, -1, 5, "1234567890", "12345678900" }, + /* 41*/ { BARCODE_MSI_PLESSEY, -1, 6, "1234567890", "123456789007" }, + /* 42*/ { BARCODE_FIM, -1, -1, "A", "" }, + /* 43*/ { BARCODE_LOGMARS, -1, -1, "1234567890", "" }, + /* 44*/ { BARCODE_PHARMA, -1, -1, "123456", "" }, + /* 45*/ { BARCODE_PZN, -1, -1, "123456", "-01234562" }, + /* 46*/ { BARCODE_PHARMA_TWO, -1, -1, "12345678", "" }, + /* 47*/ { BARCODE_CEPNET, -1, -1, "12345678", "123456784" }, + /* 48*/ { BARCODE_PDF417, -1, -1, "1234567890", "" }, + /* 49*/ { BARCODE_PDF417COMP, -1, -1, "1234567890", "" }, + /* 50*/ { BARCODE_MAXICODE, -1, -1, "1234567890", "" }, + /* 51*/ { BARCODE_QRCODE, -1, -1, "1234567890", "" }, + /* 52*/ { BARCODE_QRCODE, UNICODE_MODE, -1, "1234567890", "" }, + /* 53*/ { BARCODE_QRCODE, GS1_MODE, -1, "[01]12345678901231", "0112345678901231" }, + /* 54*/ { BARCODE_CODE128AB, -1, -1, "1234567890", "" }, + /* 55*/ { BARCODE_AUSPOST, -1, -1, "12345678901234567890123", "6212345678901234567890123" }, + /* 56*/ { BARCODE_AUSREPLY, -1, -1, "12345678", "4512345678" }, + /* 57*/ { BARCODE_AUSROUTE, -1, -1, "12345678", "8712345678" }, + /* 58*/ { BARCODE_AUSREDIRECT, -1, -1, "12345678", "9212345678" }, + /* 59*/ { BARCODE_ISBNX, -1, -1, "123456789", "9780123456786" }, + /* 60*/ { BARCODE_RM4SCC, -1, -1, "1234567890", "12345678906" }, + /* 61*/ { BARCODE_DATAMATRIX, -1, -1, "ABC", "" }, + /* 62*/ { BARCODE_DATAMATRIX, GS1_MODE, -1, "[01]12345678901231", "0112345678901231" }, + /* 63*/ { BARCODE_EAN14, -1, -1, "1234567890123", "0112345678901231" }, + /* 64*/ { BARCODE_VIN, -1, -1, "12345678701234567", "" }, + /* 65*/ { BARCODE_CODABLOCKF, -1, -1, "1234567890", "" }, + /* 66*/ { BARCODE_NVE18, -1, -1, "12345678901234567", "00123456789012345675" }, + /* 67*/ { BARCODE_JAPANPOST, -1, -1, "1234567890", "" }, + /* 68*/ { BARCODE_KOREAPOST, -1, -1, "123456", "1234569" }, + /* 69*/ { BARCODE_DBAR_STK, -1, -1, "1234567890123", "0112345678901231" }, + /* 70*/ { BARCODE_DBAR_OMNSTK, -1, -1, "1234567890123", "0112345678901231" }, + /* 71*/ { BARCODE_DBAR_EXPSTK, -1, -1, "[01]12345678901231", "0112345678901231" }, + /* 72*/ { BARCODE_PLANET, -1, -1, "12345678901", "123456789014" }, + /* 73*/ { BARCODE_MICROPDF417, -1, -1, "1234567890", "" }, + /* 74*/ { BARCODE_USPS_IMAIL, -1, -1, "12345678901234567890", "" }, + /* 75*/ { BARCODE_PLESSEY, -1, -1, "1234567890", "12345678906E" }, + /* 76*/ { BARCODE_TELEPEN_NUM, -1, -1, "1234567890", "1234567890g" }, + /* 77*/ { BARCODE_TELEPEN_NUM, -1, -1, "1234567890\020", "1234567890\020W" }, + /* 78*/ { BARCODE_ITF14, -1, -1, "1234567890", "00012345678905" }, + /* 79*/ { BARCODE_KIX, -1, -1, "123456ABCDE", "" }, + /* 80*/ { BARCODE_AZTEC, -1, -1, "1234567890AB", "" }, + /* 81*/ { BARCODE_DAFT, -1, -1, "DAFTDAFTDAFTDAFT", "" }, + /* 82*/ { BARCODE_DPD, -1, -1, "0123456789012345678901234567", "" }, + /* 83*/ { BARCODE_MICROQR, -1, -1, "12345", "" }, + /* 84*/ { BARCODE_MICROQR, UNICODE_MODE, -1, "12345", "" }, + /* 85*/ { BARCODE_HIBC_128, -1, -1, "1234567890", "+12345678900" }, + /* 86*/ { BARCODE_HIBC_39, -1, -1, "1234567890", "+12345678900" }, + /* 87*/ { BARCODE_HIBC_DM, -1, -1, "ABC", "+ABCV" }, + /* 88*/ { BARCODE_HIBC_QR, -1, -1, "1234567890AB", "+1234567890ABL" }, + /* 89*/ { BARCODE_HIBC_PDF, -1, -1, "1234567890", "+12345678900" }, + /* 90*/ { BARCODE_HIBC_MICPDF, -1, -1, "1234567890", "+12345678900" }, + /* 91*/ { BARCODE_HIBC_BLOCKF, -1, -1, "1234567890", "+12345678900" }, + /* 92*/ { BARCODE_HIBC_AZTEC, -1, -1, "1234567890AB", "+1234567890ABL" }, + /* 93*/ { BARCODE_DOTCODE, -1, -1, "ABC", "" }, + /* 94*/ { BARCODE_HANXIN, -1, -1, "1234567890AB", "" }, + /* 95*/ { BARCODE_HANXIN, UNICODE_MODE, -1, "1234567890AB", "" }, + /* 96*/ { BARCODE_MAILMARK_2D, -1, -1, "012100123412345678AB19XY1A 0", "JGB 012100123412345678AB19XY1A 0 " }, + /* 97*/ { BARCODE_MAILMARK_2D, UNICODE_MODE, -1, "012100123412345678AB19XY1A 0", "JGB 012100123412345678AB19XY1A 0 " }, + /* 98*/ { BARCODE_UPU_S10, -1, -1, "EE876543216CA", "" }, + /* 99*/ { BARCODE_MAILMARK_4S, -1, -1, "01000000000000000AA00AA0A", "01000000000000000AA00AA0A " }, + /*100*/ { BARCODE_AZRUNE, -1, -1, "255", "" }, + /*101*/ { BARCODE_CODE32, -1, -1, "12345678", "3PRM8N" }, + /*102*/ { BARCODE_EANX_CC, -1, -1, "123456789012", "1234567890128|2001" }, + /*103*/ { BARCODE_GS1_128_CC, -1, -1, "[01]12345678901231", "0112345678901231|2001" }, + /*104*/ { BARCODE_DBAR_OMN_CC, -1, -1, "1234567890123", "0112345678901231|2001" }, + /*105*/ { BARCODE_DBAR_LTD_CC, -1, -1, "1234567890123", "0112345678901231|2001" }, + /*106*/ { BARCODE_DBAR_EXP_CC, -1, -1, "[01]12345678901231", "0112345678901231|2001" }, + /*107*/ { BARCODE_UPCA_CC, -1, -1, "12345678901", "0123456789012|2001" }, + /*108*/ { BARCODE_UPCE_CC, -1, -1, "1234567", "0123456000070|2001" }, + /*109*/ { BARCODE_DBAR_STK_CC, -1, -1, "1234567890123", "0112345678901231|2001" }, + /*110*/ { BARCODE_DBAR_OMNSTK_CC, -1, -1, "1234567890123", "0112345678901231|2001" }, + /*111*/ { BARCODE_DBAR_EXPSTK_CC, -1, -1, "[01]12345678901231", "0112345678901231|2001" }, + /*112*/ { BARCODE_CHANNEL, -1, -1, "01", "" }, + /*113*/ { BARCODE_CODEONE, -1, -1, "12345678901234567890", "" }, + /*114*/ { BARCODE_CODEONE, GS1_MODE, -1, "[01]12345678901231", "0112345678901231" }, + /*115*/ { BARCODE_GRIDMATRIX, -1, -1, "ABC", "" }, + /*116*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, -1, "ABC", "" }, + /*117*/ { BARCODE_UPNQR, -1, -1, "1234567890AB", "" }, + /*118*/ { BARCODE_ULTRA, -1, -1, "1234567890", "" }, + /*119*/ { BARCODE_ULTRA, GS1_MODE, -1, "[01]12345678901231", "0112345678901231" }, + /*120*/ { BARCODE_RMQR, -1, -1, "12345", "" }, + /*121*/ { BARCODE_RMQR, UNICODE_MODE, -1, "12345", "" }, + /*122*/ { BARCODE_RMQR, GS1_MODE, -1, "[01]12345678901231", "0112345678901231" }, + /*123*/ { BARCODE_BC412, -1, -1, "1234567", "1U234567" }, + /*124*/ { BARCODE_DXFILMEDGE, -1, -1, "120476", "127-15" }, + /*125*/ { BARCODE_EAN8_CC, -1, -1, "12345670", "12345670|2001" }, + /*126*/ { BARCODE_EAN13_CC, -1, -1, "123456789012", "1234567890128|2001" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -3111,7 +3212,7 @@ static void test_content_segs(const testCtx *const p_ctx) { text = data[i].data; } length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, BARCODE_CONTENT_SEGS, + -1 /*option_1*/, data[i].option_2, -1 /*option_3*/, BARCODE_CONTENT_SEGS, text, -1, debug); expected = data[i].expected[0] ? data[i].expected : data[i].data; expected_length = (int) strlen(expected); @@ -3132,6 +3233,106 @@ static void test_content_segs(const testCtx *const p_ctx) { ZBarcode_Delete(symbol); } + for (i = 0; i < data_size; i++) { + int fail_at = 1; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + if (z_is_composite(data[i].symbology)) { + text = "[20]01"; + strcpy(symbol->primary, data[i].data); + fail_at = 1 + !(i & 1); /* Alternate between failing on linear and composite */ + } else { + text = data[i].data; + } + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1 /*option_3*/, BARCODE_CONTENT_SEGS, + text, -1, debug); + + zint_test_ct_set_fail(Z_CT_FAIL_ID_INIT_SEGS, fail_at); + ret = ZBarcode_Encode(symbol, ZCUCP(text), length); + assert_equal(ret, ZINT_ERROR_MEMORY, "i:%d Z_CT_FAIL_ID_INIT_SEGS ret %d != ZINT_ERROR_MEMORY %s\n", + i, ret, symbol->errtxt); + zint_test_ct_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + for (i = 0; i < data_size; i++) { + int fail_at = 1; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + if (z_is_composite(data[i].symbology)) { + text = "[20]01"; + strcpy(symbol->primary, data[i].data); + fail_at = 1 + !!(i & 1); /* Alternate between failing on linear and composite */ + } else { + text = data[i].data; + } + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1 /*option_3*/, BARCODE_CONTENT_SEGS, + text, -1, debug); + + zint_test_ct_set_fail(Z_CT_FAIL_ID_INIT_SEG_SRC, fail_at); + ret = ZBarcode_Encode(symbol, ZCUCP(text), length); + assert_equal(ret, ZINT_ERROR_MEMORY, "i:%d Z_CT_FAIL_ID_INIT_SEG_SRC ret %d != ZINT_ERROR_MEMORY %s\n", + i, ret, symbol->errtxt); + zint_test_ct_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + +#include "filemem.h" + +static void test_txt_hex_plot(const testCtx *const p_ctx) { + int ret; + struct zint_symbol *symbol = NULL; + unsigned char data[10] = {0}; + const int length = 1; + int at; + + (void)p_ctx; + + testStartSymbol(p_ctx->func_name, &symbol); + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + symbol->symbology = BARCODE_DATAMATRIX; + strcpy(symbol->outfile, "out.txt"); + ret = ZBarcode_Encode(symbol, data, ARRAY_SIZE(data)); + assert_zero(ret, "ZBarcode_Encode ret %d != 0 (%s)\n", ret, symbol->errtxt); + + for (at = 5; at < 10; at++) { + zint_test_fm_set_fail(FM_FAIL_ID_PUTC, at); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, ZINT_ERROR_FILE_WRITE, "ZBarcode_Print PUTC(%d) ret %d != ZINT_ERROR_FILE_WRITE (%s)\n", + at, ret, symbol->errtxt); + + ZBarcode_Clear(symbol); + ret = ZBarcode_Encode(symbol, data, length); + assert_zero(ret, "ZBarcode_Encode ret %d != 0 (%s)\n", ret, symbol->errtxt); + } + + zint_test_fm_set_fail(FM_FAIL_ID_CLOSE, 1); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, ZINT_ERROR_FILE_WRITE, "ZBarcode_Print CLOSE ret %d != ZINT_ERROR_FILE_WRITE (%s)\n", + ret, symbol->errtxt); + + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + testFinish(); } @@ -3165,10 +3366,12 @@ int main(int argc, char *argv[]) { { "test_zero_outfile", test_zero_outfile }, { "test_clear", test_clear }, { "test_reset", test_reset }, + { "test_default_xdim", test_default_xdim }, { "test_scale_from_xdimdp", test_scale_from_xdimdp }, { "test_xdimdp_from_scale", test_xdimdp_from_scale }, { "test_utf8_to_eci", test_utf8_to_eci }, { "test_content_segs", test_content_segs }, + { "test_txt_hex_plot", test_txt_hex_plot }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_maxicode.c b/backend/tests/test_maxicode.c index 98daee32..64a128fc 100644 --- a/backend/tests/test_maxicode.c +++ b/backend/tests/test_maxicode.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2019-2025 Robin Stuart + Copyright (C) 2019-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -109,31 +109,45 @@ static void test_large(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", + i, data[i].length, (int) strlen(data_buf)); - length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, -1 /*input_mode*/, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, -1 /*input_mode*/, -1 /*eci*/, + data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, + data_buf, data[i].length, debug); strcpy(symbol->primary, data[i].primary); ret = ZBarcode_Encode(symbol, TCU(data_buf), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } else { - 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_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { char modules_dump[33 * 33 + 1]; - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data_buf, length, symbol->primary, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data_buf, length, + symbol->primary, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, + testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, modules_dump); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -1220,14 +1234,17 @@ static void test_encode(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, data[i].input_mode, -1 /*eci*/, + data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, + data[i].data, data[i].length, debug); if (data[i].structapp.count) { symbol->structapp = data[i].structapp; } strcpy(symbol->primary, data[i].primary); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %d, %d, { %d, %d, \"%s\" }, \"%s\", %d, \"%s\", %s, %d, %d, %d, %d, \"%s\",\n", @@ -1242,22 +1259,31 @@ static void test_encode(const testCtx *const p_ctx) { if (ret < ZINT_ERROR) { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, ret, width, row, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, data[i].primary, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, data[i].option_1, data[i].option_2, -1, data[i].data, length, + data[i].primary, cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { @@ -1826,15 +1852,20 @@ static void test_encode_segs(const testCtx *const p_ctx) { for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++); ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { char escaped1[4096]; char escaped2[4096]; - int length = data[i].segs[0].length == -1 ? (int) z_ustrlen(data[i].segs[0].source) : data[i].segs[0].length; - int length1 = data[i].segs[1].length == -1 ? (int) z_ustrlen(data[i].segs[1].source) : data[i].segs[1].length; - int length2 = data[i].segs[2].length == -1 ? (int) z_ustrlen(data[i].segs[2].source) : data[i].segs[2].length; - printf(" /*%3d*/ { %s, %d, %d, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, \"%s\", %s, %d, %d, %d, \"%s\",\n", + int length = data[i].segs[0].length == -1 ? (int) z_ustrlen(data[i].segs[0].source) + : data[i].segs[0].length; + int length1 = data[i].segs[1].length == -1 ? (int) z_ustrlen(data[i].segs[1].source) + : data[i].segs[1].length; + int length2 = data[i].segs[2].length == -1 ? (int) z_ustrlen(data[i].segs[2].source) + : data[i].segs[2].length; + printf(" /*%3d*/ { %s, %d, %d, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }," + "{ TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, \"%s\", %s, %d, %d, %d, \"%s\",\n", i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), @@ -1897,7 +1928,8 @@ static void test_encode_segs(const testCtx *const p_ctx) { ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count, data[i].primary, escaped, &ret_len); - assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", + assert_zero(ret, + "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped); } @@ -1908,6 +1940,32 @@ static void test_encode_segs(const testCtx *const p_ctx) { ZBarcode_Delete(symbol); } + if (!p_ctx->generate && p_ctx->index == -1) { + struct zint_seg segs[25] = {0}; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (i = 0; i < ARRAY_SIZE(segs); i++) { + segs[i].eci = 899; + segs[i].source = ZUCP("A"); + segs[i].length = 1; + } + symbol->symbology = BARCODE_MAXICODE; + symbol->option_1 = 5; + + seg_count = ARRAY_SIZE(segs); + ret = ZBarcode_Encode_Segs(symbol, segs, seg_count); + assert_equal(ret, ZINT_ERROR_TOO_LONG, "ZBarcode_Encode_Segs ret %d != %d (%s)\n", + ret, ZINT_ERROR_TOO_LONG, symbol->errtxt); + + seg_count = 19; + ret = ZBarcode_Encode_Segs(symbol, segs, seg_count); + assert_zero(ret, "ZBarcode_Encode_Segs ret %d != 0 (%s)\n", ret, symbol->errtxt); + + ZBarcode_Delete(symbol); + } + testFinish(); } @@ -1977,8 +2035,8 @@ static void test_rt(const testCtx *const p_ctx) { i, symbol->content_segs[0].length, expected_length); assert_zero(memcmp(symbol->content_segs[0].source, data[i].expected, expected_length), "i:%d content_segs[0].source memcmp(%s, %s, %d) != 0\n", i, - testUtilEscape((const char *) symbol->content_segs[0].source, symbol->content_segs[0].length, - escaped, sizeof(escaped)), + testUtilEscape((const char *) symbol->content_segs[0].source, + symbol->content_segs[0].length, escaped, sizeof(escaped)), testUtilEscape(data[i].expected, expected_length, escaped2, sizeof(escaped2)), expected_length); assert_equal(symbol->content_segs[0].eci, data[i].expected_content_eci, @@ -2050,8 +2108,9 @@ static void test_rt_segs(const testCtx *const p_ctx) { assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); - assert_equal(symbol->content_seg_count, data[i].expected_content_seg_count, "i:%d symbol->content_seg_count %d != %d\n", - i, symbol->content_seg_count, data[i].expected_content_seg_count); + assert_equal(symbol->content_seg_count, data[i].expected_content_seg_count, + "i:%d symbol->content_seg_count %d != %d\n", + i, symbol->content_seg_count, data[i].expected_content_seg_count); if (symbol->output_options & BARCODE_CONTENT_SEGS) { assert_nonnull(symbol->content_segs, "i:%d content_segs NULL\n", i); for (j = 0; j < symbol->content_seg_count; j++) { @@ -2062,7 +2121,8 @@ static void test_rt_segs(const testCtx *const p_ctx) { assert_equal(symbol->content_segs[j].length, expected_length, "i:%d content_segs[%d].length %d != expected_length %d\n", i, j, symbol->content_segs[j].length, expected_length); - assert_zero(memcmp(symbol->content_segs[j].source, data[i].expected_content_segs[j].source, expected_length), + assert_zero(memcmp(symbol->content_segs[j].source, data[i].expected_content_segs[j].source, + expected_length), "i:%d content_segs[%d].source memcmp(%s, %s, %d) != 0\n", i, j, testUtilEscape((const char *) symbol->content_segs[j].source, expected_length, escaped, sizeof(escaped)), @@ -2115,10 +2175,13 @@ static void test_fuzz(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, -1 /*input_mode*/, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, data[i].length, debug); + length = testUtilSetSymbol(symbol, BARCODE_MAXICODE, -1 /*input_mode*/, data[i].eci, + -1 /*option_1*/, -1, -1, -1 /*output_options*/, + data[i].data, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); ZBarcode_Delete(symbol); } diff --git a/backend/tests/test_output.c b/backend/tests/test_output.c index 8e7c047e..3cda688f 100644 --- a/backend/tests/test_output.c +++ b/backend/tests/test_output.c @@ -35,6 +35,7 @@ #include #include #endif +#include static void test_check_colour_options(const testCtx *const p_ctx) { struct item { @@ -82,7 +83,8 @@ static void test_check_colour_options(const testCtx *const p_ctx) { ret = zint_out_check_colour_options(&symbol); assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol.errtxt); - assert_zero(strcmp(symbol.errtxt, data[i].expected), "i:%d symbol.errtxt (%s) != expected (%s)\n", i, symbol.errtxt, data[i].expected); + assert_zero(strcmp(symbol.errtxt, data[i].expected), "i:%d symbol.errtxt (%s) != expected (%s)\n", + i, symbol.errtxt, data[i].expected); } testFinish(); @@ -130,10 +132,14 @@ static void test_colour_get_rgb(const testCtx *const p_ctx) { ret = zint_out_colour_get_rgb(data[i].colour, &red, &green, &blue, &alpha); assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret); - assert_equal(red, data[i].red, "i:%d red 0x%02X (%d) != 0x%02X (%d) (green 0x%02X, blue 0x%02X)\n", i, red, red, data[i].red, data[i].red, green, blue); - assert_equal(green, data[i].green, "i:%d green %d (0x%02X) != %d (0x%02X)\n", i, green, green, data[i].green, data[i].green); - assert_equal(blue, data[i].blue, "i:%d blue %d (0x%02X) != %d (0x%02X)\n", i, blue, blue, data[i].blue, data[i].blue); - assert_equal(alpha, data[i].alpha, "i:%d alpha %d (0x%02X) != %d (0x%02X)\n", i, alpha, alpha, data[i].alpha, data[i].alpha); + assert_equal(red, data[i].red, "i:%d red 0x%02X (%d) != 0x%02X (%d) (green 0x%02X, blue 0x%02X)\n", + i, red, red, data[i].red, data[i].red, green, blue); + assert_equal(green, data[i].green, "i:%d green %d (0x%02X) != %d (0x%02X)\n", + i, green, green, data[i].green, data[i].green); + assert_equal(blue, data[i].blue, "i:%d blue %d (0x%02X) != %d (0x%02X)\n", + i, blue, blue, data[i].blue, data[i].blue); + assert_equal(alpha, data[i].alpha, "i:%d alpha %d (0x%02X) != %d (0x%02X)\n", + i, alpha, alpha, data[i].alpha, data[i].alpha); have_alpha = ret == 1; if (have_alpha) { @@ -142,11 +148,14 @@ static void test_colour_get_rgb(const testCtx *const p_ctx) { sprintf(rgb, "%02X%02X%02X", red, green, blue); } ret = zint_out_colour_get_cmyk(rgb, &cyan, &magenta, &yellow, &black, &rgb_alpha); - assert_equal(ret, 1 + have_alpha, "i:%d zint_out_colour_get_cmyk(%s) ret %d != %d\n", i, rgb, ret, 1 + have_alpha); - assert_equal(rgb_alpha, alpha, "i:%d rgb_alpha %d (0x%02X) != %d (0x%02X)\n", i, rgb_alpha, rgb_alpha, alpha, alpha); + assert_equal(ret, 1 + have_alpha, "i:%d zint_out_colour_get_cmyk(%s) ret %d != %d\n", + i, rgb, ret, 1 + have_alpha); + assert_equal(rgb_alpha, alpha, "i:%d rgb_alpha %d (0x%02X) != %d (0x%02X)\n", + i, rgb_alpha, rgb_alpha, alpha, alpha); sprintf(cmyk, "%d,%d,%d,%d", cyan, magenta, yellow, black); - assert_zero(strcmp(cmyk, data[i].expected_cmyk), "i:%d strcmp(%s, %s) != 0\n", i, cmyk, data[i].expected_cmyk); + assert_zero(strcmp(cmyk, data[i].expected_cmyk), "i:%d strcmp(%s, %s) != 0\n", + i, cmyk, data[i].expected_cmyk); } testFinish(); @@ -188,13 +197,15 @@ static void test_colour_get_cmyk(const testCtx *const p_ctx) { ret = zint_out_colour_get_cmyk(data[i].colour, &cyan, &magenta, &yellow, &black, &alpha); assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret); - assert_equal(cyan, data[i].cyan, "i:%d cyan %d != %d (magenta %d, yellow %d, black %d)\n", i, cyan, data[i].cyan, magenta, yellow, black); + assert_equal(cyan, data[i].cyan, "i:%d cyan %d != %d (magenta %d, yellow %d, black %d)\n", + i, cyan, data[i].cyan, magenta, yellow, black); assert_equal(magenta, data[i].magenta, "i:%d magenta %d != %d\n", i, magenta, data[i].magenta); assert_equal(yellow, data[i].yellow, "i:%d yellow %d != %d\n", i, yellow, data[i].yellow); assert_equal(alpha, data[i].alpha, "i:%d alpha %d != %d\n", i, alpha, data[i].alpha); ret = zint_out_colour_get_rgb(data[i].colour, &red, &green, &blue, &rgb_alpha); - assert_equal(ret, data[i].ret_rgb, "i:%d zint_out_colour_get_rgb(%s) ret %d != %d\n", i, rgb, ret, data[i].ret_rgb); + assert_equal(ret, data[i].ret_rgb, "i:%d zint_out_colour_get_rgb(%s) ret %d != %d\n", + i, rgb, ret, data[i].ret_rgb); assert_equal(rgb_alpha, alpha, "i:%d rgb_alpha %d != %d\n", i, rgb_alpha, alpha); sprintf(rgb, "%02X%02X%02X%02X", red, green, blue, rgb_alpha); @@ -204,6 +215,47 @@ static void test_colour_get_cmyk(const testCtx *const p_ctx) { testFinish(); } +static void test_colour_char_to_rgb(const testCtx *const p_ctx) { + struct item { + const char ch; + int ret; + unsigned char red; + unsigned char green; + unsigned char blue; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { 'W', 1, 0xFF, 0xFF, 0xFF }, + /* 1*/ { 'C', 1, 0x00, 0xFF, 0xFF }, + /* 2*/ { 'B', 1, 0x00, 0x00, 0xFF }, + /* 3*/ { 'G', 1, 0x00, 0xFF, 0x00 }, + /* 4*/ { 'K', 1, 0x00, 0x00, 0x00 }, + /* 5*/ { 'L', 0, 0x00, 0x00, 0x00 }, + }; + const int data_size = ARRAY_SIZE(data); + int i, ret; + + testStart(p_ctx->func_name); + + for (i = 0; i < data_size; i++) { + /* Suppress clang-16 run-time exception MemorySanitizer: use-of-uninitialized-value (fixed in clang-17) */ + unsigned char red = 0, green = 0, blue = 0; + + if (testContinue(p_ctx, i)) continue; + + ret = zint_out_colour_char_to_rgb(data[i].ch, &red, &green, &blue); + assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret); + assert_equal(red, data[i].red, "i:%d red 0x%02X (%d) != 0x%02X (%d) (green 0x%02X, blue 0x%02X)\n", + i, red, red, data[i].red, data[i].red, green, blue); + assert_equal(green, data[i].green, "i:%d green %d (0x%02X) != %d (0x%02X)\n", + i, green, green, data[i].green, data[i].green); + assert_equal(blue, data[i].blue, "i:%d blue %d (0x%02X) != %d (0x%02X)\n", + i, blue, blue, data[i].blue, data[i].blue); + } + + testFinish(); +} + INTERNAL int zint_test_out_quiet_zones(const struct zint_symbol *symbol, const int hide_text, const int comp_xoffset, float *left, float *right, float *top, float *bottom); @@ -287,22 +339,32 @@ static void test_set_whitespace_offsets(const testCtx *const p_ctx) { zint_out_set_whitespace_offsets(&symbol, data[i].hide_text, data[i].comp_xoffset, &xoffset, &yoffset, &roffset, &boffset, &qz_right, data[i].scaler, &xoffset_si, &yoffset_si, &roffset_si, &boffset_si, &qz_right_si); - assert_equal(xoffset, data[i].expected_xoffset, "i:%d xoffset %g != %g\n", i, xoffset, data[i].expected_xoffset); - assert_equal(yoffset, data[i].expected_yoffset, "i:%d yoffset %g != %g\n", i, yoffset, data[i].expected_yoffset); - assert_equal(roffset, data[i].expected_roffset, "i:%d roffset %g != %g\n", i, roffset, data[i].expected_roffset); - assert_equal(boffset, data[i].expected_boffset, "i:%d boffset %g != %g\n", i, boffset, data[i].expected_boffset); - assert_equal(qz_right, data[i].expected_qz_right, "i:%d qz_right %g != %g\n", i, qz_right, data[i].expected_qz_right); + assert_equal(xoffset, data[i].expected_xoffset, "i:%d xoffset %g != %g\n", + i, xoffset, data[i].expected_xoffset); + assert_equal(yoffset, data[i].expected_yoffset, "i:%d yoffset %g != %g\n", + i, yoffset, data[i].expected_yoffset); + assert_equal(roffset, data[i].expected_roffset, "i:%d roffset %g != %g\n", + i, roffset, data[i].expected_roffset); + assert_equal(boffset, data[i].expected_boffset, "i:%d boffset %g != %g\n", + i, boffset, data[i].expected_boffset); + assert_equal(qz_right, data[i].expected_qz_right, "i:%d qz_right %g != %g\n", + i, qz_right, data[i].expected_qz_right); if (data[i].scaler) { int expected_xoffset_si = (int) (data[i].expected_xoffset * data[i].scaler); int expected_yoffset_si = (int) (data[i].expected_yoffset * data[i].scaler); int expected_roffset_si = (int) (data[i].expected_roffset * data[i].scaler); int expected_boffset_si = (int) (data[i].expected_boffset * data[i].scaler); int expected_qz_right_si = (int) (data[i].expected_qz_right * data[i].scaler); - assert_equal(xoffset_si, expected_xoffset_si, "i:%d xoffset_si %d != %d\n", i, xoffset_si, expected_xoffset_si); - assert_equal(yoffset_si, expected_yoffset_si, "i:%d yoffset_si %d != %d\n", i, yoffset_si, expected_yoffset_si); - assert_equal(roffset_si, expected_roffset_si, "i:%d roffset_si %d != %d\n", i, roffset_si, expected_roffset_si); - assert_equal(boffset_si, expected_boffset_si, "i:%d boffset_si %d != %d\n", i, boffset_si, expected_boffset_si); - assert_equal(qz_right_si, expected_qz_right_si, "i:%d qz_right_si %d != %d\n", i, qz_right_si, expected_qz_right_si); + assert_equal(xoffset_si, expected_xoffset_si, "i:%d xoffset_si %d != %d\n", + i, xoffset_si, expected_xoffset_si); + assert_equal(yoffset_si, expected_yoffset_si, "i:%d yoffset_si %d != %d\n", + i, yoffset_si, expected_yoffset_si); + assert_equal(roffset_si, expected_roffset_si, "i:%d roffset_si %d != %d\n", + i, roffset_si, expected_roffset_si); + assert_equal(boffset_si, expected_boffset_si, "i:%d boffset_si %d != %d\n", + i, boffset_si, expected_boffset_si); + assert_equal(qz_right_si, expected_qz_right_si, "i:%d qz_right_si %d != %d\n", + i, qz_right_si, expected_qz_right_si); } else { assert_zero(xoffset_si, "i:%d xoffset_si %d non-zero\n", i, xoffset_si); assert_zero(yoffset_si, "i:%d yoffset_si %d non-zero\n", i, yoffset_si); @@ -323,6 +385,53 @@ static void test_set_whitespace_offsets(const testCtx *const p_ctx) { #define TEST_OUT_SEP_STR "/" #endif +INTERNAL int zint_test_out_maybe_mkdir(const char *path); + +static void test_out_maybe_mkdir(const testCtx *const p_ctx) { + int ret; + const char dir[] = "test_maybe_dir"; + const char subdir[] = "test_maybe_dir/subdir"; +#ifndef _WIN32 + const int skip_readonly_test = getuid() == 0; /* Skip if running as root on Unix as can't create read-only file */ +#endif + + testStart(p_ctx->func_name); + + (void) testUtilRmDir(dir); /* In case lying around from previous fail */ + (void) testUtilRemove(dir); /* In case lying around from previous fail */ + + ret = zint_test_out_maybe_mkdir(dir); + assert_zero(ret, "out_maybe_mkdir(%s) ret %d != 0\n", dir, ret); + + ret = zint_test_out_maybe_mkdir(dir); + assert_zero(ret, "out_maybe_mkdir(%s) (exists) ret %d != 0\n", dir, ret); + + assert_zero(testUtilRmDir(dir), "testUtilRmDir(%s) != 0 (%d: %s)\n", dir, errno, strerror(errno)); + + assert_equal(testUtilCreateFile(dir), 1, "CreateFile(%s) != 1 (%d: %s)\n", dir, errno, strerror(errno)); + + ret = zint_test_out_maybe_mkdir(dir); + assert_equal(ret, -1, "out_maybe_mkdir(%s) file exists ret %d != -1\n", dir, ret); + + assert_zero(testUtilRemove(dir), "testUtilRemove(%s) != 0 (%d: %s)\n", dir, errno, strerror(errno)); + +#ifndef _WIN32 + if (!skip_readonly_test) { + ret = zint_test_out_maybe_mkdir(dir); + assert_zero(ret, "ret %d != 0\n", ret); + assert_zero(chmod(dir, S_IRUSR | S_IRGRP | S_IROTH), "chmod((%s) read-only != 0 (%d: %s)\n", + dir, errno, strerror(errno)); + + ret = zint_test_out_maybe_mkdir(subdir); + assert_equal(ret, -1, "out_maybe_mkdir(%s) ret %d != -1\n", subdir, ret); + + assert_zero(testUtilRemove(dir), "testUtilRemove(%s) != 0 (%d: %s)\n", dir, errno, strerror(errno)); + } +#endif + + testFinish(); +} + static void test_fopen(const testCtx *const p_ctx) { struct item { const char dir[32]; @@ -393,17 +502,40 @@ static void test_fopen(const testCtx *const p_ctx) { if (data[i].succeed) { assert_nonnull(ret, "i:%d zint_out_fopen(%s) == NULL (%d: %s)\n", i, outfile, errno, strerror(errno)); assert_zero(fclose(ret), "i:%d fclose(%s) != 0 (%d: %s)\n", i, outfile, errno, strerror(errno)); - assert_nonzero(testUtilExists(outfile), "i:%d testUtilExists(%s) != 0 (%d: %s)\n", i, outfile, errno, strerror(errno)); + assert_nonzero(testUtilExists(outfile), "i:%d testUtilExists(%s) != 0 (%d: %s)\n", + i, outfile, errno, strerror(errno)); if (data[i].dir[0]) { - assert_nonzero(testUtilDirExists(dirname), "i:%d testUtilDirExists(%s) != 0 (%d: %s)\n", i, dirname, errno, strerror(errno)); + assert_nonzero(testUtilDirExists(dirname), "i:%d testUtilDirExists(%s) != 0 (%d: %s)\n", + i, dirname, errno, strerror(errno)); } - assert_zero(testUtilRemove(outfile), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, outfile, errno, strerror(errno)); + assert_zero(testUtilRemove(outfile), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, outfile, errno, strerror(errno)); if (data[i].dir[0]) { if (data[i].subdir[0] && !subdir_exists) { - assert_zero(testUtilRmDir(subdirname), "i:%d rmdir(%s) != 0 (%d: %s)\n", i, subdirname, errno, strerror(errno)); + assert_zero(testUtilRmDir(subdirname), "i:%d rmdir(%s) != 0 (%d: %s)\n", + i, subdirname, errno, strerror(errno)); } if (!dir_exists && strcmp(dirname, "/") != 0 && strcmp(dirname, "\\") != 0) { - assert_zero(testUtilRmDir(dirname), "i:%d rmdir(%s) != 0 (%d: %s)\n", i, dirname, errno, strerror(errno)); +#ifndef _WIN32 + /* Skip if running as root on Unix as can't create read-only file */ + const int skip_readonly_test = getuid() == 0; +#endif + assert_zero(testUtilRmDir(dirname), "i:%d rmdir(%s) != 0 (%d: %s)\n", + i, dirname, errno, strerror(errno)); + +#ifndef _WIN32 + if (!skip_readonly_test) { + int iret = testUtilMkDir(dirname); + assert_zero(iret, "i:%d testUtilMkDir iret %d != 0\n", i, iret); + assert_zero(chmod(dirname, S_IRUSR | S_IRGRP | S_IROTH), + "i:%d chmod((%s) read-only != 0 (%d: %s)\n", i, dirname, errno, strerror(errno)); + ret = zint_out_fopen(outfile, "w"); + assert_null(ret, "i:%d zint_out_fopen(%s) != NULL (%d: %s)\n", + i, outfile, errno, strerror(errno)); + assert_zero(testUtilRmDir(dirname), "i:%d rmdir(%s) != 0 (%d: %s)\n", + i, dirname, errno, strerror(errno)); + } +#endif } } } else { @@ -421,8 +553,10 @@ int main(int argc, char *argv[]) { { "test_check_colour_options", test_check_colour_options }, { "test_colour_get_rgb", test_colour_get_rgb }, { "test_colour_get_cmyk", test_colour_get_cmyk }, + { "test_colour_char_to_rgb", test_colour_char_to_rgb }, { "test_quiet_zones", test_quiet_zones }, { "test_set_whitespace_offsets", test_set_whitespace_offsets }, + { "test_out_maybe_mkdir", test_out_maybe_mkdir }, { "test_fopen", test_fopen }, }; diff --git a/backend/tests/test_pcx.c b/backend/tests/test_pcx.c index 29c69dbe..7db3bb16 100644 --- a/backend/tests/test_pcx.c +++ b/backend/tests/test_pcx.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020-2025 Robin Stuart + Copyright (C) 2020-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -221,11 +221,71 @@ static void test_outfile(const testCtx *const p_ctx) { testFinish(); } +#include "filemem.h" + +static void test_fm(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + const char *data; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_ACCESS, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_OPEN }, + /* 1*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_WRITE }, + /* 3*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 2, 40, 200, 0 }, 4, FM_FAIL_ID_PUTC }, + /* 5*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, "out.pcx"); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_fm_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ { "test_print", test_print }, { "test_outfile", test_outfile }, + { "test_fm", test_fm }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_pdf417.c b/backend/tests/test_pdf417.c index 5c073b70..e716c623 100644 --- a/backend/tests/test_pdf417.c +++ b/backend/tests/test_pdf417.c @@ -319,7 +319,8 @@ static void test_reader_init(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", - i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), testUtilOutputOptionsName(data[i].output_options), + i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), + testUtilOutputOptionsName(data[i].output_options), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment); } else { @@ -471,6 +472,8 @@ static void test_input(const testCtx *const p_ctx) { /* 88*/ { BARCODE_PDF417, DATA_MODE, -1, -1, -1, { 0, 0, "" }, "12345678901234567890", 0, 0, 9, 103, "(18) 10 902 211 358 354 304 269 753 190 900 327 902 163 367 231 586 808 731", 1, "" }, /* 89*/ { BARCODE_PDF417, DATA_MODE | FAST_MODE, -1, -1, -1, { 0, 0, "" }, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, 0, 12, 137, "(48) 40 902 491 81 137 450 302 67 15 174 492 862 667 475 869 12 434 685 326 422 57 117 339", 1, "" }, /* 90*/ { BARCODE_PDF417, DATA_MODE, -1, -1, -1, { 0, 0, "" }, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, 0, 12, 137, "(48) 40 902 491 81 137 450 302 67 15 174 492 862 667 475 869 12 434 685 326 422 57 117 339", 1, "" }, + /* 91*/ { BARCODE_PDF417, DATA_MODE | FAST_MODE, -1, -1, -1, { 0, 0, "" }, "12345678901;;;;;; ", 0, 0, 8, 120, "(24) 16 902 154 98 332 101 900 865 0 0 0 896 806 806 900 900 455 477 237 629 768 622 623", 0, "BWIPP: different encodation, see below" }, + /* 92*/ { BARCODE_PDF417, DATA_MODE, -1, -1, -1, { 0, 0, "" }, "12345678901;;;;;; ", 0, 0, 8, 120, "(24) 16 841 63 125 187 249 1 750 0 0 29 806 806 809 900 900 105 646 736 649 641 551 905 630", 1, "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -508,7 +511,8 @@ static void test_input(const testCtx *const p_ctx) { i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { - printf(" /*%3d*/ { %s, %s, %d, %d, %d, { %d, %d, \"%s\" }, \"%s\", %s, %d, %d, %d, \"%s\", %d, \"%s\" },\n", + printf(" /*%3d*/ { %s, %s, %d, %d, %d, { %d, %d, \"%s\" }, \"%s\", %s, %d, %d, %d, \"%s\", %d" + ", \"%s\" },\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].eci, data[i].option_1, data[i].option_2, data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, @@ -4871,7 +4875,8 @@ static void test_encode_segs(const testCtx *const p_ctx) { data[i].segs[0].length, debug)) { if ((data[i].input_mode & 0x07) == DATA_MODE) { if (debug & ZINT_DEBUG_TEST_PRINT) { - printf("i:%d %s multiple segments in DATA_MODE not currently supported for ZXing-C++ testing\n", + printf("i:%d %s multiple segments in DATA_MODE not currently supported" + " for ZXing-C++ testing\n", i, testUtilBarcodeName(symbol->symbology)); } } else { @@ -4887,9 +4892,10 @@ static void test_encode_segs(const testCtx *const p_ctx) { ret = testUtilZXingCPPCmpSegs(symbol, cmp_msg, cmp_buf, cmp_len, data[i].segs, seg_count, NULL /*primary*/, escaped, &ret_len); - assert_zero(ret, "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, - escaped); + assert_zero(ret, + "i:%d %s testUtilZXingCPPCmpSegs %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, + ret_len, escaped); } } } @@ -4984,7 +4990,7 @@ static void test_rt(const testCtx *const p_ctx) { i, symbol->content_segs[0].length, expected_length); assert_zero(memcmp(symbol->content_segs[0].source, data[i].expected, expected_length), "i:%d content_segs[0].source memcmp(%s, %s, %d) != 0\n", i, - testUtilEscape((const char *) symbol->content_segs[0].source, symbol->content_segs[0].length, + testUtilEscape(ZCCP(symbol->content_segs[0].source), symbol->content_segs[0].length, escaped, sizeof(escaped)), testUtilEscape(data[i].expected, expected_length, escaped2, sizeof(escaped2)), expected_length); @@ -5066,8 +5072,9 @@ static void test_rt_segs(const testCtx *const p_ctx) { assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); - assert_equal(symbol->content_seg_count, data[i].expected_content_seg_count, "i:%d symbol->content_seg_count %d != %d\n", - i, symbol->content_seg_count, data[i].expected_content_seg_count); + assert_equal(symbol->content_seg_count, data[i].expected_content_seg_count, + "i:%d symbol->content_seg_count %d != %d\n", + i, symbol->content_seg_count, data[i].expected_content_seg_count); if (symbol->output_options & BARCODE_CONTENT_SEGS) { assert_nonnull(symbol->content_segs, "i:%d content_segs NULL\n", i); for (j = 0; j < symbol->content_seg_count; j++) { @@ -5078,7 +5085,8 @@ static void test_rt_segs(const testCtx *const p_ctx) { assert_equal(symbol->content_segs[j].length, expected_length, "i:%d content_segs[%d].length %d != expected_length %d\n", i, j, symbol->content_segs[j].length, expected_length); - assert_zero(memcmp(symbol->content_segs[j].source, data[i].expected_content_segs[j].source, expected_length), + assert_zero(memcmp(symbol->content_segs[j].source, data[i].expected_content_segs[j].source, + expected_length), "i:%d content_segs[%d].source memcmp(%s, %s, %d) != 0\n", i, j, testUtilEscape((const char *) symbol->content_segs[j].source, expected_length, escaped, sizeof(escaped)), diff --git a/backend/tests/test_png.c b/backend/tests/test_png.c index 3801cd96..18f4ea78 100644 --- a/backend/tests/test_png.c +++ b/backend/tests/test_png.c @@ -137,6 +137,7 @@ static void test_print(const testCtx *const p_ctx) { int option_2; float height; float scale; + float dpmm; struct zint_structapp structapp; const char *fgcolour; const char *bgcolour; @@ -148,135 +149,136 @@ static void test_print(const testCtx *const p_ctx) { const char *comment; }; static const struct item data[] = { - /* 0*/ { BARCODE_CODE128, UNICODE_MODE, -1, -1, -1, -1, -1, -1, -1, 10.0, 0, { 0, 0, "" }, "", "", 1, "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", "", 0, "code128_latin1_1.png", "" }, - /* 1*/ { BARCODE_CODE128, UNICODE_MODE, -1, -1, -1, -1, -1, -1, -1, 10.0, 0, { 0, 0, "" }, "", "", 1, "¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", "", 0, "code128_latin1_2.png", "" }, - /* 2*/ { BARCODE_CODE128, UNICODE_MODE, -1, BOLD_TEXT, -1, -1, -1, -1, -1, 10.0, 0, { 0, 0, "" }, "", "", 1, "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", "", 0, "code128_latin1_1_bold.png", "" }, - /* 3*/ { BARCODE_CODE128, UNICODE_MODE, -1, BOLD_TEXT, -1, -1, -1, -1, -1, 10.0, 0, { 0, 0, "" }, "", "", 1, "¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", "", 0, "code128_latin1_2_bold.png", "" }, - /* 4*/ { BARCODE_CODE128, UNICODE_MODE, -1, SMALL_TEXT, -1, -1, -1, -1, -1, 10.0, 0, { 0, 0, "" }, "", "", 1, "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", "", 0, "code128_latin1_1_small.png", "" }, - /* 5*/ { BARCODE_CODE128, UNICODE_MODE, -1, SMALL_TEXT, -1, -1, -1, -1, -1, 10.0, 0, { 0, 0, "" }, "", "", 1, "¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", "", 0, "code128_latin1_2_small.png", "" }, - /* 6*/ { BARCODE_CODE128, UNICODE_MODE, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "Égjpqy", "", 0, "code128_egrave.png", "" }, - /* 7*/ { BARCODE_CODE128, UNICODE_MODE, -1, BOLD_TEXT, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "Égjpqy", "", 0, "code128_egrave_bold.png", "" }, - /* 8*/ { BARCODE_CODE128, UNICODE_MODE, 3, BOLD_TEXT | BARCODE_BOX, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "Égjpqy", "", 0, "code128_egrave_bold_box3.png", "" }, - /* 9*/ { BARCODE_CODE128, UNICODE_MODE, 2, BOLD_TEXT | BARCODE_BOX, 2, 2, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "Égjpqy", "", 0, "code128_egrave_bold_hvwsp2_box2.png", "" }, - /* 10*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, -1, 3, -1, 0, 0, { 0, 0, "" }, "", "", 1, "[00]030123456789012340", "[02]13012345678909[37]24[10]1234567ABCDEFG", 0, "gs1_128_cc_fig12.png", "" }, - /* 11*/ { BARCODE_CODABLOCKF, -1, 3, -1, -1, -1, -1, 3, -1, 0, 0, { 0, 0, "" }, "", "", 1, "AAAAAAAAA", "", 0, "codablockf_3rows.png", "" }, - /* 12*/ { BARCODE_CODABLOCKF, -1, -1, -1, 2, 2, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "AAAAAAAAA", "", 0, "codablockf_hvwsp2.png", "" }, - /* 13*/ { BARCODE_CODABLOCKF, -1, 2, BARCODE_BOX, 2, 2, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "AAAAAAAAA", "", 0, "codablockf_hvwsp2_box2.png", "" }, - /* 14*/ { BARCODE_EAN13, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9771384524017", "", 0, "ean13_ggs_5.2.2.1-1.png", "" }, - /* 15*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9771384524017", "", 0, "ean13_ggs_5.2.2.1-1.png", "" }, - /* 16*/ { BARCODE_EAN13, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9771384524017", "", 0, "ean13_ggs_5.2.2.1-1_gws.png", "" }, - /* 17*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9771384524017", "", 0, "ean13_ggs_5.2.2.1-1_gws.png", "" }, - /* 18*/ { BARCODE_EAN13, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9771384524017+12", "", 0, "ean13_2addon_ggs_5.2.2.5.1-2.png", "" }, - /* 19*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9771384524017+12", "", 0, "ean13_2addon_ggs_5.2.2.5.1-2.png", "" }, - /* 20*/ { BARCODE_EAN13, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9771384524017+12", "", 0, "ean13_2addon_ggs_5.2.2.5.1-2_gws.png", "" }, - /* 21*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9771384524017+12", "", 0, "ean13_2addon_ggs_5.2.2.5.1-2_gws.png", "" }, - /* 22*/ { BARCODE_EAN13, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9780877799306+54321", "", 0, "ean13_5addon_ggs_5.2.2.5.2-2.png", "" }, - /* 23*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9780877799306+54321", "", 0, "ean13_5addon_ggs_5.2.2.5.2-2.png", "" }, - /* 24*/ { BARCODE_EAN13, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9780877799306+54321", "", 0, "ean13_5addon_ggs_5.2.2.5.2-2_gws.png", "" }, - /* 25*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9780877799306+54321", "", 0, "ean13_5addon_ggs_5.2.2.5.2-2_gws.png", "" }, - /* 26*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012", "[91]12345678901234567890123456789", 0, "ean13_cc_cca_5x4.png", "" }, - /* 27*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012", "[91]12345678901234567890123456789", 0, "ean13_cc_cca_5x4.png", "" }, - /* 28*/ { BARCODE_EAN13_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012", "[91]12345678901234567890123456789", 0, "ean13_cc_cca_5x4_gws.png", "" }, - /* 29*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012", "[91]12345678901234567890123456789", 0, "ean13_cc_cca_5x4_gws.png", "" }, - /* 30*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+12", "[91]123456789012345678901", 0, "ean13_cc_2addon_cca_4x4.png", "" }, - /* 31*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+12", "[91]123456789012345678901", 0, "ean13_cc_2addon_cca_4x4.png", "" }, - /* 32*/ { BARCODE_EAN13_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+12", "[91]123456789012345678901", 0, "ean13_cc_2addon_cca_4x4_gws.png", "" }, - /* 33*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+12", "[91]123456789012345678901", 0, "ean13_cc_2addon_cca_4x4_gws.png", "" }, - /* 34*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4.png", "" }, - /* 35*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4.png", "" }, - /* 36*/ { BARCODE_EAN13_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4_gws.png", "" }, - /* 37*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4_gws.png", "" }, - /* 38*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4_notext.png", "" }, - /* 39*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4_notext.png", "" }, - /* 40*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "012345678905+24", "", 0, "upca_2addon_ggs_5.2.6.6-5.png", "" }, - /* 41*/ { BARCODE_UPCA, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "012345678905+24", "", 0, "upca_2addon_ggs_5.2.6.6-5_gws.png", "" }, - /* 42*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "614141234417+12345", "", 0, "upca_5addon.png", "" }, - /* 43*/ { BARCODE_UPCA, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "614141234417+12345", "", 0, "upca_5addon_gws.png", "" }, - /* 44*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, 0, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "614141234417+12345", "", 0, "upca_5addon_notext.png", "" }, - /* 45*/ { BARCODE_UPCA, -1, 3, BARCODE_BIND, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "614141234417+12345", "", 0, "upca_5addon_bind3.png", "" }, - /* 46*/ { BARCODE_UPCA, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, -1, -1, -1, 1, 0, { 0, 0, "" }, "", "", 1, "012345678905+24", "", 0, "upca_2addon_h1.png", "" }, - /* 47*/ { BARCODE_UPCA, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, 0, -1, -1, 1, 0, { 0, 0, "" }, "", "", 1, "012345678905+24", "", 0, "upca_2addon_h1_notext.png", "" }, - /* 48*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345678901+12", "[91]123456789", 0, "upca_cc_2addon_cca_3x4.png", "" }, - /* 49*/ { BARCODE_UPCA_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345678901+12", "[91]123456789", 0, "upca_cc_2addon_cca_3x4_gws.png", "" }, - /* 50*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345678901+12121", "[91]1234567890123", 0, "upca_cc_5addon_ccb_4x4.png", "" }, - /* 51*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, 0, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345678901+12121", "[91]1234567890123", 0, "upca_cc_5addon_ccb_4x4_notext.png", "" }, - /* 52*/ { BARCODE_UPCA_CC, -1, 3, BARCODE_BIND, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345678901+12121", "[91]1234567890123", 0, "upca_cc_5addon_ccb_4x4_bind3.png", "" }, - /* 53*/ { BARCODE_UPCE, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12", "", 0, "upce_2addon.png", "" }, - /* 54*/ { BARCODE_UPCE, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12", "", 0, "upce_2addon_gws.png", "" }, - /* 55*/ { BARCODE_UPCE, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12345", "", 0, "upce_5addon.png", "" }, - /* 56*/ { BARCODE_UPCE, -1, -1, SMALL_TEXT, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12345", "", 0, "upce_5addon_small.png", "" }, - /* 57*/ { BARCODE_UPCE, -1, -1, SMALL_TEXT | EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12345", "", 0, "upce_5addon_small_gws.png", "" }, - /* 58*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "0654321+89", "[91]1", 0, "upce_cc_2addon_cca_5x2.png", "" }, - /* 59*/ { BARCODE_UPCE_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "0654321+89", "[91]1", 0, "upce_cc_2addon_cca_5x2_gws.png", "" }, - /* 60*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, -1, 1, -1, 3, 0, { 0, 0, "" }, "", "", 1, "0654321+89", "[91]1", 0, "upce_cc_2addon_h3.png", "" }, - /* 61*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0, 1, -1, 3, 0, { 0, 0, "" }, "", "", 1, "0654321+89", "[91]1", 0, "upce_cc_2addon_h3_notext.png", "" }, - /* 62*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1876543+56789", "[91]12345", 0, "upce_cc_5addon_ccb_8x2.png", "" }, - /* 63*/ { BARCODE_UPCE_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1876543+56789", "[91]12345", 0, "upce_cc_5addon_ccb_8x2_gws.png", "" }, - /* 64*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1876543+56789", "[91]12345", 0, "upce_cc_5addon_ccb_8x2_notext.png", "" }, - /* 65*/ { BARCODE_EAN8, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567", "", 0, "ean8_gss_5.2.2.2-1.png", "" }, - /* 66*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567", "", 0, "ean8_gss_5.2.2.2-1.png", "" }, - /* 67*/ { BARCODE_EAN8, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567", "", 0, "ean8_gss_5.2.2.2-1_gws.png", "" }, - /* 68*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567", "", 0, "ean8_gss_5.2.2.2-1_gws.png", "" }, - /* 69*/ { BARCODE_EAN8, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon.png", "" }, - /* 70*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon.png", "" }, - /* 71*/ { BARCODE_EAN8, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_gws.png", "" }, - /* 72*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_gws.png", "" }, - /* 73*/ { BARCODE_EAN8, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, -1, -1, -1, 1, 0, { 0, 0, "" }, "", "", 1, " 16", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_h1.png", "" }, - /* 74*/ { BARCODE_EANX, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, -1, -1, -1, 1, 0, { 0, 0, "" }, "", "", 1, " 16", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_h1.png", "" }, - /* 75*/ { BARCODE_EAN8, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, 0, -1, -1, 1, 0, { 0, 0, "" }, "", "", 1, " 16", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_h1_notext.png", "" }, - /* 76*/ { BARCODE_EANX, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, 0, -1, -1, 1, 0, { 0, 0, "" }, "", "", 1, " 16", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_h1_notext.png", "" }, - /* 77*/ { BARCODE_EAN8, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12345", "", ZINT_WARN_NONCOMPLIANT, "ean8_5addon.png", "" }, - /* 78*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12345", "", ZINT_WARN_NONCOMPLIANT, "ean8_5addon.png", "" }, - /* 79*/ { BARCODE_EAN8, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12345", "", ZINT_WARN_NONCOMPLIANT, "ean8_5addon_gws.png", "" }, - /* 80*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "1234567+12345", "", ZINT_WARN_NONCOMPLIANT, "ean8_5addon_gws.png", "" }, - /* 81*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9876543+65", "[91]1234567", ZINT_WARN_NONCOMPLIANT, "ean8_cc_2addon_cca_4x3.png", "" }, - /* 82*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9876543+65", "[91]1234567", ZINT_WARN_NONCOMPLIANT, "ean8_cc_2addon_cca_4x3.png", "" }, - /* 83*/ { BARCODE_EAN8_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9876543+65", "[91]1234567", ZINT_WARN_NONCOMPLIANT, "ean8_cc_2addon_cca_4x3_gws.png", "" }, - /* 84*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9876543+65", "[91]1234567", ZINT_WARN_NONCOMPLIANT, "ean8_cc_2addon_cca_4x3_gws.png", "" }, - /* 85*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9876543+74083", "[91]123456789012345678", ZINT_WARN_NONCOMPLIANT, "ean8_cc_5addon_ccb_8x3.png", "" }, - /* 86*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9876543+74083", "[91]123456789012345678", ZINT_WARN_NONCOMPLIANT, "ean8_cc_5addon_ccb_8x3.png", "" }, - /* 87*/ { BARCODE_EAN8_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9876543+74083", "[91]123456789012345678", ZINT_WARN_NONCOMPLIANT, "ean8_cc_5addon_ccb_8x3_gws.png", "" }, - /* 88*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0, 0, { 0, 0, "" }, "", "", 1, "9876543+74083", "[91]123456789012345678", ZINT_WARN_NONCOMPLIANT, "ean8_cc_5addon_ccb_8x3_gws.png", "" }, - /* 89*/ { BARCODE_EAN_5ADDON, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5.png", "" }, - /* 90*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5.png", "" }, - /* 91*/ { BARCODE_EAN_5ADDON, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5_gws.png", "" }, - /* 92*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5_gws.png", "" }, - /* 93*/ { BARCODE_EAN_5ADDON, -1, 2, BARCODE_BIND, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5_bind2.png", "" }, - /* 94*/ { BARCODE_EANX, -1, 2, BARCODE_BIND, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5_bind2.png", "" }, - /* 95*/ { BARCODE_EAN_2ADDON, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2.png", "" }, - /* 96*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2.png", "" }, - /* 97*/ { BARCODE_EAN_2ADDON, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2_gws.png", "" }, - /* 98*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2_gws.png", "" }, - /* 99*/ { BARCODE_EAN_2ADDON, -1, 1, BARCODE_BOX, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2_box1.png", "" }, - /*100*/ { BARCODE_EANX, -1, 1, BARCODE_BOX, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2_box1.png", "" }, - /*101*/ { BARCODE_CODE39, -1, -1, SMALL_TEXT, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "123", "", 0, "code39_small.png", "" }, - /*102*/ { BARCODE_POSTNET, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3.5, { 0, 0, "" }, "", "", 1, "12345", "", 0, "postnet_zip.png", "300 dpi, using 1/43in X, 300 / 43 / 2 = ~3.5 scale" }, - /*103*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "CFCECDCC", 1, "12345", "", 0, "pdf417_bgalpha.png", "" }, - /*104*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "30313233", "", 1, "12345", "", 0, "pdf417_fgalpha.png", "" }, - /*105*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "20212244", "CFCECDCC", 1, "12345", "", 0, "pdf417_bgfgalpha.png", "" }, - /*106*/ { BARCODE_ULTRA, -1, -1, -1, 2, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "0000007F", "FF000033", 1, "12345", "", 0, "ultra_bgfgalpha.png", "" }, - /*107*/ { BARCODE_ULTRA, -1, -1, -1, 2, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "FF000033", 1, "12345", "", 0, "ultra_bgalpha.png", "" }, - /*108*/ { BARCODE_ULTRA, -1, -1, -1, 2, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "0000007F", "FF0000", 1, "12345", "", 0, "ultra_fgalpha.png", "" }, - /*109*/ { BARCODE_ULTRA, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "0000007F", "", 1, "12345", "", 0, "ultra_fgalpha_nobg.png", "" }, - /*110*/ { BARCODE_ULTRA, -1, 1, BARCODE_BOX, 1, 1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ultra_hvwsp1_box1.png", "" }, - /*111*/ { BARCODE_ULTRA, -1, 1, BARCODE_BOX, 1, 1, -1, -1, -1, 0, 0, { 0, 0, "" }, "00FF007F", "BABDB6", 1, "12345", "", 0, "ultra_fgalpha_hvwsp1_box1.png", "" }, - /*112*/ { BARCODE_ULTRA, -1, 1, BARCODE_BIND_TOP, 1, 1, -1, -1, -1, 0, 0, { 0, 0, "" }, "00FF007F", "BABDB6", 1, "12345", "", 0, "ultra_fgalpha_hvwsp1_bindtop1.png", "" }, - /*113*/ { BARCODE_ULTRA, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0.5, { 0, 0, "" }, "", "", 1, "1", "", 0, "ultra_odd.png", "" }, - /*114*/ { BARCODE_MAXICODE, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0.5, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_0.5.png", "6 dpmm, 150 dpi" }, - /*115*/ { BARCODE_MAXICODE, -1, 1, BARCODE_BOX, 3, -1, -1, -1, -1, 0, 0.7, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_0.7_wsp3_box1.png", "8 dpmm, 200 dpi" }, - /*116*/ { BARCODE_MAXICODE, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1.4, { 0, 0, "" }, "1111117F", "EEEEEEEE", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_1.4_bgfgalpha.png", "16 dpmm, 400 dpi" }, - /*117*/ { BARCODE_MAXICODE, -1, -1, -1, -1, -1, -1, -1, -1, 0, 2.1, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_2.1.png", "24 dpmm, 600 dpi" }, - /*118*/ { BARCODE_MAXICODE, -1, 2, BARCODE_BOX, 1, 1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_hvwsp1_box2.png", "" }, - /*119*/ { BARCODE_MAXICODE, -1, 1, BARCODE_BIND, -1, 1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_vwsp1_bind1.png", "" }, - /*120*/ { BARCODE_DATAMATRIX, -1, 1, BARCODE_BIND | BARCODE_DOTTY_MODE, -1, -1, -1, -1, -1, 0, 2.0, { 0, 0, "" }, "", "", 1, "1234", "", 0, "datamatrix_2.0_bind1_dotty.png", "" }, - /*121*/ { BARCODE_DATAMATRIX, -1, 1, BARCODE_BIND | BARCODE_DOTTY_MODE, 1, 1, -1, -1, -1, 0, 2.0, { 0, 0, "" }, "", "", 1, "1234", "", 0, "datamatrix_2.0_hvwsp1_bind1_dotty.png", "" }, - /*122*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "12345678909", "", 0, "dbar_ltd.png", "" }, - /*123*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, -1, -1, 5.0, 0, { 0, 0, "" }, "", "", 1, "Your Data Here!", "", ZINT_WARN_NONCOMPLIANT, "pdf417_height5.png", "" }, - /*124*/ { BARCODE_USPS_IMAIL, -1, -1, -1, -1, -1, -1, -1, -1, 7.75, 0, { 0, 0, "" }, "", "", 1, "12345678901234567890", "", 0, "imail_height7.75.png", "" }, - /*125*/ { BARCODE_AZTEC, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, { 4, 7, "Z1.txt" }, "", "", 1, "3456", "", 0, "aztec_z1_seq4of7.png", "" }, - /*126*/ { BARCODE_PDF417, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, -1, 5, 8, 16, 1.5, { 0, 0, "" }, "", "", 1, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "", ZINT_WARN_NONCOMPLIANT, "pdf417_#204.png", "Ticket #204 Blank line in PDF417" }, - /*127*/ { BARCODE_DPD, -1, -1, BARCODE_QUIET_ZONES | COMPLIANT_HEIGHT, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "", "", 1, "008182709980000020028101276", "", 0, "dpd_compliant.png", "Now with bind top 3X default" }, - /*128*/ { BARCODE_CHANNEL, -1, -1, CMYK_COLOUR | COMPLIANT_HEIGHT, -1, -1, -1, -1, -1, 0, 0, { 0, 0, "" }, "100,85,0,20", "FFFFFF00", 1, "123", "", 0, "channel_cmyk_nobg.png", "" }, + /* 0*/ { BARCODE_CODE128, UNICODE_MODE, -1, -1, -1, -1, -1, -1, -1, 10.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", "", 0, "code128_latin1_1.png", "" }, + /* 1*/ { BARCODE_CODE128, UNICODE_MODE, -1, -1, -1, -1, -1, -1, -1, 10.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", "", 0, "code128_latin1_2.png", "" }, + /* 2*/ { BARCODE_CODE128, UNICODE_MODE, -1, BOLD_TEXT, -1, -1, -1, -1, -1, 10.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", "", 0, "code128_latin1_1_bold.png", "" }, + /* 3*/ { BARCODE_CODE128, UNICODE_MODE, -1, BOLD_TEXT, -1, -1, -1, -1, -1, 10.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", "", 0, "code128_latin1_2_bold.png", "" }, + /* 4*/ { BARCODE_CODE128, UNICODE_MODE, -1, SMALL_TEXT, -1, -1, -1, -1, -1, 10.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", "", 0, "code128_latin1_1_small.png", "" }, + /* 5*/ { BARCODE_CODE128, UNICODE_MODE, -1, SMALL_TEXT, -1, -1, -1, -1, -1, 10.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", "", 0, "code128_latin1_2_small.png", "" }, + /* 6*/ { BARCODE_CODE128, UNICODE_MODE, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "Égjpqy", "", 0, "code128_egrave.png", "" }, + /* 7*/ { BARCODE_CODE128, UNICODE_MODE, -1, BOLD_TEXT, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "Égjpqy", "", 0, "code128_egrave_bold.png", "" }, + /* 8*/ { BARCODE_CODE128, UNICODE_MODE, 3, BOLD_TEXT | BARCODE_BOX, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "Égjpqy", "", 0, "code128_egrave_bold_box3.png", "" }, + /* 9*/ { BARCODE_CODE128, UNICODE_MODE, 2, BOLD_TEXT | BARCODE_BOX, 2, 2, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "Égjpqy", "", 0, "code128_egrave_bold_hvwsp2_box2.png", "" }, + /* 10*/ { BARCODE_GS1_128_CC, -1, -1, -1, -1, -1, -1, 3, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "[00]030123456789012340", "[02]13012345678909[37]24[10]1234567ABCDEFG", 0, "gs1_128_cc_fig12.png", "" }, + /* 11*/ { BARCODE_CODABLOCKF, -1, 3, -1, -1, -1, -1, 3, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "AAAAAAAAA", "", 0, "codablockf_3rows.png", "" }, + /* 12*/ { BARCODE_CODABLOCKF, -1, -1, -1, 2, 2, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "AAAAAAAAA", "", 0, "codablockf_hvwsp2.png", "" }, + /* 13*/ { BARCODE_CODABLOCKF, -1, 2, BARCODE_BOX, 2, 2, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "AAAAAAAAA", "", 0, "codablockf_hvwsp2_box2.png", "" }, + /* 14*/ { BARCODE_EAN13, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9771384524017", "", 0, "ean13_ggs_5.2.2.1-1.png", "" }, + /* 15*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9771384524017", "", 0, "ean13_ggs_5.2.2.1-1.png", "" }, + /* 16*/ { BARCODE_EAN13, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9771384524017", "", 0, "ean13_ggs_5.2.2.1-1_gws.png", "" }, + /* 17*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9771384524017", "", 0, "ean13_ggs_5.2.2.1-1_gws.png", "" }, + /* 18*/ { BARCODE_EAN13, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9771384524017+12", "", 0, "ean13_2addon_ggs_5.2.2.5.1-2.png", "" }, + /* 19*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9771384524017+12", "", 0, "ean13_2addon_ggs_5.2.2.5.1-2.png", "" }, + /* 20*/ { BARCODE_EAN13, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9771384524017+12", "", 0, "ean13_2addon_ggs_5.2.2.5.1-2_gws.png", "" }, + /* 21*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9771384524017+12", "", 0, "ean13_2addon_ggs_5.2.2.5.1-2_gws.png", "" }, + /* 22*/ { BARCODE_EAN13, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9780877799306+54321", "", 0, "ean13_5addon_ggs_5.2.2.5.2-2.png", "" }, + /* 23*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9780877799306+54321", "", 0, "ean13_5addon_ggs_5.2.2.5.2-2.png", "" }, + /* 24*/ { BARCODE_EAN13, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9780877799306+54321", "", 0, "ean13_5addon_ggs_5.2.2.5.2-2_gws.png", "" }, + /* 25*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9780877799306+54321", "", 0, "ean13_5addon_ggs_5.2.2.5.2-2_gws.png", "" }, + /* 26*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012", "[91]12345678901234567890123456789", 0, "ean13_cc_cca_5x4.png", "" }, + /* 27*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012", "[91]12345678901234567890123456789", 0, "ean13_cc_cca_5x4.png", "" }, + /* 28*/ { BARCODE_EAN13_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012", "[91]12345678901234567890123456789", 0, "ean13_cc_cca_5x4_gws.png", "" }, + /* 29*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012", "[91]12345678901234567890123456789", 0, "ean13_cc_cca_5x4_gws.png", "" }, + /* 30*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+12", "[91]123456789012345678901", 0, "ean13_cc_2addon_cca_4x4.png", "" }, + /* 31*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+12", "[91]123456789012345678901", 0, "ean13_cc_2addon_cca_4x4.png", "" }, + /* 32*/ { BARCODE_EAN13_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+12", "[91]123456789012345678901", 0, "ean13_cc_2addon_cca_4x4_gws.png", "" }, + /* 33*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+12", "[91]123456789012345678901", 0, "ean13_cc_2addon_cca_4x4_gws.png", "" }, + /* 34*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4.png", "" }, + /* 35*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4.png", "" }, + /* 36*/ { BARCODE_EAN13_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4_gws.png", "" }, + /* 37*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4_gws.png", "" }, + /* 38*/ { BARCODE_EAN13_CC, -1, -1, -1, -1, -1, 0, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4_notext.png", "" }, + /* 39*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, 0, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123456789012+54321", "[91]1234567890", 0, "ean13_cc_5addon_ccb_3x4_notext.png", "" }, + /* 40*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "012345678905+24", "", 0, "upca_2addon_ggs_5.2.6.6-5.png", "" }, + /* 41*/ { BARCODE_UPCA, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "012345678905+24", "", 0, "upca_2addon_ggs_5.2.6.6-5_gws.png", "" }, + /* 42*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "614141234417+12345", "", 0, "upca_5addon.png", "" }, + /* 43*/ { BARCODE_UPCA, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "614141234417+12345", "", 0, "upca_5addon_gws.png", "" }, + /* 44*/ { BARCODE_UPCA, -1, -1, -1, -1, -1, 0, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "614141234417+12345", "", 0, "upca_5addon_notext.png", "" }, + /* 45*/ { BARCODE_UPCA, -1, 3, BARCODE_BIND, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "614141234417+12345", "", 0, "upca_5addon_bind3.png", "" }, + /* 46*/ { BARCODE_UPCA, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, -1, -1, -1, 1.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "012345678905+24", "", 0, "upca_2addon_h1.png", "" }, + /* 47*/ { BARCODE_UPCA, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, 0, -1, -1, 1.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "012345678905+24", "", 0, "upca_2addon_h1_notext.png", "" }, + /* 48*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345678901+12", "[91]123456789", 0, "upca_cc_2addon_cca_3x4.png", "" }, + /* 49*/ { BARCODE_UPCA_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345678901+12", "[91]123456789", 0, "upca_cc_2addon_cca_3x4_gws.png", "" }, + /* 50*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345678901+12121", "[91]1234567890123", 0, "upca_cc_5addon_ccb_4x4.png", "" }, + /* 51*/ { BARCODE_UPCA_CC, -1, -1, -1, -1, -1, 0, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345678901+12121", "[91]1234567890123", 0, "upca_cc_5addon_ccb_4x4_notext.png", "" }, + /* 52*/ { BARCODE_UPCA_CC, -1, 3, BARCODE_BIND, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345678901+12121", "[91]1234567890123", 0, "upca_cc_5addon_ccb_4x4_bind3.png", "" }, + /* 53*/ { BARCODE_UPCE, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12", "", 0, "upce_2addon.png", "" }, + /* 54*/ { BARCODE_UPCE, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12", "", 0, "upce_2addon_gws.png", "" }, + /* 55*/ { BARCODE_UPCE, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12345", "", 0, "upce_5addon.png", "" }, + /* 56*/ { BARCODE_UPCE, -1, -1, SMALL_TEXT, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12345", "", 0, "upce_5addon_small.png", "" }, + /* 57*/ { BARCODE_UPCE, -1, -1, SMALL_TEXT | EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12345", "", 0, "upce_5addon_small_gws.png", "" }, + /* 58*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "0654321+89", "[91]1", 0, "upce_cc_2addon_cca_5x2.png", "" }, + /* 59*/ { BARCODE_UPCE_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "0654321+89", "[91]1", 0, "upce_cc_2addon_cca_5x2_gws.png", "" }, + /* 60*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, -1, 1, -1, 3.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "0654321+89", "[91]1", 0, "upce_cc_2addon_h3.png", "" }, + /* 61*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0, 1, -1, 3.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "0654321+89", "[91]1", 0, "upce_cc_2addon_h3_notext.png", "" }, + /* 62*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1876543+56789", "[91]12345", 0, "upce_cc_5addon_ccb_8x2.png", "" }, + /* 63*/ { BARCODE_UPCE_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1876543+56789", "[91]12345", 0, "upce_cc_5addon_ccb_8x2_gws.png", "" }, + /* 64*/ { BARCODE_UPCE_CC, -1, -1, -1, -1, -1, 0, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1876543+56789", "[91]12345", 0, "upce_cc_5addon_ccb_8x2_notext.png", "" }, + /* 65*/ { BARCODE_EAN8, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567", "", 0, "ean8_gss_5.2.2.2-1.png", "" }, + /* 66*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567", "", 0, "ean8_gss_5.2.2.2-1.png", "" }, + /* 67*/ { BARCODE_EAN8, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567", "", 0, "ean8_gss_5.2.2.2-1_gws.png", "" }, + /* 68*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567", "", 0, "ean8_gss_5.2.2.2-1_gws.png", "" }, + /* 69*/ { BARCODE_EAN8, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon.png", "" }, + /* 70*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon.png", "" }, + /* 71*/ { BARCODE_EAN8, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_gws.png", "" }, + /* 72*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_gws.png", "" }, + /* 73*/ { BARCODE_EAN8, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, -1, -1, -1, 1.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, " 16", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_h1.png", "" }, + /* 74*/ { BARCODE_EANX, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, -1, -1, -1, 1.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, " 16", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_h1.png", "" }, + /* 75*/ { BARCODE_EAN8, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, 0, -1, -1, 1.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, " 16", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_h1_notext.png", "" }, + /* 76*/ { BARCODE_EANX, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, 0, -1, -1, 1.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, " 16", "", ZINT_WARN_NONCOMPLIANT, "ean8_2addon_h1_notext.png", "" }, + /* 77*/ { BARCODE_EAN8, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12345", "", ZINT_WARN_NONCOMPLIANT, "ean8_5addon.png", "" }, + /* 78*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12345", "", ZINT_WARN_NONCOMPLIANT, "ean8_5addon.png", "" }, + /* 79*/ { BARCODE_EAN8, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12345", "", ZINT_WARN_NONCOMPLIANT, "ean8_5addon_gws.png", "" }, + /* 80*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234567+12345", "", ZINT_WARN_NONCOMPLIANT, "ean8_5addon_gws.png", "" }, + /* 81*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9876543+65", "[91]1234567", ZINT_WARN_NONCOMPLIANT, "ean8_cc_2addon_cca_4x3.png", "" }, + /* 82*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9876543+65", "[91]1234567", ZINT_WARN_NONCOMPLIANT, "ean8_cc_2addon_cca_4x3.png", "" }, + /* 83*/ { BARCODE_EAN8_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9876543+65", "[91]1234567", ZINT_WARN_NONCOMPLIANT, "ean8_cc_2addon_cca_4x3_gws.png", "" }, + /* 84*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9876543+65", "[91]1234567", ZINT_WARN_NONCOMPLIANT, "ean8_cc_2addon_cca_4x3_gws.png", "" }, + /* 85*/ { BARCODE_EAN8_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9876543+74083", "[91]123456789012345678", ZINT_WARN_NONCOMPLIANT, "ean8_cc_5addon_ccb_8x3.png", "" }, + /* 86*/ { BARCODE_EANX_CC, -1, -1, -1, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9876543+74083", "[91]123456789012345678", ZINT_WARN_NONCOMPLIANT, "ean8_cc_5addon_ccb_8x3.png", "" }, + /* 87*/ { BARCODE_EAN8_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9876543+74083", "[91]123456789012345678", ZINT_WARN_NONCOMPLIANT, "ean8_cc_5addon_ccb_8x3_gws.png", "" }, + /* 88*/ { BARCODE_EANX_CC, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, 2, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "9876543+74083", "[91]123456789012345678", ZINT_WARN_NONCOMPLIANT, "ean8_cc_5addon_ccb_8x3_gws.png", "" }, + /* 89*/ { BARCODE_EAN_5ADDON, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5.png", "" }, + /* 90*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5.png", "" }, + /* 91*/ { BARCODE_EAN_5ADDON, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5_gws.png", "" }, + /* 92*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5_gws.png", "" }, + /* 93*/ { BARCODE_EAN_5ADDON, -1, 2, BARCODE_BIND, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5_bind2.png", "" }, + /* 94*/ { BARCODE_EANX, -1, 2, BARCODE_BIND, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ean5_bind2.png", "" }, + /* 95*/ { BARCODE_EAN_2ADDON, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2.png", "" }, + /* 96*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2.png", "" }, + /* 97*/ { BARCODE_EAN_2ADDON, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2_gws.png", "" }, + /* 98*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2_gws.png", "" }, + /* 99*/ { BARCODE_EAN_2ADDON, -1, 1, BARCODE_BOX, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2_box1.png", "" }, + /*100*/ { BARCODE_EANX, -1, 1, BARCODE_BOX, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12", "", 0, "ean2_box1.png", "" }, + /*101*/ { BARCODE_CODE39, -1, -1, SMALL_TEXT, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "123", "", 0, "code39_small.png", "" }, + /*102*/ { BARCODE_POSTNET, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 3.5f, 0.0f, { 0, 0, "" }, "", "", 1, "12345", "", 0, "postnet_zip.png", "300 dpi, using 1/43in X, 300 / 43 / 2 = ~3.5 scale" }, + /*103*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "CFCECDCC", 1, "12345", "", 0, "pdf417_bgalpha.png", "" }, + /*104*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "30313233", "", 1, "12345", "", 0, "pdf417_fgalpha.png", "" }, + /*105*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "20212244", "CFCECDCC", 1, "12345", "", 0, "pdf417_bgfgalpha.png", "" }, + /*106*/ { BARCODE_ULTRA, -1, -1, -1, 2, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "0000007F", "FF000033", 1, "12345", "", 0, "ultra_bgfgalpha.png", "" }, + /*107*/ { BARCODE_ULTRA, -1, -1, -1, 2, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "FF000033", 1, "12345", "", 0, "ultra_bgalpha.png", "" }, + /*108*/ { BARCODE_ULTRA, -1, -1, -1, 2, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "0000007F", "FF0000", 1, "12345", "", 0, "ultra_fgalpha.png", "" }, + /*109*/ { BARCODE_ULTRA, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "0000007F", "", 1, "12345", "", 0, "ultra_fgalpha_nobg.png", "" }, + /*110*/ { BARCODE_ULTRA, -1, 1, BARCODE_BOX, 1, 1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345", "", 0, "ultra_hvwsp1_box1.png", "" }, + /*111*/ { BARCODE_ULTRA, -1, 1, BARCODE_BOX, 1, 1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "00FF007F", "BABDB6", 1, "12345", "", 0, "ultra_fgalpha_hvwsp1_box1.png", "" }, + /*112*/ { BARCODE_ULTRA, -1, 1, BARCODE_BIND_TOP, 1, 1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "00FF007F", "BABDB6", 1, "12345", "", 0, "ultra_fgalpha_hvwsp1_bindtop1.png", "" }, + /*113*/ { BARCODE_ULTRA, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.5f, 0.0f, { 0, 0, "" }, "", "", 1, "1", "", 0, "ultra_odd.png", "" }, + /*114*/ { BARCODE_MAXICODE, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.5f, 0.0f, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_0.5.png", "6 dpmm, 150 dpi" }, + /*115*/ { BARCODE_MAXICODE, -1, 1, BARCODE_BOX, 3, -1, -1, -1, -1, 0.0f, 0.7f, 0.0f, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_0.7_wsp3_box1.png", "8 dpmm, 200 dpi" }, + /*116*/ { BARCODE_MAXICODE, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 1.4f, 0.0f, { 0, 0, "" }, "1111117F", "EEEEEEEE", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_1.4_bgfgalpha.png", "16 dpmm, 400 dpi" }, + /*117*/ { BARCODE_MAXICODE, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 2.1f, 0.0f, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_2.1.png", "24 dpmm, 600 dpi" }, + /*118*/ { BARCODE_MAXICODE, -1, 2, BARCODE_BOX, 1, 1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_hvwsp1_box2.png", "" }, + /*119*/ { BARCODE_MAXICODE, -1, 1, BARCODE_BIND, -1, 1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "", 0, "maxicode_vwsp1_bind1.png", "" }, + /*120*/ { BARCODE_DATAMATRIX, -1, 1, BARCODE_BIND | BARCODE_DOTTY_MODE, -1, -1, -1, -1, -1, 0.0f, 2.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234", "", 0, "datamatrix_2.0_bind1_dotty.png", "" }, + /*121*/ { BARCODE_DATAMATRIX, -1, 1, BARCODE_BIND | BARCODE_DOTTY_MODE, 1, 1, -1, -1, -1, 0.0f, 2.0f, 0.0f, { 0, 0, "" }, "", "", 1, "1234", "", 0, "datamatrix_2.0_hvwsp1_bind1_dotty.png", "" }, + /*122*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345678909", "", 0, "dbar_ltd.png", "" }, + /*123*/ { BARCODE_PDF417, -1, -1, -1, -1, -1, -1, -1, -1, 5.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "Your Data Here!", "", ZINT_WARN_NONCOMPLIANT, "pdf417_height5.png", "" }, + /*124*/ { BARCODE_USPS_IMAIL, -1, -1, -1, -1, -1, -1, -1, -1, 7.75f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "12345678901234567890", "", 0, "imail_height7.75.png", "" }, + /*125*/ { BARCODE_AZTEC, -1, -1, -1, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 4, 7, "Z1.txt" }, "", "", 1, "3456", "", 0, "aztec_z1_seq4of7.png", "" }, + /*126*/ { BARCODE_PDF417, -1, -1, BARCODE_NO_QUIET_ZONES, -1, -1, -1, 5, 8, 16.0f, 1.5f, 0.0f, { 0, 0, "" }, "", "", 1, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "", ZINT_WARN_NONCOMPLIANT, "pdf417_#204.png", "Ticket #204 Blank line in PDF417" }, + /*127*/ { BARCODE_DPD, -1, -1, BARCODE_QUIET_ZONES | COMPLIANT_HEIGHT, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "", "", 1, "008182709980000020028101276", "", 0, "dpd_compliant.png", "Now with bind top 3X default" }, + /*128*/ { BARCODE_CHANNEL, -1, -1, CMYK_COLOUR | COMPLIANT_HEIGHT, -1, -1, -1, -1, -1, 0.0f, 0.0f, 0.0f, { 0, 0, "" }, "100,85,0,20", "FFFFFF00", 1, "123", "", 0, "channel_cmyk_nobg.png", "" }, + /*129*/ { BARCODE_TELEPEN, UNICODE_MODE, -1, COMPLIANT_HEIGHT, -1, -1, -1, -1, -1, 0.0f, 0.0f, 300.0f / 25.4f, { 0, 0, "" }, "", "", 1, "ABC", "", 0, "telepen_compliant_dpmm_300dpi.png", "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -325,6 +327,11 @@ static void test_print(const testCtx *const p_ctx) { if (data[i].scale) { symbol->scale = data[i].scale; } + if (data[i].dpmm) { + symbol->dpmm = data[i].dpmm; + symbol->scale = ZBarcode_Scale_From_XdimDp(symbol->symbology, ZBarcode_Default_Xdim(symbol->symbology), + symbol->dpmm, "PNG"); + } if (data[i].border_width != -1) { symbol->border_width = data[i].border_width; } @@ -366,11 +373,12 @@ static void test_print(const testCtx *const p_ctx) { "i:%d testUtilDataPath == 0\n", i); if (p_ctx->generate) { - printf(" /*%3d*/ { %s, %s, %d, %s, %d, %d, %d, %d, %d, %.5g, %.5g, { %d, %d, \"%s\" }, \"%s\", \"%s\", %.5g, \"%s\", \"%s\", %s, \"%s\", \"%s\" },\n", + printf(" /*%3d*/ { %s, %s, %d, %s, %d, %d, %d, %d, %d, %.5g, %.5g, %.5g," + " { %d, %d, \"%s\" }, \"%s\", \"%s\", %.5g, \"%s\", \"%s\", %s, \"%s\", \"%s\" },\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].border_width, testUtilOutputOptionsName(data[i].output_options), data[i].whitespace_width, data[i].whitespace_height, data[i].show_hrt, - data[i].option_1, data[i].option_2, data[i].height, data[i].scale, + data[i].option_1, data[i].option_2, data[i].height, data[i].scale, data[i].dpmm, data[i].structapp.index, data[i].structapp.count, data[i].structapp.id, data[i].fgcolour, data[i].bgcolour, data[i].text_gap, testUtilEscape(data[i].data, length, escaped, escaped_size), data[i].composite, @@ -471,18 +479,19 @@ static void test_outfile(const testCtx *const p_ctx) { #include #include -struct wpng_error_type { +/* As defined in "png.c" */ +struct zpng_error_type { struct zint_symbol *symbol; jmp_buf jmpbuf; }; -INTERNAL void zint_test_wpng_error_handler(png_structp png_ptr, png_const_charp msg); +INTERNAL void zint_test_zpng_error_handler(png_structp png_ptr, png_const_charp msg); -static void test_wpng_error_handler(const testCtx *const p_ctx) { +static void test_zpng_error_handler(const testCtx *const p_ctx) { int ret; char filename[] = "out.png"; FILE *fp; - struct wpng_error_type wpng_error; + struct zpng_error_type zpng_error; struct zint_symbol symbol = {0}; png_structp png_ptr; png_infop info_ptr; @@ -491,7 +500,7 @@ static void test_wpng_error_handler(const testCtx *const p_ctx) { testStart(p_ctx->func_name); - wpng_error.symbol = &symbol; + zpng_error.symbol = &symbol; /* Create empty file */ (void) testUtilRemove(filename); /* In case junk hanging around */ @@ -504,13 +513,13 @@ static void test_wpng_error_handler(const testCtx *const p_ctx) { fp = testUtilOpen(filename, "r"); assert_nonnull(fp, "testUtilOpen(%s) for read failed\n", filename); - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &wpng_error, zint_test_wpng_error_handler, NULL); + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &zpng_error, zint_test_zpng_error_handler, NULL); assert_nonnull(png_ptr, "png_create_write_struct failed\n"); info_ptr = png_create_info_struct(png_ptr); assert_nonnull(info_ptr, "png_create_info_struct failed\n"); - if (setjmp(wpng_error.jmpbuf)) { + if (setjmp(zpng_error.jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); ret = fclose(fp); assert_zero(ret, "fclose(%s) %d != 0\n", filename, ret); @@ -527,6 +536,29 @@ static void test_wpng_error_handler(const testCtx *const p_ctx) { testFinish(); } +static void test_zpng_flush(const testCtx *const p_ctx) { + int ret; + struct zint_symbol *symbol = NULL; + + (void)p_ctx; + + testStart(p_ctx->func_name); + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + symbol->symbology = BARCODE_ULTRA; + symbol->output_options |= BARCODE_MEMORY_FILE; + symbol->debug |= ZINT_DEBUG_TEST_PNG_FLUSH; + + ret = ZBarcode_Encode_and_Print(symbol, ZCUCP("1234"), -1, 0); + assert_zero(ret, "ZBarcode_Encode_and_Print ret %d != 0 (%s)\n", ret, symbol->errtxt); + + ZBarcode_Delete(symbol); + + testFinish(); +} + /* Check compliant height printable for max CODABLOCKF with 44 rows * ((62 cols) * 0.55 + 3)) = 1632.4 */ static void test_large_compliant_height(const testCtx *const p_ctx) { int ret; @@ -557,14 +589,78 @@ static void test_large_compliant_height(const testCtx *const p_ctx) { testFinish(); } +#include "filemem.h" + +static void test_fm(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + int debug; + const char *data; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_ULTRA, -1, 0, "123", ZINT_ERROR_FILE_ACCESS, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_OPEN }, + /* 1*/ { BARCODE_ULTRA, -1, 0, "123", ZINT_ERROR_FILE_WRITE, { 5, 11, 0, 0, 0 }, 2, FM_FAIL_ID_WRITE }, + /* 2*/ { BARCODE_ULTRA, -1, ZINT_DEBUG_TEST_PNG_FLUSH, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_FLUSH }, + /* 2*/ { BARCODE_ULTRA, BARCODE_MEMORY_FILE, ZINT_DEBUG_TEST_PNG_FLUSH, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_FLUSH }, + /* 3*/ { BARCODE_ULTRA, -1, 0, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, "out.png"); + symbol->debug |= data[i].debug; + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_fm_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ { "test_pixel_plot", test_pixel_plot }, { "test_print", test_print }, { "test_outfile", test_outfile }, - { "test_wpng_error_handler", test_wpng_error_handler }, + { "test_zpng_error_handler", test_zpng_error_handler }, + { "test_zpng_flush", test_zpng_flush }, { "test_large_compliant_height", test_large_compliant_height }, + { "test_fm", test_fm }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_ps.c b/backend/tests/test_ps.c index 9010f71e..84193379 100644 --- a/backend/tests/test_ps.c +++ b/backend/tests/test_ps.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020-2025 Robin Stuart + Copyright (C) 2020-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -321,12 +321,73 @@ static void test_outfile(const testCtx *const p_ctx) { testFinish(); } +#include "filemem.h" + +static void test_fm(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + const char *data; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_ACCESS, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_OPEN }, + /* 1*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 5, 11, 0, 0, 0 }, 2, FM_FAIL_ID_PUTS }, + /* 2*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 2, 0, 0, 0 }, 2, FM_FAIL_ID_PUTSF }, + /* 3*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 2, 0, 0, 0 }, 2, FM_FAIL_ID_PRINTF }, + /* 4*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, "out.eps"); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_fm_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ { "test_print", test_print }, { "test_ps_convert", test_ps_convert }, { "test_outfile", test_outfile }, + { "test_fm", test_fm }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_qr.c b/backend/tests/test_qr.c index 78be2097..de1dbdc1 100644 --- a/backend/tests/test_qr.c +++ b/backend/tests/test_qr.c @@ -6780,6 +6780,9 @@ static void test_upnqr_input(const testCtx *const p_ctx) { /* 7*/ { DATA_MODE, 0, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", 0, "(415) 70 44 01 9B 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34", 3 << 8, 4, "Length 411" }, /* 8*/ { DATA_MODE, 0, "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012", ZINT_ERROR_TOO_LONG, "Error 573: Input too long, requires 416 codewords (maximum 415)", 0, 4, "Length 412" }, /* 9*/ { UNICODE_MODE, ZINT_FULL_MULTIBYTE, "ĄŔ", 0, "(415) 70 44 00 02 A1 C0 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC", ZINT_FULL_MULTIBYTE | (3 << 8), 1, "option_3 mask" }, + /* 10*/ { UNICODE_MODE, 8 << 8, "ĄŔ", 0, "(415) 70 44 00 02 A1 C0 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC", 8 << 8, 1, "Manual mask 8" }, + /* 11*/ { UNICODE_MODE, 9 << 8, "ĄŔ", 0, "(415) 70 44 00 02 A1 C0 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC", 3 << 8, 1, "Manual mask > 8 ignored" }, + /* 12*/ { UNICODE_MODE, ZINT_FULL_MULTIBYTE | (8 << 8), "ĄŔ", 0, "(415) 70 44 00 02 A1 C0 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC", ZINT_FULL_MULTIBYTE | (8 << 8), 1, "Manual mask 8" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; diff --git a/backend/tests/test_random.c b/backend/tests/test_random.c index 013fffe8..cc80251b 100644 --- a/backend/tests/test_random.c +++ b/backend/tests/test_random.c @@ -248,7 +248,7 @@ static void test_dotcode(const testCtx *const p_ctx) { static void test_hanxin(const testCtx *const p_ctx) { struct random_item rdata = { - FLAG_FULL_8BIT, BARCODE_HANXIN, DATA_MODE, 899, 1, 0, 0, -1, 3261 + FLAG_FULL_8BIT, BARCODE_HANXIN, DATA_MODE, 899, 1, 0, 0, -1, 3258 }; test_random(p_ctx, &rdata); diff --git a/backend/tests/test_raster.c b/backend/tests/test_raster.c index 3d373aa1..6a0c9865 100644 --- a/backend/tests/test_raster.c +++ b/backend/tests/test_raster.c @@ -3428,6 +3428,129 @@ static void test_hrt_content_segs(const testCtx *const p_ctx) { testFinish(); } +/* TODO: add new "raster.h" & put these (plus decl.) in it */ +#define RAST_FAIL_ID_BITMAP 1 +#define RAST_FAIL_ID_ALPHA 2 +#define RAST_FAIL_ID_ROTATED 3 +#define RAST_FAIL_ID_MC_PIXELBUF 4 +#define RAST_FAIL_ID_MC_HEXAGON 5 +#define RAST_FAIL_ID_DOTTY_SCALED 6 +#define RAST_FAIL_ID_PIXELBUF 7 +#define RAST_FAIL_ID_SCALED 8 + +INTERNAL void zint_test_raster_set_fail(const int id, const int at); + +static void test_alloc(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + const char *fgcolour; + float scale; + int rotate_angle; + const char *data; + int ret; + int ats[6]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_CODE128, -1, NULL, 0.0f, 0, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, RAST_FAIL_ID_BITMAP }, + /* 1*/ { BARCODE_CODE128, -1, "80808080", 0.0f, 0, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, RAST_FAIL_ID_ALPHA }, + /* 2*/ { BARCODE_CODE128, -1, NULL, 0.0f, 90, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, RAST_FAIL_ID_ROTATED }, + /* 3*/ { BARCODE_MAXICODE, -1, NULL, 0.0f, 0, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, RAST_FAIL_ID_MC_PIXELBUF }, + /* 4*/ { BARCODE_MAXICODE, -1, NULL, 0.0f, 180, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, RAST_FAIL_ID_MC_HEXAGON }, + /* 5*/ { BARCODE_DATAMATRIX, BARCODE_DOTTY_MODE, NULL, 0.0f, 0, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, RAST_FAIL_ID_DOTTY_SCALED }, + /* 6*/ { BARCODE_CODE128, -1, NULL, 0.0f, 0, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, RAST_FAIL_ID_PIXELBUF }, + /* 7*/ { BARCODE_CODE128, -1, NULL, 1.75f, 0, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, RAST_FAIL_ID_SCALED }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + if (data[i].fgcolour) { + strcpy(symbol->fgcolour, data[i].fgcolour); + } + if (data[i].scale) { + symbol->scale = data[i].scale; + } + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_nonzero(ret < ZINT_ERROR, "i:%d %s ZBarcode_Encode ret %d >= ZINT_ERROR %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_raster_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Buffer(symbol, data[i].rotate_angle); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_raster_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + +#include + +INTERNAL int zint_plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); + +static void test_plot_raster(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + int ret; + + struct zint_symbol s_symbol = {0}; + struct zint_symbol *symbol = &s_symbol; + const unsigned char data[] = "123"; + + testStart(p_ctx->func_name); + + ZBarcode_Reset(symbol); + symbol->debug = debug; + strcpy(symbol->fgcolour, "80808080"); + + ret = ZBarcode_Encode(symbol, data, -1); + assert_zero(ret, "ZBarcode_Encode ret %d != 0 (%s)\n", ret, symbol->errtxt); + + /* Call twice without clearing */ + ret = zint_plot_raster(symbol, 0 /*rotate_angle*/, OUT_BUFFER); + assert_zero(ret, "zint_plot_raster ret %d != 0 (%s)\n", ret, symbol->errtxt); + + ret = zint_plot_raster(symbol, 0 /*rotate_angle*/, OUT_BUFFER); + assert_zero(ret, "zint_plot_raster ret %d != 0 (%s)\n", ret, symbol->errtxt); + + symbol->output_options |= OUT_BUFFER_INTERMEDIATE; + ret = zint_plot_raster(symbol, 0 /*rotate_angle*/, OUT_BUFFER); + assert_zero(ret, "zint_plot_raster ret %d != 0 (%s)\n", ret, symbol->errtxt); + + symbol->rows = 0; /* Trigger row guard */ + ret = zint_plot_raster(symbol, 0 /*rotate_angle*/, OUT_BUFFER); + assert_equal(ret, ZINT_ERROR_INVALID_OPTION, "zint_plot_raster ret %d != ZINT_ERROR_INVALID_OPTION (%s)\n", + ret, symbol->errtxt); + + ZBarcode_Clear(symbol); + + testFinish(); +} + #include #define TEST_PERF_ITER_MILLES 1 @@ -3568,6 +3691,8 @@ int main(int argc, char *argv[]) { { "test_height", test_height }, { "test_height_per_row", test_height_per_row }, { "test_hrt_content_segs", test_hrt_content_segs }, + { "test_alloc", test_alloc }, + { "test_plot_raster", test_plot_raster }, { "test_perf_scale", test_perf_scale }, }; diff --git a/backend/tests/test_reedsol.c b/backend/tests/test_reedsol.c index 6597465e..04a366ba 100644 --- a/backend/tests/test_reedsol.c +++ b/backend/tests/test_reedsol.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020-2025 Robin Stuart + Copyright (C) 2020-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -143,6 +143,7 @@ static void test_encoding(const testCtx *const p_ctx) { /* 16*/ { 0x11d, 10, 0, 16, { 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 }, { 0x55, 0x2C, 0x87, 0xC7, 0x36, 0xED, 0xC1, 0xD4, 0x24, 0xA5 } }, /* QRCODE Annex I.2 */ /* 17*/ { 0x11d, 5, 0, 5, { 0x40, 0x18, 0xAC, 0xC3, 0x00 }, { 0x30, 0xAE, 0x22, 0x0D, 0x86 } }, /* QRCODE Annex I.3 */ /* 18*/ { 0x163, 256, 0, 1, { 0xFF }, { 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255 } }, + /* 19*/ { 0x163, 256, 1, 7, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, }; int data_size = ARRAY_SIZE(data); int i; @@ -209,6 +210,7 @@ static void test_encoding_uint(const testCtx *const p_ctx) { /* 16*/ { 0x11d, 10, 0, 16, { 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 }, { 0x55, 0x2C, 0x87, 0xC7, 0x36, 0xED, 0xC1, 0xD4, 0x24, 0xA5 } }, /* QRCODE Annex I.2 */ /* 17*/ { 0x11d, 5, 0, 5, { 0x40, 0x18, 0xAC, 0xC3, 0x00 }, { 0x30, 0xAE, 0x22, 0x0D, 0x86 } }, /* QRCODE Annex I.3 */ /* 18*/ { 0x163, 256, 0, 1, { 0xFF }, { 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255 } }, + /* 19*/ { 0x163, 256, 1, 7, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, }; int data_size = ARRAY_SIZE(data); int i; @@ -261,6 +263,7 @@ static void test_uint_encoding(const testCtx *const p_ctx) { /* 1*/ { 0x1069, 4095, 4, 1, 7, { 0xFFF, 0x000, 0x700, 0x7FF, 0xFFF, 0x000, 0x123 }, { 575, 3494, 2350, 3472 } }, /* 2*/ { 0x1000, 4095, 4, 0, 7, { 0xFFF, 0x000, 0x700, 0x7FF, 0xFFF, 0x000, 0x123 }, { 64, 0, 65, 1 } }, /* 3*/ { 0x1000, 4095, 256, 0, 1, { 0xFFF }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 512, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }, + /* 4*/ { 0x409, 1023, 4, 0, 7, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, }; int data_size = ARRAY_SIZE(data); int i; @@ -314,6 +317,51 @@ static void test_uint_encoding(const testCtx *const p_ctx) { testFinish(); } +static void test_alloc(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int option_2; + const char *data; + int ret; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_AZTEC, 13, "123", ZINT_ERROR_MEMORY, RS_FAIL_ID_LOGT }, + /* 1*/ { BARCODE_AZTEC, 13, "123", ZINT_ERROR_MEMORY, RS_FAIL_ID_ALOG }, + /* 2*/ { BARCODE_AZTEC, 27, "123", ZINT_ERROR_MEMORY, RS_FAIL_ID_LOGT }, + /* 3*/ { BARCODE_AZTEC, 27, "123", ZINT_ERROR_MEMORY, RS_FAIL_ID_ALOG }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, -1, debug); + zint_test_rs_set_fail(data[i].id); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_equal(ret, data[i].ret, "i:%d %s ZBarcode_Encode ret %d != %d (%s)\n", + i, testUtilBarcodeName(data[i].symbology), ret, data[i].ret, symbol->errtxt); + zint_test_rs_set_fail(0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -321,6 +369,7 @@ int main(int argc, char *argv[]) { { "test_encoding", test_encoding }, { "test_encoding_uint", test_encoding_uint }, { "test_uint_encoding", test_uint_encoding }, + { "test_alloc", test_alloc }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_rss.c b/backend/tests/test_rss.c index b898cf92..848bbc8b 100644 --- a/backend/tests/test_rss.c +++ b/backend/tests/test_rss.c @@ -150,30 +150,38 @@ static void test_binary_div_modulo_divisor(const testCtx *const p_ctx) { } else { text = data[i].data; } - length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, text, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1, -1, -1 /*output_options*/, + text, -1, debug); ret = ZBarcode_Encode(symbol, TCU(text), length); assert_zero(ret, "i:%d ZBarcode_Encode ret %d != 0 (%s)\n", i, ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, \"%s\", %.0f, %.0f, %d, %d, ", - i, testUtilBarcodeName(data[i].symbology), data[i].data, data[i].w, data[i].h, symbol->rows, symbol->width); + i, testUtilBarcodeName(data[i].symbology), data[i].data, data[i].w, data[i].h, + symbol->rows, symbol->width); testUtilModulesPrintRow(symbol, symbol->rows - 1, "", " },\n"); } else { int width; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); ret = testUtilModulesCmpRow(symbol, symbol->rows - 1, data[i].expected, &width); - assert_zero(ret, "i:%d testUtilModulesCmpRow ret %d != 0 width %d row %d\n", i, ret, width, symbol->rows - 1); + assert_zero(ret, "i:%d testUtilModulesCmpRow ret %d != 0 width %d row %d\n", + i, ret, width, symbol->rows - 1); ret = ZBarcode_Buffer_Vector(symbol, 0); assert_zero(ret, "i:%d ZBarcode_Buffer_Vector ret %d != 0\n", i, ret); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, -1, -1, debug)) { - ret = testUtilBwipp(i, symbol, -1, -1, -1, text, length, symbol->primary, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, -1, -1, -1, text, length, symbol->primary, cmp_buf, sizeof(cmp_buf), + NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmpRow(symbol, symbol->rows - 1, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", @@ -182,9 +190,12 @@ static void test_binary_div_modulo_divisor(const testCtx *const p_ctx) { if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; char modules_dump[8192 + 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, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + 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, 1 /*zxingcpp_cmp*/, 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, NULL /*primary*/, escaped, &ret_len); @@ -889,10 +900,13 @@ static void test_examples(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, data[i].option_3, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %d, %d, \"%s\", %d, %d, %d, %d, \"%s\",\n", @@ -904,33 +918,47 @@ static void test_examples(const testCtx *const p_ctx) { } else { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d %s symbol->rows %d != %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d %s symbol->width %d != %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d %s symbol->rows %d != %d (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->rows, data[i].expected_rows, + data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d %s symbol->width %d != %d (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->width, data[i].expected_width, + data[i].data); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); + assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, debug)) { if (!data[i].bwipp_cmp) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not BWIPP compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } } else { - ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, -1, data[i].option_2, data[i].option_3, data[i].data, length, NULL, + cmp_buf, sizeof(cmp_buf), NULL); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, + data[i].expected); } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { int cmp_len, ret_len; char modules_dump[8192 + 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, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + 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, 1 /*zxingcpp_cmp*/, 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, NULL /*primary*/, - escaped, &ret_len); + 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); @@ -1218,24 +1246,32 @@ static void test_general_field(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1, -1, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); assert_zero(ret, "i:%d ZBarcode_Encode ret %d != 0 (%s)\n", i, ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%2d*/ { %s, \"%s\", %d, %d, %d, \"%s\",\n", - i, testUtilBarcodeName(symbol->symbology), data[i].data, ret, symbol->rows, symbol->width, data[i].comment); + i, testUtilBarcodeName(symbol->symbology), data[i].data, ret, symbol->rows, symbol->width, + data[i].comment); testUtilModulesPrint(symbol, " ", "\n"); printf(" },\n"); } else { int width, row; - assert_equal(symbol->rows, data[i].expected_rows, "i:%d %s symbol->rows %d != %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d %s symbol->width %d != %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), symbol->width, data[i].expected_width, data[i].data); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d %s symbol->rows %d != %d (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->rows, data[i].expected_rows, + data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d %s symbol->width %d != %d (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->width, data[i].expected_width, + data[i].data); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); + assert_zero(ret, "i:%d %s testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", + i, testUtilBarcodeName(data[i].symbology), ret, width, row, data[i].data); } ZBarcode_Delete(symbol); @@ -1284,20 +1320,27 @@ static void test_binary_buffer_size(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_DBAR_EXP, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, BARCODE_DBAR_EXP, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1, -1, -1 /*output_options*/, + data[i].data, -1, debug); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", i, ret ? "set" : "empty", symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { %s, \"%s\", %s, %d, %d, \"%s\", \"%s\" },\n", i, testUtilInputModeName(data[i].input_mode), data[i].data, testUtilErrorName(ret), symbol->rows, symbol->width, symbol->errtxt, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", + i, symbol->rows, data[i].expected_rows, data[i].data); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", + i, symbol->width, data[i].expected_width, data[i].data); } ZBarcode_Delete(symbol); @@ -1356,13 +1399,14 @@ static void test_hrt(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, - -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, - data[i].data, -1, debug); + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); expected_length = (int) strlen(data[i].expected); expected_content_length = (int) strlen(data[i].expected_content); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, data[i].ret, ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, data[i].ret, ret, symbol->errtxt); assert_equal(symbol->text_length, expected_length, "i:%d text_length %d != expected_length %d\n", i, symbol->text_length, expected_length); @@ -1396,6 +1440,8 @@ static void test_input(const testCtx *const p_ctx) { int input_mode; int option_2; int option_3; + int output_options; + float height; const char *data; int ret; int expected_rows; @@ -1406,153 +1452,158 @@ static void test_input(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { BARCODE_DBAR_OMN, -1, -1, -1, "1234567890123", 0, 1, 96, "", 0, 0 }, - /* 1*/ { BARCODE_DBAR_OMN, -1, -1, -1, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, - /* 2*/ { BARCODE_DBAR_OMN, GS1NOCHECK_MODE, -1, -1, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, - /* 3*/ { BARCODE_DBAR_OMN, -1, -1, -1, "12345678901234", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '4', expecting '1'", 0, 0 }, - /* 4*/ { BARCODE_DBAR_OMN, GS1NOCHECK_MODE, -1, -1, "12345678901234", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '4', expecting '1'", 0, 0 }, /* Still checked */ - /* 5*/ { BARCODE_DBAR_OMN, -1, -1, -1, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, - /* 6*/ { BARCODE_DBAR_OMN, GS1NOCHECK_MODE, -1, -1, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, - /* 7*/ { BARCODE_DBAR_OMN, -1, -1, -1, "01345678901235", 0, 1, 96, "", 0, 0 }, - /* 8*/ { BARCODE_DBAR_OMN, -1, -1, -1, "0134567890123", 0, 1, 96, "", 0, 0 }, - /* 9*/ { BARCODE_DBAR_OMN, -1, -1, -1, "0112345678901231", 0, 1, 96, "", 0, 0 }, /* Allow '01' prefix if check digit given */ - /* 10*/ { BARCODE_DBAR_OMN, -1, -1, -1, "011234567890123", 0, 1, 96, "", 0, 0 }, /* Or not */ - /* 11*/ { BARCODE_DBAR_OMN, -1, -1, -1, "[01]12345678901231", 0, 1, 96, "", 0, 0 }, /* Allow '[01]' prefix if check digit given */ - /* 12*/ { BARCODE_DBAR_OMN, -1, -1, -1, "[01]1234567890123", 0, 1, 96, "", 0, 0 }, /* Or not */ - /* 13*/ { BARCODE_DBAR_OMN, -1, -1, -1, "(01)12345678901231", 0, 1, 96, "", 0, 0 }, /* Allow '(01)' prefix if check digit given */ - /* 14*/ { BARCODE_DBAR_OMN, -1, -1, -1, "(01)1234567890123", 0, 1, 96, "", 0, 0 }, /* Or not */ - /* 15*/ { BARCODE_DBAR_OMN, -1, -1, -1, "[01)12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 18 too long (maximum 14)", 0, 0 }, - /* 16*/ { BARCODE_DBAR_LTD, -1, -1, -1, "1234567890123", 0, 1, 79, "", 0, 0 }, - /* 17*/ { BARCODE_DBAR_LTD, -1, -1, -1, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 383: Invalid character at position 13 in input (digits only)", 0, 0 }, - /* 18*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 383: Invalid character at position 13 in input (digits only)", 0, 0 }, - /* 19*/ { BARCODE_DBAR_LTD, -1, -1, -1, "12345678901235", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 389: Invalid check digit '5', expecting '1'", 0, 0 }, - /* 20*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, "12345678901235", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 389: Invalid check digit '5', expecting '1'", 0, 0 }, /* Still checked */ - /* 21*/ { BARCODE_DBAR_LTD, -1, -1, -1, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 15 too long (maximum 14)", 0, 0 }, - /* 22*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 15 too long (maximum 14)", 0, 0 }, - /* 23*/ { BARCODE_DBAR_LTD, -1, -1, -1, "2234567890123", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 384: Input value out of range (0 to 1999999999999)", 0, 0 }, - /* 24*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, "2234567890123", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 384: Input value out of range (0 to 1999999999999)", 0, 0 }, - /* 25*/ { BARCODE_DBAR_LTD, -1, -1, -1, "22345678901238", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 384: Input value out of range (0 to 1999999999999)", 0, 0 }, - /* 26*/ { BARCODE_DBAR_LTD, -1, -1, -1, "01345678901235", 0, 1, 79, "", 0, 0 }, - /* 27*/ { BARCODE_DBAR_LTD, -1, -1, -1, "0134567890123", 0, 1, 79, "", 0, 0 }, - /* 28*/ { BARCODE_DBAR_LTD, -1, -1, -1, "0112345678901231", 0, 1, 79, "", 0, 0 }, /* Allow '01' prefix if check digit given */ - /* 29*/ { BARCODE_DBAR_LTD, -1, -1, -1, "011234567890123", 0, 1, 79, "", 0, 0 }, /* Or not */ - /* 30*/ { BARCODE_DBAR_LTD, -1, -1, -1, "[01]12345678901231", 0, 1, 79, "", 0, 0 }, /* Allow '[01]' prefix if check digit given */ - /* 31*/ { BARCODE_DBAR_LTD, -1, -1, -1, "[01]1234567890123", 0, 1, 79, "", 0, 0 }, /* Or not */ - /* 32*/ { BARCODE_DBAR_LTD, -1, -1, -1, "(01)12345678901231", 0, 1, 79, "", 0, 0 }, /* Allow '(01)' prefix if check digit given */ - /* 33*/ { BARCODE_DBAR_LTD, -1, -1, -1, "(01)1234567890123", 0, 1, 79, "", 0, 0 }, /* Or not */ - /* 34*/ { BARCODE_DBAR_LTD, -1, -1, -1, "[01)12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 18 too long (maximum 14)", 0, 0 }, - /* 35*/ { BARCODE_DBAR_LTD, -1, -1, -1, "[10]12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 18 too long (maximum 14)", 0, 0 }, - /* 36*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, "22345678901238", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 384: Input value out of range (0 to 1999999999999)", 0, 0 }, - /* 37*/ { BARCODE_DBAR_EXP, -1, -1, -1, "[01]12345678901234", ZINT_WARN_NONCOMPLIANT, 1, 134, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'", 0, 0 }, - /* 38*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, "[01]12345678901234", 0, 1, 134, "", 0, 0 }, - /* 39*/ { BARCODE_DBAR_EXP, -1, -1, -1, "[01]12345678901231", 0, 1, 134, "", 0, 0 }, - /* 40*/ { BARCODE_DBAR_EXP, -1, -1, -1, "[01]1234567890123A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 385: Invalid character in Compressed Field data (digits only)", 0, 0 }, - /* 41*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, "[01]1234567890123A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 385: Invalid character in Compressed Field data (digits only)", 0, 0 }, - /* 42*/ { BARCODE_DBAR_EXP, -1, -1, -1, "[01]123456789012315", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 259: Invalid data length for AI (01) at position 1", 0, 0 }, - /* 43*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, "[01]123456789012315", 0, 1, 151, "", 0, 0 }, - /* 44*/ { BARCODE_DBAR_EXP, -1, -1, -1, "[01]12345678901234", ZINT_WARN_NONCOMPLIANT, 1, 134, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'", 0, 0 }, - /* 45*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, "[01]12345678901234", 0, 1, 134, "", 0, 0 }, - /* 46*/ { BARCODE_DBAR_EXP, -1, -1, -1, "[01]12345678901231[91]!\"%&'()*+,-./:;<=>?_ ", ZINT_WARN_NONCOMPLIANT, 1, 526, "Warning 261: AI (91) data position 21: Invalid CSET 82 character ' '", 0, 0 }, /* ISOIEC punc */ - /* 47*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, "[01]12345678901231[91]!\"%&'()*+,-./:;<=>?_ ", 0, 1, 526, "", 0, 0 }, - /* 48*/ { BARCODE_DBAR_EXP, -1, -1, -1, "[01]12345678901231[91]!\"%&'()*+,-./:;<=>?_", 0, 1, 494, "", 0, 0 }, /* ISOIEC punc less space */ - /* 49*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, "[01]12345678901231[91]!\"%&'()*+,-./:;<=>?_", 0, 1, 494, "", 0, 0 }, - /* 50*/ { BARCODE_DBAR_STK, -1, -1, -1, "1234567890123", 0, 3, 50, "", 0, 0 }, - /* 51*/ { BARCODE_DBAR_STK, GS1NOCHECK_MODE, -1, -1, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, - /* 52*/ { BARCODE_DBAR_STK, -1, -1, -1, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, - /* 53*/ { BARCODE_DBAR_STK, GS1NOCHECK_MODE, -1, -1, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, - /* 54*/ { BARCODE_DBAR_STK, -1, -1, -1, "12345678901235", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '5', expecting '1'", 0, 0 }, - /* 55*/ { BARCODE_DBAR_STK, GS1NOCHECK_MODE, -1, -1, "12345678901235", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '5', expecting '1'", 0, 0 }, /* Still checked */ - /* 56*/ { BARCODE_DBAR_STK, -1, -1, -1, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, - /* 57*/ { BARCODE_DBAR_STK, GS1NOCHECK_MODE, -1, -1, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, - /* 58*/ { BARCODE_DBAR_STK, -1, -1, -1, "01345678901235", 0, 3, 50, "", 0, 0 }, - /* 59*/ { BARCODE_DBAR_STK, -1, -1, -1, "0134567890123", 0, 3, 50, "", 0, 0 }, - /* 60*/ { BARCODE_DBAR_STK, -1, -1, -1, "0112345678901231", 0, 3, 50, "", 0, 0 }, /* Allow '01' prefix if check digit given */ - /* 61*/ { BARCODE_DBAR_STK, -1, -1, -1, "011234567890123", 0, 3, 50, "", 0, 0 }, /* Or not */ - /* 62*/ { BARCODE_DBAR_STK, -1, -1, -1, "[01]12345678901231", 0, 3, 50, "", 0, 0 }, /* Allow '[01]' prefix if check digit given */ - /* 63*/ { BARCODE_DBAR_STK, -1, -1, -1, "[01]1234567890123", 0, 3, 50, "", 0, 0 }, /* Or not */ - /* 64*/ { BARCODE_DBAR_STK, -1, -1, -1, "(01)12345678901231", 0, 3, 50, "", 0, 0 }, /* Allow '(01)' prefix if check digit given */ - /* 65*/ { BARCODE_DBAR_STK, -1, -1, -1, "(01)1234567890123", 0, 3, 50, "", 0, 0 }, /* Or not */ - /* 66*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "1234567890123", 0, 5, 50, "", 0, 0 }, - /* 67*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, - /* 68*/ { BARCODE_DBAR_OMNSTK, GS1NOCHECK_MODE, -1, -1, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, - /* 69*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "12345678901236", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '6', expecting '1'", 0, 0 }, - /* 70*/ { BARCODE_DBAR_OMNSTK, GS1NOCHECK_MODE, -1, -1, "12345678901236", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '6', expecting '1'", 0, 0 }, /* Still checked */ - /* 71*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, - /* 72*/ { BARCODE_DBAR_OMNSTK, GS1NOCHECK_MODE, -1, -1, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, - /* 73*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "01345678901235", 0, 5, 50, "", 0, 0 }, - /* 74*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "0134567890123", 0, 5, 50, "", 0, 0 }, - /* 75*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "0112345678901231", 0, 5, 50, "", 0, 0 }, /* Allow '01' prefix if check digit given */ - /* 76*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "011234567890123", 0, 5, 50, "", 0, 0 }, /* Or not */ - /* 77*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "[01]12345678901231", 0, 5, 50, "", 0, 0 }, /* Allow '[01]' prefix if check digit given */ - /* 78*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "[01]1234567890123", 0, 5, 50, "", 0, 0 }, /* Or not */ - /* 79*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "(01)12345678901231", 0, 5, 50, "", 0, 0 }, /* Allow '(01)' prefix if check digit given */ - /* 80*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "(01)1234567890123", 0, 5, 50, "", 0, 0 }, /* Or not */ - /* 81*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, "(00)12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 18 too long (maximum 14)", 0, 0 }, - /* 82*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, "[01]12345678901234", ZINT_WARN_NONCOMPLIANT, 5, 102, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'", 2, 0 }, - /* 83*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, -1, "[01]12345678901234", 0, 5, 102, "", 2, 0 }, - /* 84*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, "[01]12345678901231", 0, 5, 102, "", 2, 0 }, - /* 85*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, "[01]1234567890123A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 385: Invalid character in Compressed Field data (digits only)", 0, 0 }, - /* 86*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, -1, "[01]1234567890123A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 385: Invalid character in Compressed Field data (digits only)", 0, 0 }, - /* 87*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, "[01]123456789012315", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 259: Invalid data length for AI (01) at position 1", 0, 0 }, - /* 88*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, -1, "[01]123456789012315", 0, 5, 102, "", 2, 0 }, - /* 89*/ { BARCODE_DBAR_EXPSTK, -1, 12, -1, "[01]12345678901231", 0, 5, 102, "", 2, 0 }, /* Cols > 11 ignored */ - /* 90*/ { BARCODE_DBAR_EXPSTK, -1, -1, 12, "[01]12345678901231", 0, 5, 102, "", 2, 0 }, /* Rows > 11 ignored */ - /* 91*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, "[01]12345678901231", 0, 9, 53, "", 1, 0 }, - /* 92*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, "[01]12345678901231", 0, 5, 102, "", 2, 0 }, - /* 93*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, "[01]12345678901231", 0, 1, 134, "", 3, 0 }, - /* 94*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, "[01]12345678901231", 0, 1, 134, "", 4, 0 }, - /* 95*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, "[01]12345678901231", 0, 5, 102, "", 2, 2 }, - /* 96*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, "[01]12345678901231", 0, 5, 102, "", 2, 3 }, - /* 97*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, "[8110]106141416543213500110000310123196000", 0, 13, 102, "", 2, 0 }, - /* 98*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, "[8110]106141416543213500110000310123196000", 0, 25, 53, "", 1, 0 }, - /* 99*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, "[8110]106141416543213500110000310123196000", 0, 13, 102, "", 2, 0 }, - /*100*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, "[8110]106141416543213500110000310123196000", 0, 9, 151, "", 3, 0 }, - /*101*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, "[8110]106141416543213500110000310123196000", 0, 5, 200, "", 4, 0 }, - /*102*/ { BARCODE_DBAR_EXPSTK, -1, 5, -1, "[8110]106141416543213500110000310123196000", 0, 5, 249, "", 5, 0 }, - /*103*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, "[8110]106141416543213500110000310123196000", 0, 5, 200, "", 4, 2 }, - /*104*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, "[8110]106141416543213500110000310123196000", 0, 9, 151, "", 3, 3 }, - /*105*/ { BARCODE_DBAR_EXPSTK, -1, -1, 4, "[8110]106141416543213500110000310123196000", 0, 13, 102, "", 2, 4 }, - /*106*/ { BARCODE_DBAR_EXPSTK, -1, -1, 5, "[8110]106141416543213500110000310123196000", 0, 13, 102, "", 2, 5 }, - /*107*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, "[91]123456789012345678901", 0, 9, 102, "", 2, 0 }, - /*108*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, "[91]123456789012345678901", 0, 17, 53, "", 1, 0 }, - /*109*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, "[91]123456789012345678901", 0, 9, 102, "", 2, 0 }, - /*110*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, "[91]123456789012345678901", 0, 5, 151, "", 3, 0 }, - /*111*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, "[91]123456789012345678901", 0, 5, 200, "", 4, 0 }, - /*112*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, "[91]123456789012345678901", 0, 5, 151, "", 3, 2 }, - /*113*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, "[91]123456789012345678901", 0, 9, 102, "", 2, 3 }, - /*114*/ { BARCODE_DBAR_EXPSTK, -1, -1, 4, "[91]123456789012345678901", 0, 9, 102, "", 2, 4 }, - /*115*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, "[91]123456789012345678901", 0, 9, 102, "", 2, 0 }, - /*116*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 17, 102, "", 2, 0 }, - /*117*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 33, 53, "", 1, 0 }, - /*118*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 17, 102, "", 2, 0 }, - /*119*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 151, "", 3, 0 }, - /*120*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 200, "", 4, 0 }, - /*121*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 200, "", 4, 0 }, - /*122*/ { BARCODE_DBAR_EXPSTK, -1, 5, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 249, "", 5, 0 }, - /*123*/ { BARCODE_DBAR_EXPSTK, -1, 6, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 298, "", 6, 0 }, - /*124*/ { BARCODE_DBAR_EXPSTK, -1, 7, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 347, "", 7, 0 }, - /*125*/ { BARCODE_DBAR_EXPSTK, -1, 8, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 396, "", 8, 0 }, - /*126*/ { BARCODE_DBAR_EXPSTK, -1, 9, -1, "[91]1234567890123456789012345678901234567890123456789", 0, 1, 428, "", 9, 0 }, - /*127*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 249, "", 5, 2 }, - /*128*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 151, "", 3, 3 }, - /*129*/ { BARCODE_DBAR_EXPSTK, -1, -1, 4, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 151, "", 3, 4 }, - /*130*/ { BARCODE_DBAR_EXPSTK, -1, -1, 5, "[91]1234567890123456789012345678901234567890123456789", 0, 17, 102, "", 2, 5 }, - /*131*/ { BARCODE_DBAR_EXPSTK, -1, -1, 6, "[91]1234567890123456789012345678901234567890123456789", 0, 17, 102, "", 2, 6 }, - /*132*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 0 }, - /*133*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 41, 53, "", 1, 0 }, - /*134*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 0 }, - /*135*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 13, 151, "", 3, 0 }, - /*136*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 9, 200, "", 4, 0 }, - /*137*/ { BARCODE_DBAR_EXPSTK, -1, 5, -1, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 9, 249, "", 5, 0 }, - /*138*/ { BARCODE_DBAR_EXPSTK, -1, 6, -1, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 5, 298, "", 6, 0 }, - /*139*/ { BARCODE_DBAR_EXPSTK, -1, 7, -1, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 5, 347, "", 7, 0 }, - /*140*/ { BARCODE_DBAR_EXPSTK, -1, -1, 1, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 0 }, - /*141*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 5, 298, "", 6, 2 }, - /*142*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 9, 200, "", 4, 3 }, - /*143*/ { BARCODE_DBAR_EXPSTK, -1, -1, 4, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 13, 151, "", 3, 4 }, - /*144*/ { BARCODE_DBAR_EXPSTK, -1, -1, 5, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 13, 151, "", 3, 5 }, - /*145*/ { BARCODE_DBAR_EXPSTK, -1, -1, 6, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 6 }, - /*146*/ { BARCODE_DBAR_EXPSTK, -1, -1, 7, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 7 }, + /* 0*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "1234567890123", 0, 1, 96, "", 0, 0 }, + /* 1*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, + /* 2*/ { BARCODE_DBAR_OMN, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, + /* 3*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "12345678901234", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '4', expecting '1'", 0, 0 }, + /* 4*/ { BARCODE_DBAR_OMN, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "12345678901234", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '4', expecting '1'", 0, 0 }, /* Still checked */ + /* 5*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, + /* 6*/ { BARCODE_DBAR_OMN, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, + /* 7*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "01345678901235", 0, 1, 96, "", 0, 0 }, + /* 8*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "0134567890123", 0, 1, 96, "", 0, 0 }, + /* 9*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "0112345678901231", 0, 1, 96, "", 0, 0 }, /* Allow '01' prefix if check digit given */ + /* 10*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "011234567890123", 0, 1, 96, "", 0, 0 }, /* Or not */ + /* 11*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "[01]12345678901231", 0, 1, 96, "", 0, 0 }, /* Allow '[01]' prefix if check digit given */ + /* 12*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "[01]1234567890123", 0, 1, 96, "", 0, 0 }, /* Or not */ + /* 13*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "(01)12345678901231", 0, 1, 96, "", 0, 0 }, /* Allow '(01)' prefix if check digit given */ + /* 14*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "(01)1234567890123", 0, 1, 96, "", 0, 0 }, /* Or not */ + /* 15*/ { BARCODE_DBAR_OMN, -1, -1, -1, -1, 0.0f, "[01)12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 18 too long (maximum 14)", 0, 0 }, + /* 16*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "1234567890123", 0, 1, 79, "", 0, 0 }, + /* 17*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 383: Invalid character at position 13 in input (digits only)", 0, 0 }, + /* 18*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 383: Invalid character at position 13 in input (digits only)", 0, 0 }, + /* 19*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "12345678901235", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 389: Invalid check digit '5', expecting '1'", 0, 0 }, + /* 20*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "12345678901235", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 389: Invalid check digit '5', expecting '1'", 0, 0 }, /* Still checked */ + /* 21*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 15 too long (maximum 14)", 0, 0 }, + /* 22*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 15 too long (maximum 14)", 0, 0 }, + /* 23*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "2234567890123", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 384: Input value out of range (0 to 1999999999999)", 0, 0 }, + /* 24*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "2234567890123", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 384: Input value out of range (0 to 1999999999999)", 0, 0 }, + /* 25*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "22345678901238", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 384: Input value out of range (0 to 1999999999999)", 0, 0 }, + /* 26*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "01345678901235", 0, 1, 79, "", 0, 0 }, + /* 27*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "0134567890123", 0, 1, 79, "", 0, 0 }, + /* 28*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "0112345678901231", 0, 1, 79, "", 0, 0 }, /* Allow '01' prefix if check digit given */ + /* 29*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "011234567890123", 0, 1, 79, "", 0, 0 }, /* Or not */ + /* 30*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "[01]12345678901231", 0, 1, 79, "", 0, 0 }, /* Allow '[01]' prefix if check digit given */ + /* 31*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "[01]1234567890123", 0, 1, 79, "", 0, 0 }, /* Or not */ + /* 32*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "(01)12345678901231", 0, 1, 79, "", 0, 0 }, /* Allow '(01)' prefix if check digit given */ + /* 33*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "(01)1234567890123", 0, 1, 79, "", 0, 0 }, /* Or not */ + /* 34*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "[01)12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 18 too long (maximum 14)", 0, 0 }, + /* 35*/ { BARCODE_DBAR_LTD, -1, -1, -1, -1, 0.0f, "[10]12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 382: Input length 18 too long (maximum 14)", 0, 0 }, + /* 36*/ { BARCODE_DBAR_LTD, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "22345678901238", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 384: Input value out of range (0 to 1999999999999)", 0, 0 }, + /* 37*/ { BARCODE_DBAR_EXP, -1, -1, -1, -1, 0.0f, "[01]12345678901234", ZINT_WARN_NONCOMPLIANT, 1, 134, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'", 0, 0 }, + /* 38*/ { BARCODE_DBAR_EXP, -1, -1, -1, COMPLIANT_HEIGHT, 1.0f, "[01]12345678901234", ZINT_WARN_NONCOMPLIANT, 1, 134, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'", 0, 0 }, + /* 39*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "[01]12345678901234", 0, 1, 134, "", 0, 0 }, + /* 40*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, COMPLIANT_HEIGHT, 1.0f, "[01]12345678901234", ZINT_WARN_NONCOMPLIANT, 1, 134, "Warning 247: Height not compliant with standards (too small)", 0, 0 }, + /* 41*/ { BARCODE_DBAR_EXP, -1, -1, -1, -1, 0.0f, "[01]12345678901231", 0, 1, 134, "", 0, 0 }, + /* 42*/ { BARCODE_DBAR_EXP, -1, -1, -1, -1, 0.0f, "[01]1234567890123A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 385: Invalid character in Compressed Field data (digits only)", 0, 0 }, + /* 43*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "[01]1234567890123A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 385: Invalid character in Compressed Field data (digits only)", 0, 0 }, + /* 44*/ { BARCODE_DBAR_EXP, -1, -1, -1, -1, 0.0f, "[01]123456789012315", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 259: Invalid data length for AI (01) at position 1", 0, 0 }, + /* 45*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "[01]123456789012315", 0, 1, 151, "", 0, 0 }, + /* 46*/ { BARCODE_DBAR_EXP, -1, -1, -1, -1, 0.0f, "[01]12345678901234", ZINT_WARN_NONCOMPLIANT, 1, 134, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'", 0, 0 }, + /* 47*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "[01]12345678901234", 0, 1, 134, "", 0, 0 }, + /* 48*/ { BARCODE_DBAR_EXP, -1, -1, -1, -1, 0.0f, "[01]12345678901231[91]!\"%&'()*+,-./:;<=>?_ ", ZINT_WARN_NONCOMPLIANT, 1, 526, "Warning 261: AI (91) data position 21: Invalid CSET 82 character ' '", 0, 0 }, /* ISOIEC punc */ + /* 49*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "[01]12345678901231[91]!\"%&'()*+,-./:;<=>?_ ", 0, 1, 526, "", 0, 0 }, + /* 50*/ { BARCODE_DBAR_EXP, -1, -1, -1, -1, 0.0f, "[01]12345678901231[91]!\"%&'()*+,-./:;<=>?_", 0, 1, 494, "", 0, 0 }, /* ISOIEC punc less space */ + /* 51*/ { BARCODE_DBAR_EXP, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "[01]12345678901231[91]!\"%&'()*+,-./:;<=>?_", 0, 1, 494, "", 0, 0 }, + /* 52*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "1234567890123", 0, 3, 50, "", 0, 0 }, + /* 53*/ { BARCODE_DBAR_STK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, + /* 54*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, + /* 55*/ { BARCODE_DBAR_STK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, + /* 56*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "12345678901235", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '5', expecting '1'", 0, 0 }, + /* 57*/ { BARCODE_DBAR_STK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "12345678901235", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '5', expecting '1'", 0, 0 }, /* Still checked */ + /* 58*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, + /* 59*/ { BARCODE_DBAR_STK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, + /* 60*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 2.2f, "1234567890123", 0, 3, 50, "", 0, 0 }, + /* 61*/ { BARCODE_DBAR_STK, -1, -1, -1, COMPLIANT_HEIGHT, 2.2f, "1234567890123", ZINT_WARN_NONCOMPLIANT, 3, 50, "Warning 379: Height not compliant with standards", 0, 0 }, + /* 62*/ { BARCODE_DBAR_STK, -1, -1, -1, COMPLIANT_HEIGHT, 2.2f, "12345678901234", ZINT_ERROR_INVALID_CHECK, 3, 50, "Error 388: Invalid check digit '4', expecting '1'", 0, 0 }, + /* 63*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "01345678901235", 0, 3, 50, "", 0, 0 }, + /* 64*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "0134567890123", 0, 3, 50, "", 0, 0 }, + /* 65*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "0112345678901231", 0, 3, 50, "", 0, 0 }, /* Allow '01' prefix if check digit given */ + /* 66*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "011234567890123", 0, 3, 50, "", 0, 0 }, /* Or not */ + /* 67*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "[01]12345678901231", 0, 3, 50, "", 0, 0 }, /* Allow '[01]' prefix if check digit given */ + /* 68*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "[01]1234567890123", 0, 3, 50, "", 0, 0 }, /* Or not */ + /* 69*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "(01)12345678901231", 0, 3, 50, "", 0, 0 }, /* Allow '(01)' prefix if check digit given */ + /* 70*/ { BARCODE_DBAR_STK, -1, -1, -1, -1, 0.0f, "(01)1234567890123", 0, 3, 50, "", 0, 0 }, /* Or not */ + /* 71*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "1234567890123", 0, 5, 50, "", 0, 0 }, + /* 72*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, + /* 73*/ { BARCODE_DBAR_OMNSTK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "123456789012A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 381: Invalid character at position 13 in input (digits only)", 0, 0 }, + /* 74*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "12345678901236", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '6', expecting '1'", 0, 0 }, + /* 75*/ { BARCODE_DBAR_OMNSTK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "12345678901236", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 388: Invalid check digit '6', expecting '1'", 0, 0 }, /* Still checked */ + /* 76*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, + /* 77*/ { BARCODE_DBAR_OMNSTK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "123456789012315", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 15 too long (maximum 14)", 0, 0 }, + /* 78*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "01345678901235", 0, 5, 50, "", 0, 0 }, + /* 79*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "0134567890123", 0, 5, 50, "", 0, 0 }, + /* 80*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "0112345678901231", 0, 5, 50, "", 0, 0 }, /* Allow '01' prefix if check digit given */ + /* 81*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "011234567890123", 0, 5, 50, "", 0, 0 }, /* Or not */ + /* 82*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "[01]12345678901231", 0, 5, 50, "", 0, 0 }, /* Allow '[01]' prefix if check digit given */ + /* 83*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "[01]1234567890123", 0, 5, 50, "", 0, 0 }, /* Or not */ + /* 84*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "(01)12345678901231", 0, 5, 50, "", 0, 0 }, /* Allow '(01)' prefix if check digit given */ + /* 85*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "(01)1234567890123", 0, 5, 50, "", 0, 0 }, /* Or not */ + /* 86*/ { BARCODE_DBAR_OMNSTK, -1, -1, -1, -1, 0.0f, "(00)12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 380: Input length 18 too long (maximum 14)", 0, 0 }, + /* 87*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, -1, 0.0f, "[01]12345678901234", ZINT_WARN_NONCOMPLIANT, 5, 102, "Warning 261: AI (01) data position 14: Bad checksum '4', expected '1'", 2, 0 }, + /* 88*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "[01]12345678901234", 0, 5, 102, "", 2, 0 }, + /* 89*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, -1, 0.0f, "[01]12345678901231", 0, 5, 102, "", 2, 0 }, + /* 90*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, -1, 0.0f, "[01]1234567890123A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 385: Invalid character in Compressed Field data (digits only)", 0, 0 }, + /* 91*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "[01]1234567890123A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 385: Invalid character in Compressed Field data (digits only)", 0, 0 }, + /* 92*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, -1, 0.0f, "[01]123456789012315", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 259: Invalid data length for AI (01) at position 1", 0, 0 }, + /* 93*/ { BARCODE_DBAR_EXPSTK, GS1NOCHECK_MODE, -1, -1, -1, 0.0f, "[01]123456789012315", 0, 5, 102, "", 2, 0 }, + /* 94*/ { BARCODE_DBAR_EXPSTK, -1, 12, -1, -1, 0.0f, "[01]12345678901231", 0, 5, 102, "", 2, 0 }, /* Cols > 11 ignored */ + /* 95*/ { BARCODE_DBAR_EXPSTK, -1, -1, 12, -1, 0.0f, "[01]12345678901231", 0, 5, 102, "", 2, 0 }, /* Rows > 11 ignored */ + /* 96*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, -1, 0.0f, "[01]12345678901231", 0, 9, 53, "", 1, 0 }, + /* 97*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, -1, 0.0f, "[01]12345678901231", 0, 5, 102, "", 2, 0 }, + /* 98*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, -1, 0.0f, "[01]12345678901231", 0, 1, 134, "", 3, 0 }, + /* 99*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, -1, 0.0f, "[01]12345678901231", 0, 1, 134, "", 4, 0 }, + /*100*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, -1, 0.0f, "[01]12345678901231", 0, 5, 102, "", 2, 2 }, + /*101*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, -1, 0.0f, "[01]12345678901231", 0, 5, 102, "", 2, 3 }, + /*102*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 13, 102, "", 2, 0 }, + /*103*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 25, 53, "", 1, 0 }, + /*104*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 13, 102, "", 2, 0 }, + /*105*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 9, 151, "", 3, 0 }, + /*106*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 5, 200, "", 4, 0 }, + /*107*/ { BARCODE_DBAR_EXPSTK, -1, 5, -1, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 5, 249, "", 5, 0 }, + /*108*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 5, 200, "", 4, 2 }, + /*109*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 9, 151, "", 3, 3 }, + /*110*/ { BARCODE_DBAR_EXPSTK, -1, -1, 4, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 13, 102, "", 2, 4 }, + /*111*/ { BARCODE_DBAR_EXPSTK, -1, -1, 5, -1, 0.0f, "[8110]106141416543213500110000310123196000", 0, 13, 102, "", 2, 5 }, + /*112*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, -1, 0.0f, "[91]123456789012345678901", 0, 9, 102, "", 2, 0 }, + /*113*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, -1, 0.0f, "[91]123456789012345678901", 0, 17, 53, "", 1, 0 }, + /*114*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, -1, 0.0f, "[91]123456789012345678901", 0, 9, 102, "", 2, 0 }, + /*115*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, -1, 0.0f, "[91]123456789012345678901", 0, 5, 151, "", 3, 0 }, + /*116*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, -1, 0.0f, "[91]123456789012345678901", 0, 5, 200, "", 4, 0 }, + /*117*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, -1, 0.0f, "[91]123456789012345678901", 0, 5, 151, "", 3, 2 }, + /*118*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, -1, 0.0f, "[91]123456789012345678901", 0, 9, 102, "", 2, 3 }, + /*119*/ { BARCODE_DBAR_EXPSTK, -1, -1, 4, -1, 0.0f, "[91]123456789012345678901", 0, 9, 102, "", 2, 4 }, + /*120*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, -1, 0.0f, "[91]123456789012345678901", 0, 9, 102, "", 2, 0 }, + /*121*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 17, 102, "", 2, 0 }, + /*122*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 33, 53, "", 1, 0 }, + /*123*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 17, 102, "", 2, 0 }, + /*124*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 151, "", 3, 0 }, + /*125*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 200, "", 4, 0 }, + /*126*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 200, "", 4, 0 }, + /*127*/ { BARCODE_DBAR_EXPSTK, -1, 5, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 249, "", 5, 0 }, + /*128*/ { BARCODE_DBAR_EXPSTK, -1, 6, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 298, "", 6, 0 }, + /*129*/ { BARCODE_DBAR_EXPSTK, -1, 7, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 347, "", 7, 0 }, + /*130*/ { BARCODE_DBAR_EXPSTK, -1, 8, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 396, "", 8, 0 }, + /*131*/ { BARCODE_DBAR_EXPSTK, -1, 9, -1, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 1, 428, "", 9, 0 }, + /*132*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 5, 249, "", 5, 2 }, + /*133*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 151, "", 3, 3 }, + /*134*/ { BARCODE_DBAR_EXPSTK, -1, -1, 4, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 9, 151, "", 3, 4 }, + /*135*/ { BARCODE_DBAR_EXPSTK, -1, -1, 5, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 17, 102, "", 2, 5 }, + /*136*/ { BARCODE_DBAR_EXPSTK, -1, -1, 6, -1, 0.0f, "[91]1234567890123456789012345678901234567890123456789", 0, 17, 102, "", 2, 6 }, + /*137*/ { BARCODE_DBAR_EXPSTK, -1, -1, -1, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 0 }, + /*138*/ { BARCODE_DBAR_EXPSTK, -1, 1, -1, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 41, 53, "", 1, 0 }, + /*139*/ { BARCODE_DBAR_EXPSTK, -1, 2, -1, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 0 }, + /*140*/ { BARCODE_DBAR_EXPSTK, -1, 3, -1, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 13, 151, "", 3, 0 }, + /*141*/ { BARCODE_DBAR_EXPSTK, -1, 4, -1, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 9, 200, "", 4, 0 }, + /*142*/ { BARCODE_DBAR_EXPSTK, -1, 5, -1, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 9, 249, "", 5, 0 }, + /*143*/ { BARCODE_DBAR_EXPSTK, -1, 6, -1, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 5, 298, "", 6, 0 }, + /*144*/ { BARCODE_DBAR_EXPSTK, -1, 7, -1, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 5, 347, "", 7, 0 }, + /*145*/ { BARCODE_DBAR_EXPSTK, -1, -1, 1, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 0 }, + /*146*/ { BARCODE_DBAR_EXPSTK, -1, -1, 2, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 5, 298, "", 6, 2 }, + /*147*/ { BARCODE_DBAR_EXPSTK, -1, -1, 3, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 9, 200, "", 4, 3 }, + /*148*/ { BARCODE_DBAR_EXPSTK, -1, -1, 4, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 13, 151, "", 3, 4 }, + /*149*/ { BARCODE_DBAR_EXPSTK, -1, -1, 5, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 13, 151, "", 3, 5 }, + /*150*/ { BARCODE_DBAR_EXPSTK, -1, -1, 6, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 6 }, + /*151*/ { BARCODE_DBAR_EXPSTK, -1, -1, 7, -1, 0.0f, "[91]12345678901234567890123456789012345678901234567890123456789012", 0, 21, 102, "", 2, 7 }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1568,11 +1619,15 @@ static void test_input(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - -1 /*option_1*/, data[i].option_2, data[i].option_3, -1 /*output_options*/, + -1 /*option_1*/, data[i].option_2, data[i].option_3, data[i].output_options, data[i].data, -1, debug); + if (data[i].height) { + symbol->height = data[i].height; + } ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); @@ -1595,6 +1650,56 @@ static void test_input(const testCtx *const p_ctx) { testFinish(); } +/* `combins()` in ISO/IEC 24724:2011 Annex B */ +/**************************************************************************** + * dbar_combins(n,r): returns the number of Combinations of r selected from n: + * Combinations = n! / (n - r)! * r! + ****************************************************************************/ +static int test_generate_dbar_combins(const int n, const int r) { + int i; + int maxDenom, minDenom; + int val = 1, j = 1; + + if (n - r > r) { + minDenom = r; + maxDenom = n - r; + } else { + minDenom = n - r; + maxDenom = r; + } + for (i = n; i > maxDenom; i--) { + val *= i; + if (j <= minDenom) { + val /= j; + j++; + } + } + for (; j <= minDenom; j++) { + val /= j; + } + return val; +} + +/* Dummy to generate `combins()` */ +static void test_generate_combins(const testCtx *const p_ctx) { + int i, j; + + if (!p_ctx->generate) { + return; + } + + printf(" static const short combins[18][6] = {\n"); + for (i = 0; i < 18; i++) { + printf(" {% 2d,% 3d,", test_generate_dbar_combins(i, 0), test_generate_dbar_combins(i, 1)); + for (j = 2; j < 4; j++) { + printf("% 4d,", test_generate_dbar_combins(i, j)); + } + printf("% 5d,% 5d }%c /*% 3d */\n", + test_generate_dbar_combins(i, 4), test_generate_dbar_combins(i, 5), i == 17 ? ' ' : ',', i); + } + printf(" };\n"); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -1604,6 +1709,7 @@ int main(int argc, char *argv[]) { { "test_binary_buffer_size", test_binary_buffer_size }, { "test_hrt", test_hrt }, { "test_input", test_input }, + { "test_generate_combins", test_generate_combins }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_svg.c b/backend/tests/test_svg.c index 1aa35f31..6e7d669f 100644 --- a/backend/tests/test_svg.c +++ b/backend/tests/test_svg.c @@ -202,7 +202,7 @@ static void test_print(const testCtx *const p_ctx) { have_vnu = testUtilHaveVnu(); assert_nonzero(testUtilDataPath(data_dir_path, sizeof(data_dir_path), data_dir, NULL), - "testUtilDataPath(%s) == 0\n", data_dir); + "testUtilDataPath(%s) == 0\n", data_dir); if (!testUtilDirExists(data_dir_path)) { ret = testUtilMkDir(data_dir_path); assert_zero(ret, "testUtilMkDir(%s) ret %d != 0 (%d: %s)\n", data_dir_path, ret, errno, strerror(errno)); @@ -218,8 +218,8 @@ static void test_print(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, - data[i].option_1, data[i].option_2, data[i].option_3, data[i].output_options, - data[i].data, -1, debug); + data[i].option_1, data[i].option_2, data[i].option_3, data[i].output_options, + data[i].data, -1, debug); if (data[i].show_hrt != -1) { symbol->show_hrt = data[i].show_hrt; } @@ -252,23 +252,23 @@ static void test_print(const testCtx *const p_ctx) { ret = ZBarcode_Encode(symbol, TCU(text), text_length); assert_equal(ret, data[i].ret, "i:%d %s ZBarcode_Encode ret %d != %d (%s)\n", - i, testUtilBarcodeName(data[i].symbology), ret, data[i].ret, symbol->errtxt); + i, testUtilBarcodeName(data[i].symbology), ret, data[i].ret, symbol->errtxt); strcpy(symbol->outfile, svg); ret = ZBarcode_Print(symbol, data[i].rotate_angle); assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0\n", - i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret); + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret); assert_nonzero(testUtilDataPath(expected_file, sizeof(expected_file), data_dir, data[i].expected_file), - "i:%d testUtilDataPath == 0\n", i); + "i:%d testUtilDataPath == 0\n", i); if (p_ctx->generate) { printf(" /*%3d*/ { %s, %s, %d, %s, %d, %d, %d, %d, %d, %d, %.8g, \"%s\", \"%s\", %d, \"%s\", \"%s\", %s, \"%s\", \"%s\" },\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), - data[i].border_width, testUtilOutputOptionsName(data[i].output_options), - data[i].whitespace_width, data[i].whitespace_height, data[i].show_hrt, + data[i].border_width, testUtilOutputOptionsName(data[i].output_options), + data[i].whitespace_width, data[i].whitespace_height, data[i].show_hrt, data[i].option_1, data[i].option_2, data[i].option_3, data[i].height, - data[i].fgcolour, data[i].bgcolour, data[i].rotate_angle, + data[i].fgcolour, data[i].bgcolour, data[i].rotate_angle, testUtilEscape(data[i].data, length, escaped, escaped_size), data[i].composite, testUtilErrorName(data[i].ret), data[i].expected_file, data[i].comment); ret = testUtilRename(symbol->outfile, expected_file); @@ -276,12 +276,12 @@ static void test_print(const testCtx *const p_ctx) { if (have_libreoffice) { ret = testUtilVerifyLibreOffice(expected_file, debug); assert_zero(ret, "i:%d %s libreoffice %s ret %d != 0\n", - i, testUtilBarcodeName(data[i].symbology), expected_file, ret); + i, testUtilBarcodeName(data[i].symbology), expected_file, ret); } if (have_vnu) { ret = testUtilVerifyVnu(expected_file, debug); /* Very slow */ assert_zero(ret, "i:%d %s vnu libreoffice %s ret %d != 0\n", - i, testUtilBarcodeName(data[i].symbology), expected_file, ret); + i, testUtilBarcodeName(data[i].symbology), expected_file, ret); } } else { assert_nonzero(testUtilExists(symbol->outfile), "i:%d testUtilExists(%s) == 0\n", i, symbol->outfile); @@ -289,7 +289,7 @@ static void test_print(const testCtx *const p_ctx) { ret = testUtilCmpSvgs(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpSvgs(%s, %s) %d != 0\n", - i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); symbol->output_options |= BARCODE_MEMORY_FILE; ret = ZBarcode_Print(symbol, data[i].rotate_angle); @@ -297,7 +297,7 @@ static void test_print(const testCtx *const p_ctx) { i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret, symbol->errtxt); assert_nonnull(symbol->memfile, "i:%d %s memfile NULL\n", i, testUtilBarcodeName(data[i].symbology)); assert_nonzero(symbol->memfile_size, "i:%d %s memfile_size 0\n", - i, testUtilBarcodeName(data[i].symbology)); + i, testUtilBarcodeName(data[i].symbology)); ret = testUtilWriteFile(memfile, symbol->memfile, symbol->memfile_size, "wb"); assert_zero(ret, "%d: testUtilWriteFile(%s) fail ret %d != 0\n", i, memfile, ret); @@ -338,20 +338,20 @@ static void test_outfile(const testCtx *const p_ctx) { skip_readonly_test = getuid() == 0; /* Skip if running as root on Unix as can't create read-only file */ #endif if (!skip_readonly_test) { - /* Excluding OS-dependent `errno` stuff */ + /* Excluding OS-dependent `errno` stuff */ static char expected_errtxt[] = "680: Could not open SVG output file ("; (void) testUtilRmROFile(symbol.outfile); /* In case lying around from previous fail */ assert_nonzero(testUtilCreateROFile(symbol.outfile), "zint_svg_plot testUtilCreateROFile(%s) fail (%d: %s)\n", - symbol.outfile, errno, strerror(errno)); + symbol.outfile, errno, strerror(errno)); ret = zint_svg_plot(&symbol, 0); assert_equal(ret, ZINT_ERROR_FILE_ACCESS, "zint_svg_plot ret %d != ZINT_ERROR_FILE_ACCESS (%d) (%s)\n", - ret, ZINT_ERROR_FILE_ACCESS, symbol.errtxt); + ret, ZINT_ERROR_FILE_ACCESS, symbol.errtxt); assert_zero(testUtilRmROFile(symbol.outfile), "zint_svg_plot testUtilRmROFile(%s) != 0 (%d: %s)\n", - symbol.outfile, errno, strerror(errno)); + symbol.outfile, errno, strerror(errno)); assert_zero(strncmp(symbol.errtxt, expected_errtxt, sizeof(expected_errtxt) - 1), "strncmp(%s, %s) != 0\n", - symbol.errtxt, expected_errtxt); + symbol.errtxt, expected_errtxt); } symbol.output_options |= BARCODE_STDOUT; @@ -364,7 +364,71 @@ static void test_outfile(const testCtx *const p_ctx) { symbol.vector = NULL; ret = zint_svg_plot(&symbol, 0); assert_equal(ret, ZINT_ERROR_INVALID_DATA, "zint_svg_plot ret %d != ZINT_ERROR_INVALID_DATA (%d) (%s)\n", - ret, ZINT_ERROR_INVALID_DATA, symbol.errtxt); + ret, ZINT_ERROR_INVALID_DATA, symbol.errtxt); + + testFinish(); +} + +#include "filemem.h" + +static void test_fm(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + const char *data; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_ACCESS, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_OPEN }, + /* 1*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 5, 11, 0, 0, 0 }, 2, FM_FAIL_ID_PUTS }, + /* 1*/ { BARCODE_DATAMATRIX, BARCODE_MEMORY_FILE, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_PUTS }, + /* 2*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 3, 0, 0, 0 }, 2, FM_FAIL_ID_PUTC }, + /* 3*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 10, 21, 0, 0 }, 3, FM_FAIL_ID_PUTSF }, + /* 3*/ { BARCODE_DATAMATRIX, BARCODE_MEMORY_FILE, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_PUTSF }, + /* 4*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 3, 0, 0, 0 }, 2, FM_FAIL_ID_PRINTF }, + /* 4*/ { BARCODE_DATAMATRIX, BARCODE_MEMORY_FILE, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_PRINTF }, + /* 5*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, "out.svg"); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_fm_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } testFinish(); } @@ -374,6 +438,7 @@ int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ { "test_print", test_print }, { "test_outfile", test_outfile }, + { "test_fm", test_fm }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_telepen.c b/backend/tests/test_telepen.c index 2947a91a..ab84cbf5 100644 --- a/backend/tests/test_telepen.c +++ b/backend/tests/test_telepen.c @@ -319,15 +319,16 @@ static void test_input(const testCtx *const p_ctx) { /* 5*/ { BARCODE_TELEPEN, 1, "\020", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 397: DLE (ASCII 16) cannot be first character in Full ASCII + Compressed Numeric Mode" }, /* 6*/ { BARCODE_TELEPEN, -1, "A\020B", -1, 0, 1, 96, "" }, /* 7*/ { BARCODE_TELEPEN, 1, "A\020B", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 396: Invalid character at position 3 in input (digits and \"X\" only)" }, - /* 8*/ { BARCODE_TELEPEN_NUM, -1, "1234567890", -1, 0, 1, 128, "" }, - /* 9*/ { BARCODE_TELEPEN_NUM, -1, "123456789A", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 393: Invalid character at position 10 in input (digits and \"X\" only)" }, - /* 10*/ { BARCODE_TELEPEN_NUM, -1, "123456789X", -1, 0, 1, 128, "" }, /* [0-9]X allowed */ - /* 11*/ { BARCODE_TELEPEN_NUM, -1, "12345678X9", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 394: Invalid odd position 9 of \"X\" in Telepen data" }, /* X[0-9] not allowed */ - /* 12*/ { BARCODE_TELEPEN_NUM, -1, "1X34567X9X", -1, 0, 1, 128, "" }, /* [0-9]X allowed multiple times */ - /* 13*/ { BARCODE_TELEPEN_NUM, -1, "\020", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 398: DLE (ASCII 16) cannot be first character in Compressed Numeric Mode" }, - /* 14*/ { BARCODE_TELEPEN_NUM, 1, "\020", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 398: DLE (ASCII 16) cannot be first character in Compressed Numeric Mode" }, - /* 15*/ { BARCODE_TELEPEN_NUM, -1, "12\020é", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 395: Invalid character at position 4 in input, extended ASCII not allowed" }, - /* 16*/ { BARCODE_TELEPEN_NUM, 1, "12\020é", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 395: Invalid character at position 4 in input, extended ASCII not allowed" }, + /* 8*/ { BARCODE_TELEPEN, 1, "A\02012X3", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 394: Invalid odd position 4 of \"X\" in Telepen data" }, + /* 9*/ { BARCODE_TELEPEN_NUM, -1, "1234567890", -1, 0, 1, 128, "" }, + /* 10*/ { BARCODE_TELEPEN_NUM, -1, "123456789A", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 393: Invalid character at position 10 in input (digits and \"X\" only)" }, + /* 11*/ { BARCODE_TELEPEN_NUM, -1, "123456789X", -1, 0, 1, 128, "" }, /* [0-9]X allowed */ + /* 12*/ { BARCODE_TELEPEN_NUM, -1, "12345678X9", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 394: Invalid odd position 9 of \"X\" in Telepen data" }, /* X[0-9] not allowed */ + /* 13*/ { BARCODE_TELEPEN_NUM, -1, "1X34567X9X", -1, 0, 1, 128, "" }, /* [0-9]X allowed multiple times */ + /* 14*/ { BARCODE_TELEPEN_NUM, -1, "\020", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 398: DLE (ASCII 16) cannot be first character in Compressed Numeric Mode" }, + /* 15*/ { BARCODE_TELEPEN_NUM, 1, "\020", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 398: DLE (ASCII 16) cannot be first character in Compressed Numeric Mode" }, + /* 16*/ { BARCODE_TELEPEN_NUM, -1, "12\020é", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 395: Invalid character at position 4 in input, extended ASCII not allowed" }, + /* 17*/ { BARCODE_TELEPEN_NUM, 1, "12\020é", -1, ZINT_ERROR_INVALID_DATA, -1, -1, "Error 395: Invalid character at position 4 in input, extended ASCII not allowed" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; diff --git a/backend/tests/test_tif.c b/backend/tests/test_tif.c index ccd0e82a..257c2801 100644 --- a/backend/tests/test_tif.c +++ b/backend/tests/test_tif.c @@ -175,6 +175,7 @@ static void test_print(const testCtx *const p_ctx) { int option_2; int height; float scale; + float dpmm; const char *fgcolour; const char *bgcolour; const char *data; @@ -183,32 +184,33 @@ static void test_print(const testCtx *const p_ctx) { const char *comment; }; static const struct item data[] = { - /* 0*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "112233", "EEDDCC", "A", "", "code128_fgbg.tif", "" }, - /* 1*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "FFFFFF", "000000", "A", "", "code128_reverse.tif", "" }, - /* 2*/ { BARCODE_CODE128, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0, "112233", "CCDDEE", "A", "", "code128_cmyk_fgbg.tif", "" }, - /* 3*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "C00000", "FEDCBACC", "A", "", "code128_bgalpha.tif", "" }, - /* 4*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "00000099", "FEDCBA", "A", "", "code128_fgalpha.tif", "" }, - /* 5*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "00000099", "FEDCBACC", "A", "", "code128_fgbgalpha.tif", "" }, - /* 6*/ { BARCODE_CODE128, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0, "C00000", "FEDCBA", "A", "", "code128_cmyk.tif", "" }, - /* 7*/ { BARCODE_CODE128, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0, "C0000099", "FEDCBACC", "A", "", "code128_cmyk_fgbgalpha.tif", "" }, - /* 8*/ { BARCODE_CODE128, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0, "71,0,40,44", "10,0,20,5", "A", "", "code128_cmyk_fgbgcmyk.tif", "" }, - /* 9*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "C00000", "FEDCBACC", "1234", "", "ultra_bgalpha.tif", "" }, - /* 10*/ { BARCODE_ULTRA, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0, "C00000", "FEDCBACC", "1234", "", "ultra_cmyk_bgalpha.tif", "" }, - /* 11*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "000000BB", "FEDCBA", "1234", "", "ultra_fgalpha.tif", "" }, - /* 12*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "000000BB", "FEDCBACC", "1234", "", "ultra_fgbgalpha.tif", "" }, - /* 13*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "000000BB", "", "1234", "", "ultra_fgalpha_nobg.tif", "" }, - /* 14*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0, "", "FEDCBACC", "1234", "", "ultra_bgalpha_nofg.tif", "" }, - /* 15*/ { BARCODE_ULTRA, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0.5f, "", "", "1", "", "ultra_odd.tif", "" }, - /* 16*/ { BARCODE_ULTRA, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0, "", "", "1234", "", "ultra_cmyk.tif", "" }, - /* 17*/ { BARCODE_ULTRA, -1, 1, BARCODE_BOX, 1, 1, -1, -1, -1, 0, 0, "FF0000", "0000FF", "1234", "", "ultra_fgbg_hvwsp1_box1.tif", "" }, - /* 18*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, -1, -1, -1, 4, 84, 0, 2, "", "", "1", "", "hanxin_v84_l4_scale2.tif", "" }, - /* 19*/ { BARCODE_AZTEC, -1, -1, -1, -1, -1, -1, -1, 32, 0, 0, "4BE055", "", "1", "", "aztec_v32_fg.tif", "" }, - /* 20*/ { BARCODE_DAFT, -1, -1, -1, -1, -1, -1, -1, -1, 8, 0.5f, "", "", "F", "", "daft_height8_scale0.5.tif", "" }, - /* 21*/ { BARCODE_DAFT, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0.5f, "", "", "DAFT", "", "daft_height1_scale0.5.tif", "" }, - /* 22*/ { BARCODE_EAN8, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "9501234", "", "ean8_gss_5.2.2.2-1.tif", "" }, - /* 23*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, "", "", "9501234", "", "ean8_gss_5.2.2.2-1.tif", "" }, - /* 24*/ { BARCODE_EAN8, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, "", "", "9501234", "", "ean8_gss_5.2.2.2-1_gws.tif", "" }, - /* 25*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0, "", "", "9501234", "", "ean8_gss_5.2.2.2-1_gws.tif", "" }, + /* 0*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "112233", "EEDDCC", "A", "", "code128_fgbg.tif", "" }, + /* 1*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "FFFFFF", "000000", "A", "", "code128_reverse.tif", "" }, + /* 2*/ { BARCODE_CODE128, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "112233", "CCDDEE", "A", "", "code128_cmyk_fgbg.tif", "" }, + /* 3*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "C00000", "FEDCBACC", "A", "", "code128_bgalpha.tif", "" }, + /* 4*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "00000099", "FEDCBA", "A", "", "code128_fgalpha.tif", "" }, + /* 5*/ { BARCODE_CODE128, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "00000099", "FEDCBACC", "A", "", "code128_fgbgalpha.tif", "" }, + /* 6*/ { BARCODE_CODE128, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "C00000", "FEDCBA", "A", "", "code128_cmyk.tif", "" }, + /* 7*/ { BARCODE_CODE128, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "C0000099", "FEDCBACC", "A", "", "code128_cmyk_fgbgalpha.tif", "" }, + /* 8*/ { BARCODE_CODE128, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "71,0,40,44", "10,0,20,5", "A", "", "code128_cmyk_fgbgcmyk.tif", "" }, + /* 9*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "C00000", "FEDCBACC", "1234", "", "ultra_bgalpha.tif", "" }, + /* 10*/ { BARCODE_ULTRA, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "C00000", "FEDCBACC", "1234", "", "ultra_cmyk_bgalpha.tif", "" }, + /* 11*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "000000BB", "FEDCBA", "1234", "", "ultra_fgalpha.tif", "" }, + /* 12*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "000000BB", "FEDCBACC", "1234", "", "ultra_fgbgalpha.tif", "" }, + /* 13*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "000000BB", "", "1234", "", "ultra_fgalpha_nobg.tif", "" }, + /* 14*/ { BARCODE_ULTRA, -1, -1, -1, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "", "FEDCBACC", "1234", "", "ultra_bgalpha_nofg.tif", "" }, + /* 15*/ { BARCODE_ULTRA, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0.5f, 0.0f, "", "", "1", "", "ultra_odd.tif", "" }, + /* 16*/ { BARCODE_ULTRA, -1, -1, CMYK_COLOUR, 1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "", "", "1234", "", "ultra_cmyk.tif", "" }, + /* 17*/ { BARCODE_ULTRA, -1, 1, BARCODE_BOX, 1, 1, -1, -1, -1, 0, 0.0f, 0.0f, "FF0000", "0000FF", "1234", "", "ultra_fgbg_hvwsp1_box1.tif", "" }, + /* 18*/ { BARCODE_HANXIN, UNICODE_MODE, -1, -1, -1, -1, -1, 4, 84, 0, 2.0f, 0.0f, "", "", "1", "", "hanxin_v84_l4_scale2.tif", "" }, + /* 19*/ { BARCODE_AZTEC, -1, -1, -1, -1, -1, -1, -1, 32, 0, 0.0f, 0.0f, "4BE055", "", "1", "", "aztec_v32_fg.tif", "" }, + /* 20*/ { BARCODE_DAFT, -1, -1, -1, -1, -1, -1, -1, -1, 8, 0.5f, 0.0f, "", "", "F", "", "daft_height8_scale0.5.tif", "" }, + /* 21*/ { BARCODE_DAFT, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0.5f, 0.0f, "", "", "DAFT", "", "daft_height1_scale0.5.tif", "" }, + /* 22*/ { BARCODE_EAN8, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "", "", "9501234", "", "ean8_gss_5.2.2.2-1.tif", "" }, + /* 23*/ { BARCODE_EANX, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "", "", "9501234", "", "ean8_gss_5.2.2.2-1.tif", "" }, + /* 24*/ { BARCODE_EAN8, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "", "", "9501234", "", "ean8_gss_5.2.2.2-1_gws.tif", "" }, + /* 25*/ { BARCODE_EANX, -1, -1, EANUPC_GUARD_WHITESPACE, -1, -1, -1, -1, -1, 0, 0.0f, 0.0f, "", "", "9501234", "", "ean8_gss_5.2.2.2-1_gws.tif", "" }, + /* 26*/ { BARCODE_CODE32, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0.0f, 200.0f / 25.4f, "", "", "14352312", "", "code32_dpmm_200dpi.tif", "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -258,6 +260,11 @@ static void test_print(const testCtx *const p_ctx) { if (data[i].scale) { symbol->scale = data[i].scale; } + if (data[i].dpmm) { + symbol->dpmm = data[i].dpmm; + symbol->scale = ZBarcode_Scale_From_XdimDp(symbol->symbology, ZBarcode_Default_Xdim(symbol->symbology), + symbol->dpmm, "TIF"); + } if (data[i].border_width != -1) { symbol->border_width = data[i].border_width; } @@ -294,12 +301,13 @@ static void test_print(const testCtx *const p_ctx) { "i:%d testUtilDataPath == 0\n", i); if (p_ctx->generate) { - printf(" /*%3d*/ { %s, %s, %d, %s, %d, %d, %d, %d, %d, %d, %.5g, \"%s\",\"%s\", \"%s\", \"%s\", \"%s\", \"%s\" },\n", + printf(" /*%3d*/ { %s, %s, %d, %s, %d, %d, %d, %d, %d, %d, %.5g, %.5g," + " \"%s\",\"%s\", \"%s\", \"%s\", \"%s\", \"%s\" },\n", i, testUtilBarcodeName(data[i].symbology), testUtilInputModeName(data[i].input_mode), data[i].border_width, testUtilOutputOptionsName(data[i].output_options), data[i].whitespace_width, data[i].whitespace_height, data[i].show_hrt, data[i].option_1, data[i].option_2, - data[i].height, data[i].scale, data[i].fgcolour, data[i].bgcolour, + data[i].height, data[i].scale, data[i].dpmm, data[i].fgcolour, data[i].bgcolour, testUtilEscape(data[i].data, length, escaped, escaped_size), data[i].composite, data[i].expected_file, data[i].comment); ret = testUtilRename(symbol->outfile, expected_file); @@ -394,12 +402,84 @@ static void test_outfile(const testCtx *const p_ctx) { testFinish(); } +#include "filemem.h" + +#ifndef NDEBUG +#define TEST_TIF_FM_TELL_NUM 4 +#else +#define TEST_TIF_FM_TELL_NUM 2 +#endif + +static void test_fm(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + const char *data; + int ret; + int ats[5]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 5, 11, 0, 0, 0 }, 2, FM_FAIL_ID_PUTC }, + /* 1*/ { BARCODE_DATAMATRIX, BARCODE_MEMORY_FILE, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_PUTC }, + /* 2*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 3, 0, 0, 0 }, 2, FM_FAIL_ID_WRITE }, + /* 3*/ { BARCODE_DATAMATRIX, BARCODE_MEMORY_FILE, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_WRITE }, + /* 4*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 2, 3, 4, 0 }, TEST_TIF_FM_TELL_NUM, FM_FAIL_ID_TELL }, + /* 5*/ { BARCODE_DATAMATRIX, BARCODE_MEMORY_FILE, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_TELL }, + /* 6*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 2, 0, 0, 0 }, 2, FM_FAIL_ID_SEEK }, + /* 7*/ { BARCODE_DATAMATRIX, BARCODE_MEMORY_FILE, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_SEEK }, + /* 8*/ { BARCODE_DATAMATRIX, -1, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + /* 9*/ { BARCODE_DATAMATRIX, BARCODE_MEMORY_FILE, "123", ZINT_ERROR_FILE_WRITE, { 1, 0, 0, 0, 0 }, 1, FM_FAIL_ID_CLOSE }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, "out.tif"); + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_zero(ret, "i:%d %s ZBarcode_Encode ret %d != 0 %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_fm_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_fm_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ { "test_pixel_plot", test_pixel_plot }, { "test_print", test_print }, { "test_outfile", test_outfile }, + { "test_fm", test_fm }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_upcean.c b/backend/tests/test_upcean.c index 124dc027..e7e39778 100644 --- a/backend/tests/test_upcean.c +++ b/backend/tests/test_upcean.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2019-2025 Robin Stuart + Copyright (C) 2019-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -119,6 +119,8 @@ static void test_upce_input(const testCtx *const p_ctx) { /* 73*/ { BARCODE_UPCE, "000000", 0, "", "00000000" }, /* 74*/ { BARCODE_UPCE, "000001", 0, "", "00000019" }, /* 75*/ { BARCODE_UPCE, "000002", 0, "", "00000028" }, + /* 76*/ { BARCODE_UPCE, "2001234000055", ZINT_ERROR_TOO_LONG, "Error 290: Input length 13 too long (maximum 8)", "" }, + /* 77*/ { BARCODE_UPCE, "0001234000040", ZINT_ERROR_TOO_LONG, "Error 290: Input length 13 too long (maximum 8)", "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; diff --git a/backend/tests/test_vector.c b/backend/tests/test_vector.c index 2bd7f8ac..bc45e729 100644 --- a/backend/tests/test_vector.c +++ b/backend/tests/test_vector.c @@ -3430,6 +3430,91 @@ static void test_hrt_content_segs(const testCtx *const p_ctx) { testFinish(); } +/* TODO: add new "raster.h" & put these in it */ +#define VECT_FAIL_ID_RECT 1 +#define VECT_FAIL_ID_HEXAGON 2 +#define VECT_FAIL_ID_CIRCLE 3 +#define VECT_FAIL_ID_STR 4 +#define VECT_FAIL_ID_SUBSTR 5 +#define VECT_FAIL_ID_HDR 6 + +INTERNAL void zint_test_vector_set_fail(const int op, const int at); + +static void test_alloc(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int border_width; + int output_options; + const char *data; + int ret; + int ats[6]; + int at_cnt; + int id; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_DATAMATRIX, -1, -1, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, VECT_FAIL_ID_HDR }, + /* 1*/ { BARCODE_DATAMATRIX, -1, -1, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, VECT_FAIL_ID_RECT }, + /* 2*/ { BARCODE_DATAMATRIX, -1, BARCODE_DOTTY_MODE, "123", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, VECT_FAIL_ID_CIRCLE }, + /* 3*/ { BARCODE_ULTRA, -1, -1, "123", ZINT_ERROR_MEMORY, { 3, 0, 0, 0, 0, 0 }, 1, VECT_FAIL_ID_RECT }, + /* 4*/ { BARCODE_MAXICODE, -1, -1, "123", ZINT_ERROR_MEMORY, { 5, 0, 0, 0, 0, 0 }, 1, VECT_FAIL_ID_HEXAGON }, + /* 5*/ { BARCODE_MAXICODE, -1, -1, "123", ZINT_ERROR_MEMORY, { 1, 2, 3, 0, 0, 0 }, 3, VECT_FAIL_ID_CIRCLE }, + /* 6*/ { BARCODE_TELEPEN, -1, -1, "AB", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, VECT_FAIL_ID_STR }, + /* 7*/ { BARCODE_TELEPEN, -1, -1, "AB", ZINT_ERROR_MEMORY, { 1, 0, 0, 0, 0, 0 }, 1, VECT_FAIL_ID_SUBSTR }, + /* 8*/ { BARCODE_UPCE, -1, EANUPC_GUARD_WHITESPACE, "123456+12", ZINT_ERROR_MEMORY, { 1, 2, 3, 4, 5, 0 }, 5, VECT_FAIL_ID_STR }, + /* 9*/ { BARCODE_UPCE, -1, -1, "123456+12", ZINT_ERROR_MEMORY, { 1, 20, 0, 0, 0, 0 }, 2, VECT_FAIL_ID_RECT }, + /* 10*/ { BARCODE_EAN8, -1, EANUPC_GUARD_WHITESPACE, "123456", ZINT_ERROR_MEMORY, { 1, 2, 3, 4, 0, 0 }, 4, VECT_FAIL_ID_STR }, + /* 11*/ { BARCODE_EAN8, -1, EANUPC_GUARD_WHITESPACE, "123456+12", ZINT_ERROR_MEMORY, { 1, 2, 3, 4, 5, 0 }, 5, VECT_FAIL_ID_STR }, + /* 12*/ { BARCODE_UPCA, -1, EANUPC_GUARD_WHITESPACE, "123456+12", ZINT_ERROR_MEMORY, { 1, 2, 3, 4, 5, 6 }, 6, VECT_FAIL_ID_STR }, + /* 13*/ { BARCODE_EAN13, -1, EANUPC_GUARD_WHITESPACE, "123456+12", ZINT_ERROR_MEMORY, { 1, 2, 3, 4, 5, 0 }, 5, VECT_FAIL_ID_STR }, + /* 14*/ { BARCODE_EAN13, -1, EANUPC_GUARD_WHITESPACE, "123456", ZINT_ERROR_MEMORY, { 1, 2, 3, 4, 0, 0 }, 4, VECT_FAIL_ID_STR }, + /* 15*/ { BARCODE_EAN_2ADDON, -1, EANUPC_GUARD_WHITESPACE, "12", ZINT_ERROR_MEMORY, { 1, 2, 0, 0, 0, 0 }, 2, VECT_FAIL_ID_STR }, + /* 16*/ { BARCODE_CODABLOCKF, -1, -1, "12", ZINT_ERROR_MEMORY, { 57, 58, 0, 0, 0, 0 }, 2, VECT_FAIL_ID_RECT }, + /* 17*/ { BARCODE_CHANNEL, 1, BARCODE_BOX, "12", ZINT_ERROR_MEMORY, { 10, 11, 12, 0, 0, 0 }, 3, VECT_FAIL_ID_RECT }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + int j; + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + for (j = 0; j < data[i].at_cnt; j++) { + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + data[i].data, -1, debug); + strcpy(symbol->outfile, "out.svg"); + if (data[i].border_width != -1) { + symbol->border_width = data[i].border_width; + } + ret = ZBarcode_Encode(symbol, ZCUCP(data[i].data), length); + assert_nonzero(ret < ZINT_ERROR, "i:%d %s ZBarcode_Encode ret %d >= ZINT_ERROR %s\n", + i, testUtilBarcodeName(data[i].symbology), ret, symbol->errtxt); + + zint_test_vector_set_fail(data[i].id, data[i].ats[j]); + ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/); + assert_equal(ret, data[i].ret, "i:%d j:%d ZBarcode_Print (%d,%d) ret %d != %d (%s)\n", + i, j, data[i].id, data[i].ats[j], ret, data[i].ret, symbol->errtxt); + ZBarcode_Reset(symbol); + } + zint_test_vector_set_fail(0, 0); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -3449,6 +3534,7 @@ int main(int argc, char *argv[]) { { "test_height", test_height }, { "test_height_per_row", test_height_per_row }, { "test_hrt_content_segs", test_hrt_content_segs }, + { "test_alloc", test_alloc }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index b1360977..0b7ad600 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -70,6 +70,7 @@ struct zint_symbol **testAssertPPSymbol = NULL; const char *testAssertFilename = ""; static const char *testName = NULL; static const char *testFunc = NULL; +static const char *testFailedFuncs[128] = {0}; /* Visual C++ 6 doesn't support variadic args to macros, so make do with functions, which have inferior behaviour, e.g. don't exit on failure, `assert_equal()` type-specific */ @@ -167,6 +168,9 @@ void testFinish(void) { } if (testAssertFailed) { printf("FAILED. (%d assertions failed)\n", testAssertFailed); + if (testFailed < ARRAY_SIZE(testFailedFuncs)) { + testFailedFuncs[testFailed] = testFunc; + } testFailed++; } else if (testDataset) { if (testAssertNum) { @@ -206,12 +210,21 @@ void testSkip(const char *msg) { /* End test program */ void testReport(void) { + int i; if (testFailed && testSkipped) { - printf("Total %d tests, %d skipped, %d **fails**.\n", testTests, testSkipped, testFailed); + printf("Total %d tests, %d skipped, %d **fails**: ", testTests, testSkipped, testFailed); + for (i = 0; i < testFailed; i++) { + printf(i == 0 ? "%s" : ", %s", testFailedFuncs[i]); + } + fputs("\n", stdout); exit(-1); } if (testFailed) { - printf("Total %d tests, %d **fails**.\n", testTests, testFailed); + printf("Total %d tests, %d **fails**: ", testTests, testFailed); + for (i = 0; i < testFailed; i++) { + printf(i == 0 ? "%s" : ", %s", testFailedFuncs[i]); + } + fputs("\n", stdout); exit(-1); } if (testSkipped) { @@ -1640,6 +1653,18 @@ int testUtilRename(const char *oldpath, const char *newpath) { #endif } +/* Create file. Returns 1 if successful, 0 if not */ +int testUtilCreateFile(const char *filename) { + FILE *fp = testUtilOpen(filename, "w+"); + if (fp == NULL) { + return 0; + } + if (fclose(fp) != 0) { + return 0; + } + return 1; +} + /* Create read-only file. Returns 1 if successful, 0 if not */ int testUtilCreateROFile(const char *filename) { #ifdef _WIN32 @@ -2677,7 +2702,6 @@ static int supports_extra_escape_mode(const struct zint_symbol *const symbol) { && (symbol->input_mode & 0x07) != GS1_MODE); } -#define z_isxdigit(c) (z_isdigit(c) || ((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f')) #define z_isodigit(c) ((c) <= '7' && (c) >= '0') /* Convert data to Ghostscript format for passing to bwipp_dump.ps */ diff --git a/backend/tests/testcommon.h b/backend/tests/testcommon.h index ca49ad0d..ddae4a93 100644 --- a/backend/tests/testcommon.h +++ b/backend/tests/testcommon.h @@ -49,6 +49,7 @@ extern "C" { #define ZINT_DEBUG_TEST_ZXINGCPP 512 #define ZINT_DEBUG_TEST_BWIPP_ZXINGCPP 1024 #define ZINT_DEBUG_TEST_AZTEC_SKIP_ALL 2048 +#define ZINT_DEBUG_TEST_PNG_FLUSH 4096 #ifdef ZINT_SANITIZEM /* Suppress clang -fsanitize=memory false positives */ #define ZINT_TESTUTIL_SANITIZEM_INIT = {0} @@ -190,6 +191,7 @@ int testUtilDirExists(const char *dirname); int testUtilMkDir(const char *dirname); int testUtilRmDir(const char *dirname); int testUtilRename(const char *oldpath, const char *newpath); +int testUtilCreateFile(const char *filename); int testUtilCreateROFile(const char *filename); int testUtilRmROFile(const char *filename); int testUtilReadFile(const char *filename, unsigned char *buffer, int buffer_size, int *p_size); diff --git a/backend/tests/tools/bwipp_dump.ps.tar.xz b/backend/tests/tools/bwipp_dump.ps.tar.xz index 4de6e205d1b165c5a5811ec645b7c7f15ab58942..a9cac3b456b4663c65cece2828fe4dd151d51c6f 100644 GIT binary patch literal 162940 zcmV(zK<2;wH+ooF000E$*0e?f03iV!0000G&sfap7`X5LT>vp1$yUEJ0H%@u`y9Po z7M&UcT)M1GaJ=_k5-&EC`p9&5s=`RrG%d36q5cLe_C*Q6#V$_XLig=g7Db$N*x_xbGlT-f?@@$Ef^4C}=Dxn9YY3 z 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
  • oM*j6jiv+qDuuAs?LV=`hM7RQ*#qrS7OvCyXaFg1fq)#x@`V7$=x$X z{fZ^p^{wJ1?!WRFU*2g~%7!mBbMhPXXjQWwR=A%tI1w5F&={tD`=xU{x4k%27Z&vx z#!xUq*TO6i6qIAZ5}eMulP78Y)8LhN+CHs^+-8 z4{idAliYD2;X7@bcWc)mo8EIv{9x*#>?;0+n_zC8wQiRppYzjz+GMVAr_O*8(g~3s zbq0Ls0C(n9(_r+{-)h19&v<&Nj;(;#obzgrU!*z7Z*9|)zc%}smUi^1ae>eLQ?`%nDiMUOWaOGn;K8L^ z=LB0y26QZ)w`Y}u`{N!g`3y*n(jpX`6*g%A`!nt&aR}Z(U+%A4)~u+m60Th)h_CVo zCvu|%Aja_|A)exEszaWzHy{l4nVhs;O%hBz>n9_XmZD+{@_pmX`>D8glMq5+f?p zBuQVo`_-|;T%#a_@Y|PvkYU?OI2aD!XpO@>BJ{dWhVb6=S7`URtIJ@zG=1fEM3yj( zBAW<6@GEpom%L}UvJAjvtgev@(;Eu)A%6ZrU}aYOr&_IPjhyRtmXpF@SI)C(Z8jbz zy)-Y|A@71%l!ds< zZQL1C=kR|czP%9188ES^s?f(Qf1j57SzV!4N4WcK_UWoTMeR^x@Le1I)x;PidT@x_ z962H=$_q5KUk!7P)G^Z#)M4;hVw_TxS_B@$?gH1)xxr>2RA4RWm?>c9hOwZzRE8RV zDK@$EFo2z8gh#kgbPYea9E|pViYN_it>f~V3jnynDS?d7yH4adRd2Sd5db+t-+3k~ zmOBsMx>MvfC1xs!p_sYy{wiA`Ew!nc4vQGV&ou-)WH9%&e!YT+*@&)*jm^UW!?pW!ppbr9Sb|!yWc?wERBKDC@{n+#wtG1O-qK9X~ZMbkQB} zTu8s^L^@*cg9_D?^f6{CxXjkA{bCjJp;ft>XaHTyW`yucSf7ph_Shhl5W#(WP&xDd zTssQgh$&sU9sw=H-Tm>8Zkz(K!0`EsZM+jd2$|m-0o038a*hQu zAjg=2!6pW>qoe@kqmDz&9tBk7K)uZ~1KsYtjs{rDhOB0T6=Si$U+#IJ2^(e&so0yg zi{!lqv(!JWyyQcjVsV5=UPA>mEMY^UAm`rE26<1LG!p?#5MXFqfQeiH`|$vqXVm!e z;#x&gSfn+&@@2g0mh8rvakW1bHB&xX|JX&FWkL%uq&Q$mO_b`LRULF-Xm(ch+Iat! zlb2R`^afQ<0c&_byLT%Dj1?&yxbDy)hwd}ntT5iK|7pyD_!vnzdJy92I|6(RQBn~7 zcYW$7z88+Oy&vxb4jxRMyNwIrWP0)qO~r~vEtMm2@{FA=7*XIL|J2`ux`3E}v>fhG zm*TU4?pYa@J7c{pp0$7>;QX_@2~<9!RvP6crb$~ucRk~SbchW-cG<~8mCf;M*;cIX zkQL#P1r_#wdPDtF;M`jxhfH7nlj_}?#Wtwo4|jFpZ2XYh@+`B$;ghtv234;%*TUO~ z5&g%N5osVQ1kzNf4LR2pNzVvb(-*0@u8-)|%`0>u`}t8>o?~At{e*9cdXNHOR|!L3 zl__Hgs~t5JM(*=?M28KaVIfhNFWGs?awO-PYE&~{OZ|kzI=JGAhkLR3i!YbI$VP;a zgNnc+fK$}08E1NC_ij(zk=*ew%aByf%Tx0wc@3-)LLn*R>^wJ3hY^Mo(T|Lr6nmPL zTpYJ}IM9$}AVPf&bZOHPfQ7eC%DDRs-Ltpqj^W~!dC9^$fhYSQ@%@smwjQzBlw7pQ zHQs;e&LH(WDH7g>wMKdv;ZN3>w0$ABdC3B$IhjBEDkkafZjWB%G%>-)O885@l}Ue= z3YP;gbaz&-C>OM5wB$+Dc=}i>%sNVV9U?%em=CGoqDVq);8PRFL4>7vxcj_#K9O|N zRFEvt=CKl6KX`3B?p%hFYp;!8k3zxCF{1?~ex@9=Ocpk`Jn852#!_p-1D%}1nMS}( ziB!@SzSbMCo7yy1)@euQ56w`c?Tui)!bB`SA{WaM=tJX7$c5!9S&Mb*qd=FTj3q7z zlzcfFY=*OZV+i6Np`0CP-Q7R2{Tndj%^c) z{hA#W4eCux2>{T7UG75~+@2cWBu9bZ=~C8nA(Y_uqHCUGoLpi}r4saGA_n2M{7&&<>n8+cgHGG>p1C0U!0JAYJlUVCIzY?!p+I6 zV8R^uU|FN?KGv$scN#uWd!vM_O>A%Lm4CR&rD*^yJc}o8sNgRgj3Y2gjJ0Tl?|0KX zrMF|yy7?qH+Pza;h?U1^V?7*oLhPmI5y$bQ`mQ#n?vfB_XL&;yY~+~Ue#R=K>}zCI zyw^NhXs6HUz|3ngf}CSKqU%*02t9X6by!OmDB7iXxC<O+05ijr1&WP;k)iP$&sVz;6Q-ns2E2hLaAV0&YM^Dfoo0k85 zmmaMBjZpwmd$bVWi|Vh~&ru6=h)qDY<{PQ_GqTh#;B(% z=$62&CUnkz=fE+CK(_T`yof>3Y3-^eAjKGi*Ap~(qzz(NjfZ5CdIQn<_sH$kV=8}Q zz8iSdg!jWJ%S*n*i9}}Sx1?iu!lT}_Ci^?VeXIPwlQk4 z{J!5%80LF4>xebWjt#=m8XJ3EB6%P$Wgq{fc;8C&ju|bAPv`4YbWBaQuS|+Xd-oRRaTDrsxN3%r!uEh z{I(j%-iwML-CVKMEp*#xTN-cBQ~TvEn<&cp3im_7|GfeF0>Fx1kn_t}YAx|+d#^z# zZ{;1Gtu_yZ{{?r1ddlPVGn74oJO55Lkd&Q*8nkk{KRvgDN4$7B+o85wRe|c3lfbu6 z(j_GqmioCk!WXsJbh^~(;8(*NV!ee!76m2X$w`7W0AE7Ld`K>qj~Y_Ey`Brb^Hca{R^xe^lQ%MN*4aZ*6L zuwfsEliWis2dm0hP!KUFfmH3!MFbQc@Cte2x0X)0K+7(40M3b#O@%cl?^(r|ov&u0 zqzl5Y3H~Z-Kp12`( z(AYS3*7F${gq;txj%nWrY`75_f%3!`$}~dUd`mSGG{y zIppqZ+eoBxk0^y9Ngh63bt!C>g5&}OlQXOG_aiCQOdkPjX>LH}PT-bB`05?H;@Vyp zry5{~#WY@iIOsGhWf**0`?WP6)GYtVk&z5n3aY4(np~^4UI~wjlWR;(P?bE~3zlgB z10^g{s0;Fk3Y&KUJ%+ooeAtEv)p6Lwovo6d0^r|AZR=sABA%Uy9p=Ar=-^sHo|rkZ zSgD1U;0`*Qu|se3klfVySa%QvhxvB0>G-O?^v(TRcaKhtmm#1@z5J$#%*hJ4P)JiY z`%XsVUhO{QW^?_IC!WMO%tuJBxd@v_Bzt;mbGt7S0=vNCqL3BA@7=Tk=v|_S&C+Fb27=L9&!IOmVIf&Uj!*`5Q55eyYtlOz zh(%9F0)m|VBDnC)kKpqff&RLE_=RP6nlx%5k^KAeA><>Sag%l*L0<6S=+mPtJQ^+V7AUZF-(2cM_n zOrqK8c$dUc0=m&Em^`f<^iSBd>c6}1)VEN9X$vjYD&GhVQr?qpi1z`0g24Aj;nYRMv}Nq{gX0kDk%xTjB!@I zbJbvI+po$-XE^THshy1bzAAL2xSA7*2CY>4AG>5pOnqPmm*Vz4*f4b;|B;RFNG5f-O_fvHUjN5 z$TlmDD5Ks+Dnd@pf=O!+6q;nxt(CFrSI0e7bg@eY0uERsXK6vcnW;@*O&LEU1Q+~P zCvbbU@b^LdfdMXAprUA*l+(#!!X-^>e6yEdr? zM#I)U^L<0%um@=9Hd)Z!qtBO@KW048F>Q(oi5iTSujc3;_23N3*!0A=EdbQ};sZ4k zi3n~Aft3NO3?go|47l0Z&%5jkWwqkvM5|te2);T0kfz1)KXx&|tsW)5gnb5Mo5c;( znKJO@wdHhbiVArgO+_!)^%Q=z*ybxw66o@K#Cf=1Bl8)+AS`+v)OxR0$C^|2nNl;ty?*vR>Lx<_G@XFHeH8-&V@pp*2-5-SZ8W0xR8klQsr` zNX>|Ryn}kK-#q1-H3ib<3EY)v2si^tUN#`4h#S}G?uV|%M-|`5@QYFpzgYbWk1;KV z@@Q)l9pBd~vt^QKs&ii<;6C_9E-lL7C8Zbyh%1{^>bo@6e6!{qvzy{tTE<1%gQbz=qHFYX8lo^kfu z+~4>ki1;_I(aS}D7$|I@cQ1B+n_-{0n1JRfCPLKbj;xT6i^8p4XjwADyB7p+cyKKE^EowI+%h6tm2r$iFmI5y0@AR4zF`C1N%GSzPIbToWoVj?*aQskpfbd zaT`*@%D=cphzt%ZWV~PbaW1}XBPEVI7F*m^$Et8w#&Nwpx=ysVHR=sAjLEUH9dVBM zrbb7ZhBlGAbkZV|XA{k0wn5y6NkI6+y_R2`SBYF$K!Pn|{?nQU133uv2a`3r^5E8xfdho*ay9kZ>ckP6rlQH5_TRZk*ip?`ddx7a1vG8%w>VJ{{@4%)5j=TtT zi<|F?`dq5*-Jv=h-*O9a?U@EkJAZ54sWS5rT6PibUZ?}KOtmN_E*pfR^2%e)7Wr&_N z@$!lDpH5+U@^@vB7c{?TxcYZtFpEK2ecw`is=k8V9rUH=7u;~67jPl*Xd{8Pw7XLT z)TD-(Sjg13#jW<^c!cD8aHppd+AIvtL0(}S73gxDtsEI<4MwkTeI8R+70*zb^LLE= z3Nh}AqFjJqf}=bw)#f$U&;K}rmab_K^h!oimK>6#fJ6P`xAyse;Iw<#^93`P*VB*g zI<<0y9eO#2qwzAZB-S=&Fb!}fm@Q@K_~jBB!os~#-LbPF#Dak@vSGoaEF`B1)Ylv8 z$;F8h>T0X2_tjXuO%05}y`;-FzYh{DM16){$l5sBxwADHueAYUG(WT`*D&TI^Ald1 zY-Pg1(i49E$p{Qbnb$GUvI2!8J9}y&9krxNz5V>n!(nOHK)fEN-|HvSID%25mAybV zm?;Ktq6t~$yOo^qZ&f{NX)jl!bQ{`VR;@QF!25`>H^op9`6YGn$Us*C#H!~AT^KV> zgzpqor`f9lh=n7!OqbhhzF9W!q-#ZGP!$Sg;VQ&)vH{heyD(b>23}NaCLo7buxgmY zNd29Ua{Gyd097e*pwbx(tY(%NmWXOxreHyZXEvo$P4QD0+XsxRbHVfN0+RXPndFX@m~$>~a0-7S*m0 zzDH$lSV_>atlR=*rTjAwwP5%|B21@=5;mn>PCdh7c;9o)UOi7sfX*u3w#JbM)6(zL-utk?;JYCn6+q;l=jYP4;Th{vc!OPr zgH|``Z}-ycKRfh+ad;RUy}hJHpag6kcJ@*YQJjYp(uUO4rit3r&$wEl(pF>hXLM79 zkot{`AIbjepUE}`0WKxOFjq>*f$Z2is9qmjV09x7Z|3oCA{Pd04n!14eQ50b^SMek z>~mMUGJQ*&k1{f{O1=XxU}|eAFs=}LBgZloH;)0%r{7aUQI(;>^0`Y-`45WEHe*pI zgZo{p>p`%Tdv~g^j#5RpCpM=?heU56Axgsnqxe zLj&$iMk=C?rvjbK9czg^hzwV~$zlrfnv)}v{)QYq-1Wolo+`iUCqMiX$x!xn;9{X} zi8=UZJL=2xmh#1shR2A;dFDo#UZYmhUc3%BGOb>h6|^-P;mL$a7vatE`CiKpyl`x@ zXi#96j`E6P9^A?Ms8MZhsgx*a9?H7>vVrOYH4g|bL)P_*6T;E1Da2yi+D1~e=SN}Y z3qcoRY>;-}xxYdMtKdYB97RxfbCY%m-Ws3W9$;o?+z+5|cyW+}LQm47Z zfA&*daqdvEjeVhGeeF66ipVAWH!Dv9>;Ag$i2Lt*BBDaBQXnvzJ$POEB>>YBX~x>Q z@&#oRaO$=VOBPq$%;|^cJE;wJ#OZo<1d$5W=Pc$PVS~;G8#>7Q4V}@Ew!eioQLEa z!<4|zm$W!$k{MTIzp+a|6NvS6k;xu`Z)BPSG2xUf&o9cCS8YLsF-Gnoe|{w<#Ur#OZoc&5b}JX zIFm6NfiClN-j;%@IK{A%40MiVKg&m^x1lfbj$o;P7b(?&7dny0RUdvT0+P72Wk=pI zp%=*gI{u@CGC#!!?8inoLI}@XY=|q(rT!b>%2LEfwAa%_--erT?#lDsoQC}bT31We zgJ)4uOX)9AXgs5xei0NxV#QZG`CP?_HlfHY!8qyhO1Y^Cy2U_pe=KeOL8G1vz)HN2 zp$^C8LoHfcs3CTFfJXQ9hZl9AJV6ZZ)XaYA%@gCSROQ*;D-y?=D*q}s)MP1>v?Sp> zm2Umq(Fee7h>eQsH~If7oeBr8k0q2iVgE^7Qv81|BG{Bma~FJ%3Q>)* zLl;DQ_kM!)o%z1(pmtJ8nwCp}>v}Sqe2jRW*r}R;eS`xS}0V)z_P*jYbJ0WZdQd))`5$Hh_w`Ey@ushAal>d8j0WDjYKty|KN1@icHA zH7Da-^4}=IL;ArwIH-HfM|FU~l%KX@ZTR&^4w+6sug4!JDY*vP2w7GRu7*bD4akz( zJCBMPz~`NH8`h~Wm|0w&hCQ>`o_fV^(~>22@(N^^wU*7}p{x?2S`8uT(=Z{xg-JLk zT%8>f2mJqXf5&r`9LZC@o(rtIc+Q>n%#x2(aF&e42imdsGx@s(M!rJv`Qq$G=O(^c zJkNm?#*d%mxW-7tz7BnQf%#Gq5-RTVz0O-_Qz=1+tg@`&3B{Si7#v15Fheo5~LjDk(o$P9$EQOSmyLWf7|&jg=0of1lm{PtaXRu_^$e%Gfn@~c;f z)r}SHaIc&YF6wo$@L62c*OS04$wB)(Pcxjc1U+pwkZd zH3MbKOZ&W7cX@b+hH$av?YXuwG^ZI>{EGtC9TGzMAQ6mHaC~q-|Ha_2LHMNzKNDZU zVHBZzsAu}gnV3y2vXiQ~``pe*YNbcPxBoytJ!>E`uka z!Aufs&m{8wDViTnVdORO<$=7In3_zh$Fw0KXXSm2R*n^$H&ppp`fKxN_DV?M7o-o4 zFPB^UOkTtLwUGr1dw48~mMR0n8zh^6g z7hPwg!a1ZYh^(L7hy*y7^15hv^OwtEzPD>EZmt44ckQT}o-k9P(+iv>O6Yg?Lt(Y7{-Bc!=~sj!~(2=b*&nSd61RYf@_IKg*TceW+Bvh*$89Wu<+i(Wed9t>6cSuts+wSsOc%0 z78^+4>0S&!?!hE_n2AC>+ata395J%*rbw+MqU&>`Edn4WWXBdyfnJ2N(MCw=0=_gV z0@I7dW`eI#Lwx|C32<|$$;+KnV_{Xm37?8k$1kh3BUSE@Ouj#0kFW+Dt5>P`blUsC zie%zSCB%oojzF}T(A)7viw*AgnVz^F123MtA0w}&; z2)uO(ICPynG;Kb82b#(R^o+C2zuHj-E?VN?_`^xK*@i)QU=NtpH%K2Qu)70helz2g zT(s1(9(j`3)_27-SmNMY>K9uH9MaP?KFh+Fom$SKQMYp`MUQ&Lko!Txrsi`dWO}&u(IHO4Td>CJfrB1|=E+UpD+ETL546hL9$h$i+GGmuxm9fUQJ6(hHayDmM z_x24=d#vx^`(FE8Caecjs`dZj9uAIDX*Y2~5*&+LCeDiMDR-A_&FZXp2uxj^gMaf~ zmChJYz0@bN04+@ItI8j4SxP9?zMHCUvJQ5=!5}**EU%eye^-4}g1?7pcLBD=v_c1$ zZxtCdeqyxl1*nl;P@sP_N~}lvj0d_};5OpMO4zc688Z$ck@ODkD@J9Mg3?nZQi9XZ z9;()47%m~8ASsSvhVr{_{@Wf)O&Qe4CrjKL9TtYsm%LgT=;Js9E3?GGjJvah`7&+r zG&6)Cd=AWd!lyl8L$c}f0^O~JQX6a}jgO_HmGByX@Mp$R#AvFx!zo(-R9MF`H?rbU z3J$Nq&-)6kzpZs zh|}{jie5Pnc4K$i&%isTho!~r>FT&4U+g@YrypH#-z{y^h|Imb$tX@*7eO8Q+h&SsiwSB6+=yHE1j|0Z@^U7_5drFNqEaMXYuh zP{5EIWt6*8d@C%L10f8o(^$%;dD+RfF~6WYM*w0_m;Ga6?Ic662P9wJ{Abq-lm{!~ zH10qeGj6Nv*~ucgwZS}EnS_mq874u@3oM^$7pY$-E+~HAD=5dWLWpe9TUvFaE5gaZE&k6G^1n36@Ad=rO&_>X)_ASa&ABxMH!DM;b`mEgNl@pj)TW zdjLm7;UEMH^$7&8MvdGA$CwaA0%XYsvOap++;A-s-W7^_#s$Iue%bBl(=PO8sJ3?} z=SeF_>+p5c)Gy?AiU0C=H`~1yCweB%fU{;nl!d$$P$|W_^3yN8KT`z}l1n%D$v=P$@63h|tJsKu zefW4!^*@3IItO~su6Q_KsEW0E4NPF?q0quqI$d{|N2E+PAI_MHo^h04<-bmmpW}FS+PG;6$PN#|{se zfxa=LgBcmps7TsIXZ_@@MUT5O`>1lGd{!&VSb(>OuC#6Fx#3kHjuU?%FZ0i7GOHyD$!S z59`A@Qx_S_%Q#GZJf*#Dw?E@AyOYC+*|`sp&JwHZJ&MU1+mc!VoeONkzxyGv_+8jo zRm_`7UST?*AS*6=lH-Oo@i_iII>MF9A%AJ(ljCWR@7ieNWQV zOa|))MHBtEMf5314eDFgDP=$5tU#fxL1Lelf42AZSAt#W4RUOXL2iUxQKq0wbOhyD^M$~HO zO=e6^L}R{HjRAT9;)vbDsy^(tHZyet1{dRo|JzeWZeczR&Z36oE3q=@v zQ=C=re6=23bXo9`)~5keL`F)h9}O(jFA0N^ejbCZGUo~ipXBnKzTZlCCQ2pm4_FK(gJ%^q%7ZncNx3YQ9=yHKRGLoFq3dlVHfKhsFg z>~CBBvXFG&hUe-r8buQ^V-0|E!j^J?9)4t_fYo3*-&Tt2CHxs}CJ*g8_1IzJm}-q` zSZWYpCG!j-SdV*<>~Um-`|3#mREZ^J$r>kM+ng-SA6D(D__PC`@T@DHmFj1IlT9?W z0*D+SiEPa8;$fxQ8zUK-6J;aSToSp$2GiS$F zAA34|$q2a@>vYVQE2tCFv^Qb3h{F&Vciy6`@_!N}~ zDQcT3^>u($T4$4C13>xwWttS7=x}Baolg!!Yu(V#7TCKLQHVaZ0Va#ehBKc+M66M+ zF>rpApPD?Mc-3tzJ+MlX2AW`4Y1*259F5|hNU#H86AAH9T(0}X-ES_zyVvF`{!S!t zvR;z^FOlgDAe`3?E_{AZg8Df#q5bEG@NOuym7>i+&!%-%Voa!%#h@)a@i;B$^!SM( zQEapL;kMBM*nQd%wR)CY&j7p9!cLrvjLXO;Sgul2Oi?7#EGL3DI3B{LGdPH z@Zz3y%Z9CW&yx}LVhKxg+4d?LdXNV8Xztwjs`1CQ)Fb6)6M~~AD8fyV44eObqvd+| zavN49eFyxBDs*0M9-HPF#lDM!_27dM*`xKEV5LwMwVKJ8$cTi&7%AQ1=h@PYYlY>a9-*0URc(t4@yiRIcK=y#q2SV$4rKEf%-FVAH^GbB*$ zbjmGrfmtBsB5J~_8d?VtFCuLH^w=-??Y^6kwByBTK zuE3=W{##IO8TBOb3Kr6Qb>#C-v9~6a~XbA^L|yK}Z3O11&c=5|R@Dr$lD6 ze40(bO4e%fe2piK@>%>NXaP$ap>#kP#7_)7usgUMamZ!wh-_u9M_g~x&`=h@;Gnyn zh;^Epx~fO2BHO1cZMb*2fyQxiZd+hp5TBA`kqYw)V8`Xqu+zN7^-||YmJ&5QV#Ojy z4?Go*pU;jb=-V%G#f*E%&HwLP;Lwxr^+{y$_H@F!ABK^=Bq{(cCEij>r84uLT5xUW zl-0_qd?D743&70OTcKqHtb+sVRv@x!f*LbDv=I_Gxz}eJ?`>vUJ2aDIv+bADg8-bj zF!29si3BQ#3Ws3tZ6v}3wehm0#gI>)rsQRzuGD%!8Gi_h{)qA6$_Oc*a-a7rNi9)~ zy{EPT3(2t9Mx>)0rAB95r!;D=?6XD(C&3GYWAj%NT30?7$HTvsN+GnWM4q_#5Z?8= ztOlSz_i<fAUg3-!igACpN9|BDaJq)HR^hyo9|||@ zyyDIJZYeE`gDRG;Ht)u_vGOQi_z{NFeuVOO6!>cWD08SW#?i-gVFm!yqg~~N!{c>k zo?R`^sN_hdk!dlKz3%_BM-R(XEUT8-4L{s%tL&bQY9Ywok?p(Hvm^cogHoGQw-`E_ z&(2ZSR^@7QC!A8lYVU zs}NA@tC-jGDzxN5(-sL&C~@kx^zUFOqk9^MqW86SCY*xqvoO!k^9YPs zy)0liR4AvmKd6zCpNGjy{M$nX3=V7zXm*5b0#^ur*|k8Extjypi-8$U_2>OuGV58+ zfEa&Yu2}%23O#xQ;T&6K$^|is6&M3K{+p{ZoAg^mP=ZO{iGaaW*SZD=UQW81!Z!o6wHNGB*!1I#&`!~1tQ5Im!c!+!6TVB21>O|V>XVtV~oAt&hRs+n~|3Dm?y9|#W8HicK|Kb zWH{HtCAQxybM(bHyIq(TCBk+B+NnF50QNw~;mrikgPIrA`;+4)2hNVG^M}J99MrN; zS1w~znfoIXwNNP<$3l1uG`_oavP+rr&6PeLse5l+VN2^&Z)1QrAGh6z>qfDYj7O{7 zDn>**ig1V(Ns0}tR6ngLj0vXKEe0$ADB_n^SfZ6FTwxhoZ9)C^|Kdb&k+708kN=qc zxz_=VKz4=`B6&t^>LoD(41;7QKo7R-GYR}9^?+m3v5{y> zB`=_Flc<~EktmWHc7yrfEyB zaSqU$#hie-1+0{16yh~R#n=3Cl`>w2LhET?49iT0^W@E|X^tL&UUmLS6?}|cZYMmC z&eqPn=13bD=AgVXBFNh^`h4H{Jl&H`vX~wS3j|Rm!(Hsxoh83K=+TjTgI^t6HM!TV zwM>`PnB0M;U|O|g5x>SnsX^!ML$KN2H3nw@_Mc~oo!5L1=rFl|(?c%s#3C#CW9GLd zT3s!^#t?z2;iJEaRE8it)xHC$rcG9~sGkRSXkra-?ZjHv2lh={Y(`7SiQYtvNHkN^ z?g_U>zS$J@pn-4r&K`c3DH;zH*W~6J4P(=R*3fh|=dK}OmjH?<%L`Q|*}R!h#q;~) zheDl$KP|jjma|ENNJZ(DT&)Opjer;u-x`568I|-52|8cx1sW zwu|vdySI(|2_!n~OzNM=vt6)->+^vl;tYE+E31BEL|2hAu^BCwLg$==7&)JDGC~3x zYxJQ!fO;^eRpZMxzfP}Rcz;mdNXaG@GZ(ker@pl-3W{Yar@`Uug~U}@Ti z54@*)$swYsu_G>Fl&IiuuHKoqV41}9f1EbXgh<%9^YnqpW8RuqzuIGTX4aRk7Au-% zjYr~?2E}8|;Scy66qx9baJb)Z_*$UNvfm<0&efgXPv94qRM_{kL6Cbj-&g8vF)+~6 zi91Y&+W701^e?>buv@ojX_+86<-tI--H=Tyzztr4|WB(=T*9*276+)C&Q>zB-_u} zO@S!qPFMEHPERA}G{M@U<9}b_&G9~he~785y!J7(qitk`{(Yna{V(NRDQbc*HwgQ- zOtzO--XC-J`3p>Rz%|tfM$9CpCh+i-TVxLUuV)9ENw?@{7?xeV=o*0Ic&ku5KVz?s zE@eVJFtsRKRsKDD=K^&&3RQVn=y;)q7~-{-g&7%C9j?dVA1+-Gl(rpuZ9%9ceb?hI zP7-w$!#}YXTe{XAE2D~QGi}TYhRs4PLu=zmMI6PfA?5SZ1{TbOeX^03JscLf#fO|; z?VmASWyy_L;n~PI#6|(4&6;+$d=x0LZArOD5>Xp}8URs1uD=I$c|;Xq@9%7ra0zcO zPrPS_GLTpQxl|2axgdJxT&=|6(Wq7EJgr_e;;;*Yg!Oleyln^<9q$k-D-FRHSmhJv zb&CTDp8jR*?;C~wM#fX{*y$H~c8mG5!1oP|&XAWWf40>_E$^lorPmJbSr=*q1r&_I zfC)nQ7qN$|xhLVk2vGDp{XoE?pm?-oSfw>FHYU_{eqP?b-3hdAbuu0NNmSqyPXkaD z`qp$@8Q=bmS*@-9sEI9NXQNAf#Mobi6zkJaGN#c#_)avnMZckEg(@!azT6x&&TAEU zb~z1NpT_;m`$C*=MnKZd>%G?F5H<=^Rvhm{-QVn>o2!1LAJxUEqQy8;pW)QMy$*-7R~yi81F>@{xx?z0HN(Q+Z=(mox;wx&iS7G5}1dg z<}5>MJ()W8ZC*y4v4lV`_uY_iQXpz0-WN)i`Ly`u$Wt|EE5}caZ>#HCH8z~ zbnR+`3J9hw!cU_jBwwjVt6>l%DLdgS9tg zmxWtSpy!i?iaYf|IoFD!;<`xpufH3wB@#MldNZ~yJ7$sH*OnuTRyL=x+3hAmqd?DL z57oIuFdNN>Grs=(Y;0_y5AJug7&}#`N3guqF}J-5Biy*g01A7?|b$OiKu~m9#y>mHWw28E4Zuy-X7cU zM@aW9cx|0UI8&X73@Oy4Kvm442`>$n?6}NC>_vc-Ru6B|=D9=Bn;`-HBD|_=(=*#lNrvWG;DbW$FYIu-E-*tzw{4Z zC(x?>{>eeXiP)c5P`abs{N>Gzi+~hkLOAR$qLR$+FW|a_7TJSYZvlwr0(eSh#;SeV zU$pem_ksVu{(s+I;{;5W@d){G9TgD^_e&;PM4X^0hOGk}+`M0boNFF!Gdl>Ny?`U* z!JHo1o<5rZ;v=i=!?1r`$4FmTNa@8W^F7sbrdNhQ?@j>Pr~u=6Y86g`uge{(KCM(reay0zZ%IN_ zi2Q*NRZCI?>%pOCe3lhUczKC+c|iYHD>gpxl<+p13MZX2TSJCAHl3K^e1&tshAC@vs5MB+_#36KMtipNc>wsu>t;8(q($Jr?%VID8f#3zyd3 zR%9x*hQbfjxnD85`{fXS{i%p`=B>qMfUF(Z?xmlY+0KfICUJs_^q!qkMk^ubMw0?f zhQ35t)L3gQ?9BtFWl23t+*o|qLz0xw*(RO=*k(>t&c_Vugm}sNsOgn&fzSjj{z0rK z#_-C3FkHj~6tH67YaQh#RCJHjYGq{xjzUM^s-6Byz%&E(mRB53nIE!vgX}ZZMn?}f zo0BJe_@eL~l0#Wo4e3*Hx6qmp$5Kx;cW?UUviyKaF%{GvE71k$>>^}QYzQecj!KJH(~|KUg;I|-UX(p|5%0Z&mW+eJS-+uA>% zdaau-k)l_4g^d1-X?Y>*>?7t-$K(;?^LeKCYm$K*feA*vG*lSI5yI53e$}{sDDw`^ zP1?7PrHr>`o|4+RdX;ftgmQ+m^oxo3J+v6u^Y8|}#o9hJu*qdTJ-YH1H_|;%y9nJ6 zL9vlebn?wN%^Y?bqZQViS}_ta#VveznFF^BDw6N!sG1msQo%cs)sWv#;DT;+pK7mW z4&3XHx`&@z>2oDWyXV2!~A}bt8I* zEP#S%P}y|T3Ug{jTU0=$u8RYpHywnu@3Sf$xgw}?Umg{|BhIXvyT$+TJauc}#7vi7 zN5aJry3ysjvita}5I2fCN6!=7CmtV6LVGOA0GkSppBkU!o z_n0#?(W%Dv9pdQ({ry@CI6sgA1CQ180Ege-b#-}xbzNR!-A>uFTOQZ_2>(XXHCmMd z9*Z`iMcsrbrVWJDE~0dMjj)N+3zbKFL046fLyZ<AxBdZ6Yn|%b+ko)$)Z~NvJbYYlt#mUqR6zf-?{{JNA&3!t1h%OnKJuKa@!xS7x06vkSF~O*zAE@Tf#o$u6{iD-J0QfpOt%ARLpi zYrmy8k3R1x4*elqeX!&FenIObI|coZUc%$b20Np|6B@Eq;)Rywc5%F=qPJvpFe(>_ z1)<3DXDk`cUM6xGZ9kW!kJ z?Bx#P<0w4F`cXtWUI-)TUv9O2s?k_k2_$Z6sI>&J1tjly=4zn zix}fq{t%3_#CYwzDmoVcn?GmB287r7x{oN|7Gdptskj#epYa{@gm1j9({T4p)p9SH z8gKJyEGW}kFqx>^x8cuzGf6o5bl-%8(93v~l=R){-J|vO7t3nq%*L5QhA6VDPcDCJ zxNiCzLYbm6-jBj9agd-)iX;+$1lGui4o8USQvUv{nwNWN0+x^(O)awGux(LRlSD1N zamjp``dP3p0a-V|aMaW$q7|bA5Wo^tbrO-hI&$`J z_RqB0GsA6>kO1#zFq_IVx09tAjM1;bO9gER;8bkVmbZqmLLa9a>u;hD_22}=Gv}_k zuO!h7?CSENF(wJP;tfy~qh(NESwhm5*#boD#4tI42?E-?)L68o<_mziY_i&6wB$Ov zM7rF{j6Z%rrH*9<&VLCZnZ}=}F*dfNlsi6!*-d3KINXL;Afr?Jsa3ehY*@_P|vUy?TgNVYV+$?MtmX5aBPKI~mZK%JH&sZJ+c z42ii6@p!;4-bHQ0cOSnUXJgGE_@%Xi(hX6BC0Ytje_-xb1zCErzs2Y6VzPxu7U9yP z)Tc?m2J6eCdY_bPo)r->^&;g}OnLY{_Or=gM;e!`n|_D9!mjvN<)Ujc3Nfgt@N=sV z8s|a2jUgPcg2robWXNU3z}?N!wY;3!@LxdpZI8-LYSDuadn50d*-iv|H27yNWDcZl z2SUxZIwvo^LYQ__K8B8uDDaD!83a7a*qCqjb4GBU{R|pCl+rIt@v8p$q+v%rL?1Z} zvye}tBfXpl)vha4^DW!A_XEkR{QSFZJHcV2Z__FdToG(d*3E+lQ_!5nhhA@MC`|_8 z{KwQ5W4VEW!5`XJbw;wny}ARMQHl8V5!8zkDL)(ls$7L*9`2=GYSvUtzBFsK6H*b% zLM~et$oq9KQ$!A_fyLR|k6T4=RYMr$|kPP6Ugia!MT!yqqQ(X3kUO~sXP z|Frn4LXuN_a6&Kc#MCOPX~mWtm_G-Wag?;~o4y-qXA|FlTP%+-pXO^sM9xvtYrgxHU);1?hf$r%&LR!R2k zm!Y19&>5|)@OZLguWsYz9YQi>MO}B{k7bPh{`36U(YMw1JFRp+0ofT;NL3XStTVZ{aoEyr?8e^_&;8maEs z0b@(rDNj~sZC<~SSj5`ka9`Lsb|@J@XbDoqTa)?oV0uui#7x%`7yy~H&+L!qmJ#v` z7x>cOXpwZ29Z^RJyL>QKe8ghpNWpgVuVO;J+mYxExo>u~L6TW;A6Du@Kr0K)`Xbvj9eiG%+D` zOIf?cPU_pU#31>TJnooAYL1EbP|toO9~|@iZ+Ws8Op9P*qd5AeNnu;lnM*?Lt0@S7 z5h2UJDSlXZQ;j+OD{x%BtW@+fRj^*@Py1!Ln+`>p=~i;6x**vVks3bt>k-tST+Z;? zE+rF!WRJmUo}gv6ab3_lHEZYu{RQ_Ng?>uR{MwGp!2>aGU1?-$GvpYbtyxG5QE#LU zWxz&W41eQS2v4rgbksce+Atk?YmXy2O!V#>Xx+-#H&JOxa|NIT2SGkla>P+A9xlmB zbzneIm7bg_UJ*mPr?Nmy_kPh1{~e@|S?@e7X@V4q9-J-NJ*`}N;n&ek>a@R<&i?-D zQwA}hrTO^(qFoLCP}AX#C%rfxDIoMR8eVUKG6P*Z@qVp58c>3^L%&@_66)`pp?~t)C8Yy&i8Z;FicC8YDji zr8K_xo;tGARTZdIwLX&ipB1z+S)OKio$>(H8Z&4*>Stbfg^9UU&K1>>x}J-gY+-h! zrvtY|$AM_v>Dw?%2@|q3Bowt!bp1Lhh(D6j>|tKEAHYs~mCyYjh=Ot3ysu2<_28x_ zg8D#G+ADp0qjKzIzi4O<6IbS@T0HlUKOI1Mnimv;iR=+ygz(+XMS~7B=#-ICo!YCf^yR-+?{ZX*uDd*O0Patez}sdERxdkI&+(Dqak zWel-9>+^-!k}zRx;-}nXHman|KY{f=M|SN4B^I#PzI_yzWmv`lp@A%L8{>E7L8%Qp zGkrf}5BH1mCZW-lt~-tr=YnxnQmRF)&ecvB3`5*v!{FN_U5xIJE2DIF*Dx>Ih~F2t z2tLP82~#p6@0pl#UE~IaapJa3B8Q~|IJcDn!<1;IDNHn#_x2YeCV!@VG$0y=?9}xy z9%cK(mY;XNuJVPA*^vD0SwNzrKj*oaWy@u7&dxD4_4oJpRH%Rjb=$en#3 zmLe`aJoxnoL0z30tNE)^(cvi2oYgbZkoyfMqGEY*qlO;S<#Z4j_WUE^+IqO&1MI34 zdwPIM!Di>0_FO!&y#XC9|G8U$2$fC?k6x5MHSdQ{;8)9;HA<*ksz#knP}C}{LMgujwWh2M^n z^hc0-oTOZ(&gZ2C)i)%I{bEto136f|O)Rqf1)BVIg5xZVG zYU)AaoL%F4pPWFu&dkLgB+rSkH&*%O&-j3P11 z`1Oj9r^`F!fu|8}MfqN*|&@H6(dFmtJ`~M9J5GtAJur1~kzT;pX%$lRJ zQj7EHsPwJ-F4^PSGK6*2PjZ>aVf7=XoH8(tC+Fhn)x`R5Z@`0Ocsm$7qKH*9GrC8{ zyYeS|iog@#y@$<_HK$?|5%(2ccE|Y_su=7h3fP>;-fus-AF|h)>_I7)v4q=Mq{HOB zbI4&T>&9L9^}{7S z1Wi=X5D(`~BB=5F8iP;klEzW;pLUr)&q0 z(zHp@4WE~Q+~et40j~ngVnETM=7X+TU;rnRq`yo~tB+U?Ued`coHPixRgHS2@BVNaC2WRJqMSXcTEa zxL2LrhG9XUKk(mS;Pz@U;x+>RA4dvKgCJ3)-tG6unL$8WPa(l)TExRh1tVDQ@){4E zDz6OqctJ6Udz`2Pyv$E(l5F;QRY>Q=e4-s!i-k7!T1mKob2wrBt5oJFV6jQ?{Id`i zMiEW^gG=doLZ+uL?A!6i(>fM60STE|bi|0e-HI6rx3}q{PIP}b|K?NTc(P;|t{C-Y zirR5t91FFe@M_ZhCd%(hO1}&(p+aT51PgV~by!Zo7@_CG^sshplW-6HkT!=#5ox?s z6+1h@(6%C$SSG-{(O(!oZ>%91Zpj`WmY+Do53jy{SM77o{()9i3hJJ zavt?c^^f-647P~ErB;<@-{axJ5KEW_kQ?uDM?C@AX>J`xyb@SVqF6H}3mPyZ=C4 zXM7}0NGeuQ=0Vr{;RaUbGFzBTccAJY|9{A|FxIGms^7hlSYuLc5Nes|Ns<1KteT^0QAipMHPj;+h&A zjkjmz?+GO&vM_&~D*Bwfv<$^tOH7K4j?n%xW#3uvdaY$R>w*192=!>6$hpK_=}bxB zYy?*7G7^1RMDj#!Wo1Z5>PUy^%%2j6XyT;rGBK9OHe^#GW5lqIKi=aXWB0fu4hG_s+UW{U_b&fC)C%iOtBgbA5Cd48}Fc4yk8hbBN z5w6|l3SMF|Yv5_M99AIl+mfHawHsVh^7|U5KFE<9;v@ra2nsHp0A>=82ie)0yF)$? zNHTA&96xMCuOA5CXj4+s6S$3yWv0ujf3$dI0zG3iEFG<0uDsVE4&kQabfsrzB5M?! zi-BP2UZvRR0O8z>f{?E^HInPN{)gs%Out=qiG?sP#ZPiqf>BO4pQDWFEMgl1h<9ZrCTm%mY{-(EWjjL0Z!E8_S)yDh`7?7Sg`50l2|uvg5`HKobhoFsN8EQ6BV-f@@GH%t1{f2( z8$6Gy7V4^(NlQv`1EURJ9|1Dg^`M^q|DzzRZmfv`t$Np$=rN3NevDjv(9a?p4Wb&! z*BzPu%CD=4nSc6C0UK7i;9!Dw`{{UO?#z_Jy3;$NX&_r9F0W<>wQmZTJv`j4rNaQvE@(XD+|lEH(4a94Wf7Pvve)PC=oV% z=Z^mrn=y)-d zEPt$Tq@jIkT^@3K>Vdx~N=^`Ty}i)646Sfr&lS@+(}0elOVOks!~`Qv=v>s|I%wh4`mgK(i{H+HNN1e}N4N^}k!nMOZ=Cx7$UE`i(aW}x9RESgDMu{xUej^*d+a5hrrg4~tBw@rLfPuXk zzY*sjBIuyZk| z3+mb05On*|@M{Igz^K+LIAxhOd`4K&9*J1k4+IFCdVU?3?LnnUI?$S=-n6xEoA_)4 z);ua3LXNl0o6)uX2{j~`jJmN<*KdxBDsHm+jaSyyGloSg2y{Pc!ofjC#MB>8pI03cAe35;4Htdjm~9oj0&?&RFb4 zV9CO($tH0Q+b)q75_0@o(a_P>5rYd{0f|Z?^eBPQ_4m@EQNQarfBUN39T$Ikc&&}R z#b?qg{W0D=LwjRxOG$2*bM3bJbItQVwc*=sWsryDMeG(-BT8ZJ5rQ>{Y`bgIa}Rv( zYr|4wU-S!e#5Xii4AKm)dZ>wcP&z}p@-T{n?YbUAozZ+b6I2orzhmg#6f15nEgn$a zs(UD&?!^7Q2kzG7UQ9>`$h444Bo;l(FbA#7n6qNK7qv1?bT|=wAWiM38-%pQ@p_)- z$_!;RUp-d4h)bKvvhI`g zVO@YLS}o7g-kA=l_);1D6tGTkElj3STyk1vpT#oe%VD z{^Q20^1wECv0m@_MqqNC!?yi23qN&jJ{*hoWqgJAj~NK5IhXT;1!7=GzgCyzvH63< z=17bgT{1tz3j(?jZqU8(JwtW}TyAORusw)i;<#XK9tq{|u9Lo8GWCc)m#tmiKHl33&^eqc8AO z{O-jl7WIlV-cU?4BBso+e$#A}89}p?iWJos=Q!}4K6lGBy1SB^ud!v<(Xh-J2~K9S zCKx~v(bZagCxB4}sLq)HkJWwBu>A+lv{6-NBIc6(=jQtdJtlgHS;lo>5$A>lVE@*}f%iZc@nIkH@S z@zhXUl&c&b8q-55*)E%}4n-XUb&a5>463NpdDW2+dWc3x-1FDp`j-o`6&mk0=?+U< zs!?1f`#Lvim#lsZiDk$N)9IF<6r~L_ucz*c&|p|5)er$VBl9YUarsgagnc3Y*v~Al zW$d8XghQofklKYN9uahlqMef$Js?xXWtH9xXnt@VbEDyyThxhQI%1SxdWt!=rS-QN zHZV|;o?w>uwCUx+yD#6*oOLb;Fcdu2&~@v$G>1cR?P^C`_8m4nr)A1HD!)-mpsb6n zDbgqmu$7s_dd!}G^2ITEK?rD{d4!wrueC^G;(tb;+WhundJG&eR7r^-`1Qil_A*d` z;@2q-W@PJYan5?4>zD42hIAFL#;z?0>c2q*Kq=zyV+0WV*{ZABjoV4W868G9>EOKfqIW^#a_(@y;Jd^l zQh_$2Ykq;vtK0qsnvoDRZIOsxf)}UoLFc$e=NqlCX`>O<}d=*hQ4WXf(;7$Y!T_Ip&%jqhb-4I}T{rTSIR> zHUrEXE?tOGj7t~0eS}~~SaUw+1F5`iyyzp!M3)$3F6y6~k+_b$f>6!qoRn_&Rk?lt zO}Uxc0YLt7^4!jw5^p*ID8N7h6Y%pO=t`Lv^9@O1@mrMVzq*rfRtH5VwB}wT=Oin+ znY*65bfb$v+r~jjcpk6V%a9Nu;h%do6f zPy@$s0>u!;Ob=u8aK!a#E4U?RVVEZpM@cUGz6xVK!R(4;a!j`X8UYw=iexp)mHs!hn(+d2 zsojSqHG_?J$YAAqWv6O+sGiG{T#M+vDTsunULWg{-J*VX5_{-PKtGdu=-~(JhzHHv zwPBC|4AObOPMoekEkj+VrPHke9w{!t3gi>v6+j5A0{kB zwGeoQ(k-fy$|Sp_zO4O#>4a5#4jRp#wkSn<0(N*|H_p*7W#RtA=8ukLkAqVM= zLqC1nkQ8{*3n2|v#KU)^ky97)PL`9woDQjN>9!`D2Kt_uRcY|y|Ds*Z@%D`kCa{nW zoO;}+AEQdn4-ajRZXWP(i*1v=f9~_N_|J%R&hN7>RixQwQ?=Z9w83HGW^*w!LJ_>_ zgwdt!bm{Zsa^9hFt*i!dI?knYk6uxBzB_)v!CU%pd=XMf5#9b=FNJW6sR{0aQogTM7-G5SF6^E5>JubwWk9XEx!T_sn_X29nLF>V&egM!2PL{w zzVNe-)K^9V4GCfSQIus>qpMo)$g`Tg#EgwT=Li zC2EhPw~{wpB#+49h+6w7%5g8;V9BU~Fo=Rrao($gq?-Y2O7Kwj zeay}156!6=;`=}{86v61{I$9uY8Qda6r78 zKAuxFwA62^vCd!%U@nOCRxTc<@ip+?2z9T|AhN0iBhoMd|GdZx%=wjKh6#ejYgTp; zytrW0kU)K!b+HUKwu{RXaYW#YDTkOb1fcI4wd?Maa$zqQIn$oiAh4=|Rn#6D0xu0( z#E9*H>s>t%Z0|n(@B4UVybfklvR)f3aLKx>BJkh}-diRRO|`~-2WK!4`&eb)8U^8C z!-X`sxzrO&6V+JFtKqgnyw=lriKu&3G#B9#j_^C8tR6L)qQMEw|O#uAIGg-aaAn&r9m7MnmU5y%w_`^X_y| zHGZPhv<>gp(MaZW(HR74Xh7*d;_ew{K+)6L$hIuXBqd>;I@HPd;)*)PkJS*rYpvoa z=YPzUlFZ+>W$k+<@vhVj#MHRu&Te&Znw`Fr2hk4oDWa%a)JM_LAAEPCA9}v(E3Q}C z8a(MX92$C6Kz|e`j{BgTApf%Pvy@@uILMo!ru`MG20|8@_ncEA7}Q;cH>E%A`Zm?w~LGXW6|xw|?oANj)6gsx|*P12_o zlpjuG#H=csDMb?^4wX1<7Z4HJygBp<=n8{MWL4$Va+e#Yw-F1RQj~m^5(NDWyb788 z#ylQxOH4#x;ee61fL3bjL$2u9fO~xt0zvYv_y0#1N6|1D^~CLDW)`(f>A&a2)}hir zy=1LP#qKPik+`qe6>fv$IM^JtanRW_o2L`!2>-~`Rbtm1y%snfKO0U1(LIrU-M2gB z>=h3Bh#T8x{>2iu>XoJ*x4S8qNip7F5rKTbqc0eJs1M|U3juSP)|~ZJc+}<>8n_=Z_8=m7$mH4~f+nc&XP{xdTYw{Qa2%n0q|++DS>Cty#R)G8@7E_kj1x51}&UnI6vz zL$o7+f!XD?6>Wh+bv@ohKaeKm%l*uB2?ncKM+``%RCDo=w^uz)r6`zO$|f;T&wJ7FgS^*5jIqb=t?o6~~{z27{jOtP41@+XCE z?q5@=LaPu({dci47s|C}Q&0LE!U?(YX}o)nnZk3-fEok+5~0qxB_kr`x3Yqb5|DwH z+axM95O1-+IaP$;ih_6(6X){ya$#SK(Y!Wa*+q`Xz>vD?Qb$3Z=jh@@9nX@qoO@c~ z*@2aozU-oXt#%Hjr3JY+F-9rMooOt{qIQ+Cn3-BQNQc7A9%k*X-P#)DgR2@Waw%n-BU9%u2>c*4&vNh;BnTsXpbk23Wej2GCp1`T_^rWP83|iY30ALVx zEFKhY$l#XbP?i@F&LyMSEY5cv<|=v?ar~D8Ry64-+gY>d8or^@1r2Y>4{hd(sTq1_ z@9jI_0g^(dednXWV(1*R?9m8NZccj{%mJ~lcH#iRhPr~)5#9Zi-D6-X9#y+f6Z}3y zBFTvamcL2r#9y))%i-_;+`q%5OR@zMPb;xzt^Uh2iYk+7 zAS?d<*iO(YtNDL~kEwRnEqD&RHVz7Dc8GpJ%J9k*_vTM&=m{kz`Y)9aF84?IX=aRZ#tvynGyux34z$`97#EG1B1+FM)FNI1-M6vi3ZzcD1lF| zT$U_~CZzIhLC@OzE@X9B{)mY*t{gm$&pL`Ru=zzpS%J{ZD>>TsA~L1oCK~$Oybe~j zI1%>cd8=z~6$j|u;)Z)>nMo&!%^!KP?BRQac9zAu16h?o^G?Lm>)WQd<9}Xhec)Ws zH__1PRS|__@ZBaGkqB@rOyUVk*C+oS@T>pYZol1^yl*$7ew7cM>VfKLRGLe|E;Ci2Xh5SEE`_zm?GN?Qt=O@P$sdv)v1|`Y@anMY zI}b@k%rc0xV*%EZ2r$3TY<{a7uZ>liOKU~6#96cx#6yW6Y+IKU%eKhCqg;V3m%m8X zM~^>k`HKn{!9pjt%uH*-F;#xaUiUQet_$COXpEtz_yxz5zvX?{FtNqkTT$=s`<}N~ zz6{`2k+QakUgAl zvwKFII+?Y5#EeRAnTN7_udN#tO^->%M|eKpY$K)};bPOnK`Nh(?Y?)%u_IS5;{K7n z#tz4mk4%qIlNjf|t#eP;=RAC{FlSeL>0Wrg8(!z@+;ZL|Cz&bd%$M{hbzvr9;Th)x zhx-EMYQB#kgnMV2xzj&md<@vkzgaf>IV`zjC61fW<_6K1bPqP@X!6M0-c%g%+bO2S zd^Zs`Zd9`QwY_CJa~29g(31GRxcMVHZpXRf9QQzrsj$SM1rdcm@(k8;Eq~O=tztST zTO+DX_LHr)xRPv^E(+^2>WIWvYAsF^2j^oMR=1%9wB~I}s`Qp3UQGUqUdR(ZAjH?f zgW*0kwur1Z(K#$^DdQ^pp-BA}grx!H?z;SBaR&3ahvz^#V=~=K6)&p+3hr$>V<%z+ zAlt=AwT(p{*kvI5tvgAM5D0u{Ez|m%z5uBfF6%d%>PUK471kEEGS-0k0Vpib4F_6T zx_yHV-mgw;PYxp)Ac7V|f;7Klp?D3S^b>E!;j6-|ShC?JXe-~M8=4adYWH|o?xDKE z(Z%+T%%D7`s$kX2#rC=59H#`Z=TD^>BdUt#?REh~sOc9hS<^Lc!Z9_1Hvpn`5h?b%Ieo+9_+iaFlSWxL=p+TW>v+ZXTiC1~u=Cd%J zf#y5-c@5b=rKGFnffudt1_Qx@)rgy_JU{fTHoeE5do66~?3W{+8yzD1rHlJt&c*-y zv$H^orRj!mIq{wW3KuTJdcN~*_VJ&GZo;9GLlYPiXthS3u@ zpkX$5oD(aO;JNn3_A@f-RD@MIXO~jxfQ1TI>pDaXZ)s{h0LcPl`!tq7pFtcO>ReoP zO+6){rkq_YM?;2si|I}Jb1`$;+*+IOMLsr}Btp8upy_5N8oCDdRrGkAwB+nB(A`sf zNxbr5S8gYD*7abPx~9Mz>z36HF$IK=UXB`E?REMaqfd8NWJR0uKrOf?9mE ztXv5hy*8#;OYean&EOo7{1q%S+M!f4fa5Pxp+6o9YkN%F4UAb$h;3FO!P^JJpEd#4 zyXkoU#Qft&EGE@Ck|vjI&fFD5j|6>x)Cg_&j%OecZU1{%48_uXlMF*dhLNeBpWJPJ z6;g)W*jfg>g`5is;|aK|Zkt|&(p7nbBu|Cjw(h!j;(Kpt&w*KLUbWpM9CXTO1#fNV z3Ks9Egiqx~t%}9J*Uo{7%@IJLsIFIA7zmMPRmBM+??q)#lK+F4M`d zAk!Mvfc^se;1bw|u^q0sDPX8t4weukc9FIFm@ zn$UzUX?}a--@jgk93(BfnV1j<#Ck(hM$@v=%z=KRwQqk&-hEJgQx}?s=ae6Y z9lOa|0}=vc(@15#Hm^{PC8iir~IK_X0rT~o|ar9-cxaP7HgsM5cO6lWSwA59nm+lytDpF=4P*EOr$D9WRM5|8%n-yF!Sq(6s4LFlEZ zWM?|gH5rpOxqTJ|_;GT*^6ajIw$vOH7i`anfCv6jUgWLi5i&{tfl{&U4FALeZ4as- zR4!5HATL&XgH@CDx{E_Fj?!hk)F^ESHuD`Wj{~c2BT?h^=XF` zeyZ;Qm^dkngu}oo=Y2V&R}g19(lmL9#t*VL`(?j|a?tqumQ%zBy>U1X1&O3umAyl+ z_c>Jj$}zs%rR#anb$QPFvMGr-Gamf7Bc3XQvABeL5|!YruJwM?M!Gc%sLsk7PD@l& ziT7N=w-#+?EDF>|BD{U2!$xWBgFj!NSjcOgvnY46z3umQ!O$h}sbm;K~6n=1f z@Q2laGZHW~d+{^GK@%q$rVt7yh{s=mLZ4KY!RQ9mE7J?vv-sQ3iw5`62mYLfW;@Y4 zRV3MDR!RYTm<;hERZ7{&5YsJ3_cjEs(vr-FLg~|}vh%W$@#)uRdk|&CC>X#MtO-8V zxLUD*Vs>PNFc@B?yLLH+dcsIT5{b_sX8VuFOs|=%5q)dVA%Ir-$F4fV?sPU{S!lR+ zrPI$>lY=)bV`<$HF&@NnmYTKfCiMF}z|j<^uoU7lgCsz7fb47v4eZHRrS+@+47$^4 zYXTV+M#)~O>>6Jj;OqbUG7WC;x_0=&f&^pPf>~z9HC?7lnegua{GSWSwQCXL!P&NE zWa65N=C1NY0`my+P(zc=>`cNpjZ8ebJu;@cCmFpC^baKJngH~VwmF;WN92(2skJvd zon09`s+Gbh3lAQILssO3sY^Q?zxjJA(G4@8VT+17=YFfg;dMZ?kPxlP()qY9p5BQs z7frXHuHdxf2ebapp?_2>J{ar^8x?eI`uW1Bt!0o~)Pt|enERj&kNOQtZtjcNla{aA z?lrM2+90qo(!#eJcg+pmZLqTwa!E)2fRtcJsSejZiI_)i!`B{9zU$L_t^XFbiy zi(3wB2pnOu-bakWs~T6cayDH6K|sF0%N}RQDyOAx-Ho^)yq8f1zS#)NVLJ;7;LW}g z=?C)3B!|+kWN?iEOvd^N`l5rlmaurBfP8QKRRmZ_`~EChy*A=dXsUylT1G@4EKfw} zvZA^!yqJ^NqAyT0mgG{Nm6~1WkGy+7GPpz>U$CvV#q-BQLKKNBTF8t7%Uf7rC{BFpn=<@sqs~!}wv|=EL%QU%^RVn^Y>aT&n4F)!37NxNp*)!3_M!Y93Dx z2RiMATS^d6BKn)G7{`fYwIW#$_!`ie*nMb9(06P!iPBtJ1mI z1GY^mh6X{S@h$8X$82TGO_ScouZi6bCqvA;RZ<0EU6zx*N&vFt=DK%D7|HTJ*qVsV zm!*760V&!N3UJ5jmru%*$iRGk9m&(h7*aeGE5E!aao^ANbxvx;MB z@!PxT^%ra;%0y7;ND_*CGgRT06hHkhw(Roq2r5wN zoV6g$1mc?05Y&$ge?tx=jg7-uxiMO~?@{bE!b{?;J;A{LAUP%pOrKh3z;*8L(;^p; z#1klRsJgAa&SzlPLvxJgY_OYOH(H?0T2MPj?@4939GM?;l4gV{Z)<@#7O1w7eU3ZQ z5?V2I8008yZg12HuB|&`nr9lB*my5mnZZeHMiu|9-6}7c9$GdEo(qO+1}0yu=`pm|6ZfuD#aXi~8lS;hmG=J{Cx|Y$L%=#) z1HWqq!9}i?A^RT!>b#Mx^#)PEZD9Zp1Pwjz%^Joav_8pnZK$eFu#30IiN)vTsuA0u z#Y@{k;cX10()uCYAWcE1zDGCztr=^}8V-AAcwT;*g(=M)gkYzo z{w{Z`V6CIprM`TRAjeO(xD~RrU%9F`J=J>ZU}%c_{a|WN5^PQ-;XK)yVEQ>3xDCRh zH`h`LgdzwwuHp2rPLA6NypC|(YC0U%s~GOAl9SPU%L{@eVgi}%(&J{^#(CAr)W^2p zW$aN&f(BG)RGn}V^e9``jH9xqLKqk6_|Nis=5O_u^RPUgWIr8|NP2HGn7gMfNKJZ? z24WFbAWD$7_f~!YJyXNVHS?C5n`$i4Rb;Jf@0TD$b{iTio;hHBEuOK!@761=X>R9r z6vUR;<~t>u1yYRB{3V@S`>-(VZLPxH@5R76Z*e2bgu;A5aJ(8Z!UwKldcziInVY;d zjU}{r8XKJtg_PCJlx`B*GR5uVq(^y0U`CO5K%%?uo6tIY0wW|1?hBECcP_y~=Q>?+ zC;@NkqUmo0pnwGSorZbu9pwSTJ+lW>Ejx7@K8VXcB|QXy8j&+u&B1T zl_k$^9~XE%`ZqM@Z^nfMVk5@s9(&o%cNyEOvg2;Oyg6%jv1Z!V*j$0}Pk^W11-`&+ zj=n~bP#3HfMPE4nuqPc53o|D&KC{T&dqEV6m z^}JRq1G7imZ4%LVL(*{UF0#W^{UabDFesIDH)fva;jhN-*IhEU5I0f1-E2yPqp>mZ zq-tF*5!3xZcI8Wz(f#t0yTK^pzL#IW^K?S79wtd0CER28tW=H~KNbhz78FfONtwx_ zUv;L(oHXSdui$<+PC;pkXybX)yO>Eb>}$#Ot&_g2XnXY!Ss`xrSsK2)P+Yc?j(27= znqMMRU?EM}@2r=2W~Qf1dtOx*iJjSn zVATCET!|dnaERmOt5W#dE;C2|)eH=prLI-`JJC!Xi78H6ALk5uHF$aSoKFVUrQNiX zbzFZ7zkej?UZec05zmc@nj9$&Qv=b46{4?~3$ap8^S8#CGbyHNX8tGL<0id5K4rA8v#B^YL2$+n7ETpxB(x0SD@J zJh`nb3)1=o?E$t|K$`$>+Wfah7ge9UG7lvl;+J}jaX11OR_7)B<|y+JM1J^%<@FacF%M?HBTO*aXJ&uCE}1`HDQQ$98E7Ua9C-)f=ah-`NSTKdengiSoK5iJFp9hLQFDfc2g$V;GQ$gjxn9aLD+EO1 z@~W8W(dyC9|Mp3~po}WaiBJz1lPL$6)f=XZ?X@O#!oH`a^MLH~v!Az|dViR_bET~av&8Tq$`{@6IL zt#rlMcv%`JGhtOi0eY|F66ZUEnEH}+^3F=MV^}^czomM{{7u$m05N(+Qfnr~Sok+Z zdcW+}A6G|h*N&{974G0zvZt%y;}#M%yl!7`7h!YEJl;0&Kv{)LPFXp|IfMOY79YE~ z(QXtG{2@SkpCen|aD4m;+r7@&5H=PR5#yZ#+b19$ETCO%w(Gs6*?ZGReP|OvS2;C= z`46Phg^KZ7wWzT67+!^5GrAmmygO=UzVl}WLP}D-LJlYt#X%*_KP9&oM>i?!B)3Gu zg(}+`=wf;DyT8 zLe5zSK@gDY=>nC{kFS>VyE&Q5pf!kl*%H7bq4B>&72_hevmFzmMc1<+BsfS3(Y|S*~|?H6PJ9`p^-h!waaIUoa8=Bi7(L;8i9=ogmu6#mx}u#qmTXmYc~Jf z-?Gjz;NrF-dgHc2H)uY51HTS99)()thgu%{(=K!0p4O%0AEv`^V?MlFU79(Ad?v=Fv1APiyZGx?xq;kg+&rg6 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�@{A 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 b00Gzd34oAT0OaO8vBYQl0ssI200dcDk#K+6 literal 162872 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

    GjXH0q{e4b>Q&It2l_nw8| z8H6+KWHK3cR$1(T;y6_QUM>KjL9Ok~$vT(}uTvts>RFFAnH|PCUI$a)m@bu^0=Daf z+O^MmK5Rjht?MoUx8H!eVRb~_+QGiB_1uX;3rwji>WPO8Hm6K@8+D>?&5O}8=ZOs`UQYkExDrSC;5q-g^^m>u zD-l_`-v8_9oaPLn)r}13> ztk)%-g7J+Mdx78NS$$Wso`)z*hrrC%@>d$sEl)*kU_es%pgfiy`?bCraHKGkCzD~3 zT<_2%o-akti!jTUXQItd>e_d*V-Hc5kz6j-9p;b_Y>HByUoq9|FRtJDSf_f0Q^}0M z<1R=kgw>ez`<}Uvam#~wIs9(J@VcI3WQn5Fcq5h$k`BX?`WY`<%eVc)nkWUEv#9gQ z%D9+i6P^>RT>+gRmO@wl)V6j}C}7O1Bht~-3{|ou<^rn2(in}n)uFCBihglbd<8;6 zqh$iKzCd?U?Om>H8%Ig7_A7o>FVZUHaAp88K+eDTIznAy)qBK_6h-mkViInP@KFRN zkbwGkks)54PTg>=Vl1tfJa*MA7|k^0{A_j01eNr`RUK^xG0|$-xxOkJpUFMqodbnV zplUl;Dt9Th9u3D$t&m7=RkWxu<<-aUnZ<_^EVpokCMgUC9-UKx{qaR$*9GmHe;4Z z^J{dIn3y>v${rhVLMw|n`cxjsZSO0aE>3<$CWC=y5#fo7FxKJg`eO%*ZMV3rk4d_L zK4bX^k@e@$SSazS`<*q7`G#O?n!@8g-@Mu8Z_0lhfQ))+krvv_Q(0QbL4+^6)_YmH z`{O~jU-uoF>8N^SB?EY5ekL$tu$%+UjzJo=hDo?5aIH%R`^L&Cl+Cpq`QyjfZUO%P zbW|lUY-8Jj`PKJuVw--CSuXT~*9GeNuttr>*%e?lC~Ip)>RE=OU*N-n?V?~-8ikQx z<@i`--7k}P#pFbyc^GKy8t(4iO96m5kMB_@^bUO*q&Xs3^aD%}vpB^SXLHT$+FboJOZcZg7S#25i{TU3xWm~i)y z9n!gRoJ2FLA{3-KA%1PI&zlT4OoioA{WHiKz;SF`ToHT4(U`RvO)MUCBzsVd z2a{1hIF?RpVIZ?MI}jJqcDTzCx7fF-ce9TCEV;{EM#*; zafEsoM5d?Wkb48W#`funPE;I$ZNsncID>$Ll1tXYA0Hk{Vg38_>_;&bsU#X!2D4r*ZIZfFkRm^+q_Tw*ZywpT zMWMfTPy9crZ|bPca2pZ(_amYso2%?9EvTn8pggL!^EbVhfGM9)Dm5G?$VLE0(h zHQH0bZ$>I!?BTFCJjRXA&?L2-O5<9bK8Vq8E*2O#=tv|HKSCzIHMzU^xO!c@iC zhrc>M047?|S_vWR0mHMvE?F03Q{tfBea$)oZO5e?IB5Fe{Vz%zN&{yxs2cn=2Q30x0M4u+;wukTnGG;oTQ~juGnM#jq z`ja7rr17C*yHA{?d&~aNpn+(S{#sum#xR(*9x z(>8Io+jF@~Sd9AZ0H%N`U2{ce1%9&I6{D7&3MwcZHpsTr?SQeXtrUoWudlI)Re6 zikCh~$s{^Fx$A@DPIKg>;P}$-4xXSuj+BZ(B16&^{2NbyqK!SC=|OUt1Ss_$6Txm@ zi;X0e%*fxgt%NaHI*({u=H+%FETmjA!kCLcyF1QJ%}GjS>?UF3U0A|}AX)L_bD6hx zzG8|h3kXj}@E&2RbUTbioc55g^H>rrY4dmX#!02f9- zW#%B74tBVEU91>?#d}opjlc%whZo3_3<1FgNNZg+O@w0@nu%xgiERunyo^yqdpg#mIBmpqZ$87TJtH;32N2oHP}OE69MBK;#MOto_-+ z;<)0GhwVwU4_=+>$7kO5z4%=6ctFm{y(~m$;6HIg9;64GVxzUPB9>GBC3nYE&0J>& z_(WsO?P@eUWB6lzyV#5kba*j#ZA(`R^+;z+U-{#W*kOC_o%4nqqATn`e;-PO8m2!s zZ9S)OT2t*C5jP$ZXO1JG0?NYo8Z7f!xwqPCT?xHaBYL~d`MvNU2cN=u;%>e3;-Hv1 zvhMH&eF!K#ZPIqz*E;)$p(w+Tiyh!d2H}F`elFvoZ~}}p-aSnvyz&>wQQF1boUwNh-m(b3AZFN8J++N?dp{a(eDgFBfOK) zteIlC+SHDwgzM;ap4$5~dfL+({t1b2N= zyg#07`wRWQMLG{&d+5g~p&ogqt70%#>VJ{do{g|#U2amob(=Ecu-`bb~p}>&)cyn07Wsb zZu{jLPf4V4`c;1PqjmID#t*V>bk<4kZwDtMmJk59&clI#7Qnte zFN6LG&v)^vOq2o1?AQMt^|-;LgH9b9PWJ;N0kw@o@n2vSUJU#u(a8J1!qn$f4FzCt z161Hn7S&T&seCLI&0ICqXl9X9zyXt7Cr$iKAS({@P$l($RkTBCvyV2WlK#{<(n*NZ zuc|n&4K+LwsQJuh>LC;m4fSrbnAJ;f)T^tV1V5jJj<0=t7Z!8T1)skzGHFBeP<~bV zzCpyCu6EPGe?tF6t)jc#hrAQBC$$buU*ez;N8GhUg~dDv2`+*_uC{rlDs!dy5AsIo zl|q9dBSZ)K2df$IAcZQjrFS4V-(h~h;7I`eU)F4X0DmVls3D+i+Ca08+uKgjZRJ50 z;L<$I+Ncn(w)q^H!SnwzdLXIuSO<%1(gnOrDBFGnNd`3H7lwOuI(~oYud~wK$t9En z)f;x9?Njy6iz6rF>z~mLi$|w_;8Hz1U#uWioF0)DFxT_C>b&YXTM`$-{2l=q4ie3< z{yjucI)AFZ&YL^EuiK@W=tYM|>@c_%kjA(BUrc$NArrL(o+7 z70lYSvWXo6#WZM3DcZM@ui7}41=N5#HD`~p;u5Q{Q2l$#&OfkH9&Q#_-<(usqm7sQ z`9=de-g#c(lfcO+#Z$u^6t)ZIuj--6|gXmpkoa;Vp{mz75c7i`%&N~Vq$X2ERJ%@@_;fYGQl zw@+R{0R@x^zFU1%OJa25Z?s5U+Fh*^Znd)6xKOl%tR4(Co~;;yv8fS_fdOe2SO@JA z3XQC1U>kF{p5+~n-)6B_8b=skNb`b8Fm9sylGd{o|M)U25u4H-S-Q+InQW6_6F~7q zjQhhcpa$rJNWp@Z<8`w@$~)kSK$rRf$9Ju3y3A5_p}B-bHVG->@h_94o!aBXInRRB z+*Z)3#yWrm4yoJ~v0-y5-yz8bB1&6r>vnSmx-#N_!W%{L4nw6NL2U-0wo$t4yTky% zyDs=fGpE8*SnXHC&+w4|5wP|JfJioCQRsyqDe?bn~O<$5%=R zd0{Bw6Ee{(@CJ=^CzL*S&i)co2~f!UBGy?Y)E|?}3+RcOjr|}BKc`DG0tyf0mzQ5g zKJQ}%h6jq|R%x3?BGi=o17cra!Wdxn!U@=*bf}PjbFQaU@|4AAGX!A4i$hzwunwM&~24PI~&VW zf@dDuX6`NA$mv<>I*t>-#R4*?R7q(ygll7CUs;lDemmh{n!qQjp}bnA?%}YD?&;mb zCPBu!-x`0Ho`@UKi*q)~QRjFSo~*k;Zxv*tsQYIGHS?bAxoInjQmAH`dOSSC4lSGZ zbi3Z4OIA3a$xcux0-^L)`f4-O~Slr}k%2bjounSYEsZIRR z0|k;jQ6@aN@Cw#vm&5K$Z6OF>rV1B{OuPgn3CRq07wr;zaI9O=;|GBgl$^8--gboO zI6kwNryxH{SA!kFx@JJgIZLs*O#}7FLX)QM8ar6pz|w-G^~bE`Epz>)t=dZRd6^zd z--|@=Q@Ws=D$PoPh8VVglhT(v)#AVSx?z=!&7 z!8Xvy0v3rTblxgBwFZ!WJ-2^;#@2%OXeT-ohI;SjmV`KozHEikIcwe4%Mc#9*xjdl z~v?i2Cuoyvl)B1`BH`=#j}p0=?u7vWcd#InaR7BcK1ILCNhr5`EU52090bne zbo}nM5@UDj@jIvMn;{S`q?bTk#MFf;AbG&;DKdyo^k7 zkP?b7?vd*Ux@LgFxqu~~Kzs7O7li*InL<}1;h0`5c^}%|9}M-N_8vfk!%CJoQ*C11ZWe(t1p{Bi z=4W-*xNo==&+pGKl7)z!p|u z%@G@y$c7fXn{dRn<*3XWIXZ=K`}`MBgfN~tXV_PSZW~JlP8&Iab(m=ersLQ+2t>RCouuXokisJ1!iRzzi~)X$QVMgd(E7h z&YCUp=+5p8YAADSP1lmb*EBXCCHV@>ebdRJn8NSeCRM`giLtw3bTDl_ApumrZ!pj& z;;cGfxI}?5*F#G_MOc9Vh}L+=uP**5Q^oeaiAk!F2d~17Z(?x?u8DKUtr07y^L{Tw zSzwBH4^jcAOZPZjmz`%Q1zB!d_JWnI?z$D?JY_NxFXAA$!wjZ&?Oh?O3Qc;$SwEXQ|h9K z=K?x}FKzR;;-rUIEc-H~s;pu-{KHORtnXWaLlyL#b#G^%0Y{dPtuFeC%eOG!;850; z8n*5$=r6vu`jXV1{^BVcI-}yd(fh&;SZeV2$Q=(eB_o4hY*=3qbBSPN`H9R;$zhk5FuAU87YbVKR4E(T))1O+CryVt z)yld1;Jrp8Cizr1rr;1BKT<^ZakFux#--Q4p+r=>hgph@Qgv5ex#Wex$>2I+HxL{O zub~!}gz$v!slo6E-U%MSQ0M%V!RR9xgC&ByU5)fS3jKQ`LYgUTGr5r*_%==w>M__um)yPQf*HeM?O!>KQt|?St6HzC!i{gPL(I2g z9&M?ja_*ytO5ueO5a~Vl2sb|mytLaspe=%a`;Jq_*Oyy_?!U7Xd0ogZO>S$j+GXOAb}^)xUCM+jGT*=L{p%OWUX5Z;LFDKOcw6Fe&W z9Y-X_y>W`lrzvHy0qq>b|B;NeypjSEBgKPkf$$M~RTaV}5qqpKBOvZ*IQ=`_dO0ln zcHb-vVsXbjIen4g!-_j%m#ey3h7HG`mYtrT&3$oXUT}=6S_!=G)ESCVWFUL7eJyg9 zUQ#_=x5f1%5Rfn&mXX4|#j?08z?90%jIrsqOdc=uv+B^wG;nv zdz^~|qAN4}m3yz>auN1LqCQrf>7hQG8g@M&*Y@41pQuVmoQsVz#k^@Ski*BVj&`?MLV8xdnql3;CIixjY z(QDoAhmM9O%3+;nm9` zqIdC5L-@{^o}H;6Yyt5S0>#zhLI`~_sK!d|%uqu?9OA2_3W-VO1~(bixpqrnWF_ua zcN|Mf?2-_H1U()i1v|?=UXcMD6vp1Y;%i@Jl!>5i@f?9Dg=&gcgnoo=oWJ>CxxeUr z_wA^@?yz#)V@sz%)FZFo6f)?sy?|76vSoL!_a`RFxjRD7>owobB}NNkI|;o{30sGQ zzPo@tqctfb>CxsAW%bNg&}QjjON_q}8P7-ouVOJNmmn#xnAD$BRF9ybJFJ8U1-&ym zFT5&|QcM@c{)7$rB0FG|U{oBI9(lkH&-m~J=hy)Et@mk(Oq;`*7&yA~M~PKuJ3q@k zJG(YoM2{PQI}4Heumcwnh zp3qG^y+2*p-S0M=iK7>D=iN6azHfdpC1=}1e@b{pYZZU}+rJi}u=ItBvz=kM?6!K! z7R7^f`ql>rE{Kuh$c4c9rzRgJ>PhqJ8i5tcI$mG#T2MY-A&!>LLiM_eh7NEI)O@{9 zk&Jcl?2=Q6gAxmVIF(@2e8RcX8qx;u{>;+&WdDhCgvRVBzGRj>^+g(8OB(~Se0GmX zV9w;>a;jSO(kMz%gO#NPVv6Hjy8>x0>xyo|>hEXnY7LzeBcwGMHTCix*y*()7E8lT zbroiJIwA#IHKIcX)b2xt@2bPHi&gq?a^uGcpX0EA`!9t|xF`>OPyrM)yYL5Pll* z6u`M71zAb_k3F|b91~iqmj7c^Y%=} zPp{zD_)NL?)o}Nq0^;9SPh}lvuAOt)bn;I7<@1Hma(Bf=ImCmc^-wal3Xv)M-b8X8qq|x6y8vFoD)7sSaH%xH!~eE3v;Sh z2}~T-B*6qy#s=Z-=&=#VlBni#?jG<9X!`{2?MeQ}9!uq^wzynvDK{(L>IUQ!c_)9- z^;;`)7s7GE+pxqa+Z+cmrf;nyWfL07nf6bthoPvVu^&+~6#|1o6=j&9PiRw>j=Y5h zu!gdOep>+hsIblJ)~`;z<&8mZmMB_lnr4@a;kA%iUmRABkDCH@o316 z3fTh~ZTAO`G|vh$M}t^<`JR5d!i>H#@m{(w-W+G__V{{$*7&yDP&2)>>E&?j73X&0 zIbTKc0Q;sw%fLs2SUNpWq!bw3Fl6}qe%FI}};4*h{i6g0?7~KqlM&WupJV z^V;SOZ`v5*E~-57y*KA%y<>ig%NkpDtSfC{ZhL%If|YJJb>+Op=)-JJJMcsq6EK}H z6q-qpn8%JxiPc+*I^>6^Et!#(6evHj_L6`fsXkn+UBem*#H1Z9B(b)j0-V`4ZabD3 zp(`SYtMv?c?f}m`{mmB|u9*!A=t?64Z#O^2xmGc4{l*oS*Y4a)HTH*V5IOBwz*{=> zvo~q(i(cbNqiBNDO~kevF8<*B-QY+}TT%%;M{)6TX1lau<$N3uoG=(z*Pp=*Qm z9*DC9?8KuOwyXb4${N}^R^>EmR)U0pSJea&2kmJ|K43gYa1ag;!g~>-rxY6WiJ+mU zJ;E)bIo1f)@JmQ%S3JP{#P|A${tPI^^^7jpt%`6BNK8HT8Y&NR+3L}HRa>(3D4rfe z(?cGg&xid06CS-O%Vx*16|rCbP}4@wkYmb?PZ@8SBOFE&f7zaj7)C6~{cBXNlgl0o zy|eS5ZgB$iizLkqxhKpra)FZx-7~mlCGxAKT;%*dW|;k?nv30d?BPO6^5dShqMjls zn{`!bd<`JXiMZt`w*LoL$>j)>ruyxVz1U(REtsckv?!j4SxAb(XYfk~3fT^wJ>1~Z zF)*|z(*m5<3L~O+l7$PaeJ~2pC&s!IpYN$OgM}76I#PG-6!s4a0a~US#8~wmmf!X0 z8o~u>GUKRp z%1q(O^j!Zl4KO_|(@CMriY!dZpAX&aI*QeR;g%x@H|}L-!BZwXG(NX5Fl@8Va}n?? zi!HD95U90vCCZ8{Lj^I_YE(QMm5j2ai?3zvKPtKUqH2qfx>2gl=8YIo72EoLv3JG9 zO-{r=Gq`OeTYZ{|9?VmYS!a%-1)Q^3@EaeAm`?cQdR~K9r^;f1Wx_yD{)%%c!JbTw zrNA>S7)3{o!#vgz_nHWccKcnk75NlHHlMl`tCZgv5pmFfEHqHi50?7Iz=Tt+553w4 zfQLQf&>L}d&}y(tT4`Nwy?dp>$$$n}&{TJh&Ra99JCPgim=LG^q9i1xKkiIf#*-$u zaf(un=JsHx;sbcmh#kx)k6UWYe{(uREf-j$&nqX66=G1?__)nmuJAZf*5I0h^Ga>nG07K8K`V|-p?xD@Lhnv$0eZP zLm~}##c1<;j=jp$)-J||VOLDZme-k>Yg)W=6A)@)>30O76e#W5nBa@l*I;!7*=Zvl zzWTe9+6*wJ;=#}veoU*c3k{_H!7LRMNYLZd@4=VFZK59G z2wRTZ8MI3d8Y;|)eWI%tkty#obuHXm2)`~K!V>8Tx7^ozlu>lN%Q1iiFlDZ%Wck=W z&7M<}eONd&jU#+!SM)W<2jOibClzDzc0g~{rW>q1WbyY6Q;NT!3GQEc^X7 zhS~xB<|5uaVYu4QM&NiM&9cZ4Di}Q?1IVM56l3CJ4^j6k$V%59EtNA~mQXTi` z?9)vOrUPNHr7qEbpPF_S4rA3!0o`~0rEYQWxTn+rZT+P7FDp~i9~zfy@2gm0RRcy? zo)sJ0)*gZ+2tVJZ}qbJ-47v|jx#I8~^2c23cF6u;m!ABT|I{8V%%!Im^OY;Ag=8Nc!t z)nYh~8V4)^i|KT-%J{n>I@2a4CdCzS?<9_%g2_|48TgmwoN|qe+USQV8k{wF4(< zRAZKo;9`&cEVOiKd>59S>ct6s{2sYLir#U;*@tDaZpnl>13$7sD2)T659 z!~KFCOUTzBSM4j9f8dK+ta3?WKJB0Lkqkr_rHyt@^kZDarh*~HRveO?Go&AuCb0`{ zU`J1_&)e&nf6LFXgP0H&NcTJi=Bj}LO4A%&oMl;Vj@nj-msoTYsGRFh^d|bmX?=|1 z@?8B>F3EEjgz|+Jqw2t@eb*{lZ~-pavjxdtl;-xZ_IZXSI5ThJQxMX{I(U6C&)*r7 z&=YpXPiE9ckcZ!l4({b4AFN?-$y+MLcGwSUE z&v9%4_80p|9)_I{Fk!kw`ppeAFOft%pZq;SaFkK)V&GNnWrcbXcChz{&U^ozYW2D_ z-0qln5G6Nw4Tpf>iM*G|-azV4+F0)*rb~l~P?A?E3*CqF^{}!v zv--+7+gRvUC{4yg(@W({x%w=bf*4bN#*K|sV@baua09D3Q!wZkpcU%J>?U}TznyS1 zVcKH8tYqadH?{pds6syS%);>7=bXumrqB`JUDz^42+7x&p*FtHS&n@%EjX#p7jlgi zF{2z&w7*=lDv(~Pe59Xagk-3pD5qP~lyDJbV4H?jkc3XP?{{|~hjy{sSsb7L&etE~ z_=x4!)f=I*&UPWSmUZThFdVPlmY;)e4_TL}LHPs6NF>+-4}h5$gxsLTYpX0rdf@MN zo!&D1bOdjJayzo39+w6`%EDct%bs}xMI25GF-IV!>j`d8p6q%?fKkqWJWH$*Dm`z> zLwZAvXAyo1wNHX#^LqIhcH*S+^TA5XdK~v{5x6Z*<>R^xg~ppBP*O4azQn|4myB`f z;Kwz%E02D_%m%8eBfp(&k|i6yB9+mFL+a0~lS7$&MA-kFZZ(|4Jd)@FRn{KfJY%ZL z`ua@y`1?0&nyFJ`Z8=VD51ef=cj!0nR1+fGs~Io;A72I?FPMWx4#nIPiirM06n+I# z?9R5h(;y9h-!6=ii52Jp)(pm6Jxl*`5CrE#7RX~R zBE8t~AWOm9m_xD2nRJX>h^E^Z`nO#(gdb$kG2P=FJ9_psxHgRVe}30pbhFSD&+KhI zONlZ15GoP$1{aAXFv!^(9@E?oMjU(b2mJ}=>6c(iM(Wu_&Bc9OnJcq0h^OG z%*he8_|b1xdnYcE{GY5))obosAJ7Pk^e%}6w9;_4#=}WmQ%kobnN6tK@GZ-^hkGAQ z09v7gOq4~lnTXiP=C#Co{|iH$ zGnRsOG4 z@6UP#e38*t2Qug4$GhLLX84M9=^|==RGyL-fMk<>Pr58-GUaxiMFa#OY#^B7L%uhu zJ>)=sKR0eV9%yOZ)?`mb7zS1R@+B)L1V8hfo+s=6zp#N!9|X=>x(7uA7)5YdGx~;p zaR8?KN(JrT0s=ei2L#a~X4++lHWKu4$P=%1z_)lo?QCc(1J5)Uj>Xxd7mstG{HbtX z?GkA|V*F=_s4{l?x=sUQvXYsD6)l7CW0T4pRJT&C>jubTe|+!ZCgD3aKg;eq4KYx7 z2NB>Atb0#vp40Bla!j9Aca-1qPEbAZFJ=sVq~2`-jVqTo|0fbAm-UeK*6?$LbMjX7 znZR{z8^k%V|LC$xaF>!^fcI-ckMOmWL?fb92^N5ybSl-~si^D(nERm4Avoihb-gTnI`(#v!GqY}tk`P*Kz+i#@y$?$z$h z>sXif1T0zkO1#E(pCDZzJA4CMW4BQbU|B*+ei^l?du-g^k2@&A?Cp*21C;hJez9!C zT|4rKWX;2oh;C#E986@Pw(|!qbZ8mi<_iP^TXgV0eY*T&wqhUMk5tOF_p}IMcsTzC zTPu*&v-e~LtD|Mpr@}U3fr)zF!wkF~x&UA})}6w%R+Bl9xgmA=EJNJii(lVaRfduI zQOL_LDx@?M&op*O$8igy>kY20bwXrw93+)OBaH@{U)9s`h5j%b*Mx=nwX+%YUk(d( z2?Hv?CoAPl_k2!yo(Ziv>$}HIv3n@-R>*4AO5eISlbLJqPnR57!TjNZr+^uNeqMC6 z{Gk2pvhb_Xc!kvmd&>}z{ICXTCO-j#06gIOfY9rGp+GF;*A4s{xB^f(Hq)WwOr~u- zh@-ogQ9fxnq+9Y{(qPp>Mf*o9m#s+Oulo95rK^fxZre|AwuTM=YZuLXXQ=>_&|pe% zjMXSro@tEYASCtolagFVEZ0qL2kXEqY{!aJ~bf=;4O2Y9cxreSB3|dJ5{FYZcGNlav-${z|`6TaW%0H!^5v;zHZ&+UhaI60)!(DzYj!W@gHM*wJR z*l(Gn-)CE#Rv)REkNN$qU`BO(>CtgndfD6i!4)iPbPAc>4idS zjQ=R$JJ!DLG~Y!Z-e-rzA7)ZDF~mU)tX=GF1^L3QC1l)OXmS4pgz%5y0ady(iFvMH zNrGlyMNr_{Po)hg1pe`j08iM{Lhh-o!Ub`?h29v8+c&a`=!GtrLyVXxr&PdbxXO_e z13RU^*8X^e=f%S)kS%l_NR^cWNMcXZAVXX1kMn;}-bx<|Fh#rc#AujnLC;mce&IMY z3%ALX4-~tZr(AIeyno3F2K$;+11r+l+Y&wamS%N&tg{g8=`;;yXFy*C2WlD zT|)`ebKB<0=?ck=*6=wqfDY+#ylT31Se~xD%rMzn{NjW&gB#46$kT_JvD}CHzIdgD)(q9j}PejXMGza2rL*_ zOojz$W{mK)l$c_ELV|pii{PA}`omB>-+xfcaudO6Vt@SB=q~Aj_m$q2Z|W@K>N!y%cV`{`+89RJ1`Bjm0`EG3+CL-y zY&J8WQT^X4E_m1z>=lERwY95}ushuINEM3t4blUi!Q^OQCQQ{G^n?E#{!7jgzu>Cy zKg&sx-$hhF*BRX)8V-HP?+;}^Z?~Z}8L$xUPuRK_#-^#$f=b?|TNDt1PY?%Z0r1j`;z@sEl%$UAgMh6~5*;?n05H1C$l=kP&8e@}O~g(xU&^R#-)LnDEh6QI5!qE(W>;lJzMyqgqm7=HOhz;(_#|%+GNm3f zR3aMfg#BZK%@re2Ti1%+XHB%QqiU1GDO&cb$P|#AT0%PLfN#@hdI4CX8x!`Q*9{go za*et)7tCI410H>GI8T#5E7lyF{H{~#ZDg70!tUUmt#AMGqx(N%Z@SmR8+_G&x#qL}p$8e$fQ&*5Phd2Spg(%|v zP|Huy@OW;b*Rm<=;RJCSb?0J~rw+k2XKxSzbgd66Nn37>HZI<-UefA4y-_DUxmg;R zo4W)oN{)cTqVAW@GR1iv)KbH5R<^K_C0|&JrBJQaly_JdZ;!$5cWaT)>$SLipWm85K z`gKV5x*!ltJHx~iVzL{lbI@w8>D{x+WI!`E%RB@=nkGro8c1k9w+2(ORk4$qG=-}s zUJK4$&egv!MGxYsA7)JZNKkp8oh;)Um6$zcK+Cm<4uy9_BWk46c+-OQ)n~A9L9d?Y zWFsr7A_G8^_sgJ<^z-RkFKp)XUB%et&+x0^4YMtuN@m>MELU@vF;b-gX!qvO#xVei zX-uq8I8cWOCts^YAHkEzO5Fxbx$@<3v@aZSb^WALX|HBT8509X8daBAHTSEwBe&V% z)#w|4Yk0ckZsZ|gOF^b~4pw2o@tlPKC_0`%)UcUNx8;ds^eStqkDcpBGz7eEpr8WC zv!S%7dlQ+C-R=hoVG%J^5Bt2ZsI%)AGDg=rY6k7Bt}B7v?^h4)3}4PZAAGv8tkiQ| z#vNmDb}@T?U+n2GST28YPy8?ZG;Bh5zY>35(GzZyWC(F`jF=NV$O*-8v3ymEzN0}8 z(rUZNv$!@Ci%v&bW6{xL7^Rt*I2`Ak{Mo5~3;RJXMk;jyODFgR+My=-S5nw;VL;s$ zJ5&b&^6*8R7Xr3I144PuFk*Z}rmwfSI4@Y-`GpPt<%=;&oHU?hGPqH*;(=40Wd(W( zZWkKMkP(ZbnN_2IR27EedhCLZ-hw0DSkc80gU@sB{4}xEmnx~3_QW#%Y$A=LpStE@ zM)m|4wAba#C^Gj_lLGebVRwq@G2YvlZ|xu9bMeYndMlmQhqKdUPo2M95=dzzRfllC z>^S%O|D){5ol;pfiz&+wvUU7g1JRk7AP`ZBt$i0iUv?#SCD7XjOE1!ND(a^WsHI5;b>x zTMnI=gYaT2uUX9{KFl@4Qt@+Nb&Is^oCry(d;d6gRtrF(%`L&AT0p3sCx$)C7wZ`` zR->j!u(p-ecXm_ZdVS^5^0Lrb3yaCwwJRgKJcz2y$Wi^aKjj*%Z1Tl;OdxpJ&|Zqa zMsXVLlJD|h#FYT^@rpqZn1+I9Mh+-KM`g^J-g6&Bh|HOb^+lqtqXh}Jc_1^;PFgaq z6h=N{e#PQt$Mi0%+-ReAlG<@=2`OlBm8N7tnC0#RKv|lc;P8qxYCWQ-Jo)y7`O+I9 zRK?cw3f+T$VX3J);ap!xg`5*EBY zu5SBhqRGHMcLM`b5dQ?E>3tlq@Nii3I3pcY1k8-znL~Yu$@7bt@c7dgr1$s5 zf=W{cpIQrIaxNMRU%ToF+1!q0LRDbIC}9!ku+|YBnK*0BDqQOVTgU>nuuzFnj3r6u z|L*)|$fQs8>=M(0-0mcP#-4EV-i5|#@_UAqFDnSL1EscvJ4PLHMut$ccW(Buv^N9q zAal2%`UMl<3_K+fcgX_u@_B;fiF~ha&1?<9E-~Tot_7dM6D5aNzfbtZmXR1kanH2u z5yPC^1(SJkXHQmcrCtbxEgR;_aAy$M;MO=2oTnt)g$spL}!zdDq{b4 z#W*6lCCP~!@^toGQ*3BSK`S5QiwMIjK4k0xIBI({oZTJlk*&81yfylOiY!tySy6XI zTc#9DY@7S}dhE-mA1GH!`qLCGUi#_RrgVKG8b_e&Kx6A+S#t3V1X#)Ef8k4-G>VdE zOe++&A;3pV@qt5D?l$MomGH3~lQE(mltfn}KuD#P21482itf8gPL_S~srQ<9uo_x@ z`)~l)QfDwBy#~)j$s#%poa8v3pD(ilG>hr|_R{s5?8f987=70d0kD|=s@w&YGIl5L zPqD`G9oKtKsFDnQk7OdU_CU_XZ{8}Ev~5%q8@34)M4!Vw<+>RybC9$6yu)v`d>w_{ z$UcGp5}I>bHzSap`KMJDGwu{^U=7o@A5Q2J25COn|9%-ltG&23HdO%YrfjK%W&eLM zr<r8)Z5FCoaoQ~ID@Bs-hJ2Lmo z->HNByqdSs1DOzrg#JDB$ynw3gDiwWd}A93yV4F94Vq2x3q6LvK1&6q?YFDIcVMIG z{*T1$4BwBpxIHLpZ$}UXDP=3`qdbTPdyCt8ENeS`jo<02aFEBKUb*2jeHXXgej@66 z&u%>b2c%LfC905(GI4!XBPGFc5W95v)ZDwWG|Z8VF{H38y89RSZTCPaVngG>7E1@o zi}aQ&sT5jcy1fNqX!+`;rT}~C7~m`QtBrLnt@PRw)NEXSWAQSEtdztVz3|9 zw&I37q+FCZJU2@I6M7K-CuZyDde4PIpJy1GD*nFF*i7@@ID_tqawCO>y_eTbfMo}? z;agBk{&(~mk^w%|t&7xirU5z?>=~BeQ>9IR&(8h1A;ZS-)#a2fx-3DJE1VHmS>UV9 zg>zj&_2Uf~Z(eJ6>qFJCO(R{k;*^m-{1C04BlZHqideZQviqsZpqv5kS=_ZFt?6&Wj^;62whB&z|G5 z%WU6`^4oZ0&Arhasc96H_8PEVwT-g`Xe0`f)YW0Pcj>Xc6%Ez{e9^d0s+MPJoo4)hw{1YS2W z11@7vpU-@02M5FqlXx5%AaP)I#{&9GKOloPKQg3 zI&>nK{#CO+&{Ex-OJh9o6pTg382W7Y`;4^eQTHp%05?F$zk_*@jv*CS1rv$-8SaF+ zaJXv>2#a90kmSPtI2fUC?3;TXR)a@0xYBPbB{^z$G z(s)fUsrfiePA(7(${COi^Ka}r?<_Zm@|K1UQ0_ALNW5s*5SkQdFGy&k${ws#*g1+n zUsO(14gG~scBKgIOGvzvT#QDUaofD8=E`MmU?MIPJtfo13J!5!ms$HELD=sIbgpW>EnYuYLxoa8MS zEeA?Qt{n1vc?z5c4^Jy!T!7LIa^*G?wy|wwkaY^yN>Nk)5X}6b4e_3JB z6==!Gsm&F;;w-ZXD0e+eC|hm#TQkbO_+6~_u0KR!C@*y7GQa1%yBF)!uh(EN{`Q{I z8~X;}gLu=qXKI-B5|6XNn;GJ<$*)6Op9lVSO_BUMFv1E4{Az;zrCP%VHoq&*S0`^$ zb63j|tK!|0>|sP_I*D0Dg>^)N?y)U+`Qg%7vA_~K;Jy(ui!S0;rne-RK5R=`j{ga> z2yrh8G-qgmvmjaa2nP#d%v#LKn7UvvoZ`}qU_0X{?!7`dl)F^J-n~-s1W^OLH|&c@ zt8K>+REtbm4dr-iYCqTaYT%!jTT%`mCl795_M!RY8GNwBZ5>teLh5 zy@8Ydg4Mic>eXA+>qN!Y%k*Qcd(TnZ6$&qN?#>0>?VrXJVKwvGc)2}V*gArTYu4#+ zjJyQN@DqO8Z)JtCrjKfip7Hsc%1w?(loz!=SeKx-D$X$Wkx85SjTK*PVB zt2|he2|1wshIOP#>GD~EXn(Oyl9Kj^G$vlhZ5pl1JvB?zdRGYZycPGH#_y=?;FmZd zoy0Z62Ho7AZ;lhLh!=KQd)Y3~>N4Mz`$_Y%Z45nCCEZh`Pgzli{757XVMCJBnWzoC z8K551yj|Ndv7!ix;?1dL`H!H8V4&{Z*Kz~TF9ElrQYS$$ttd&A$SuY%xQeP1s7S8~ zYLGzX162H&l5nAw*r7qZf;7&ra=NDMzgNxJ`0vz(2trfq-eiNdh$oFq6m(5a9V9=a zeE8Y1Xv0iRt?Pu{X&(DkFS@g>b)9|Qne9G2#1Wt>X1G3BS!+!5kvSo~r-HQ-n`#s# zZ3~~e6z*`VUU}ZwC3s+q+g@v5{Q3_2;luVO_*JW@<7km~<}x%O85{D4%$BrosbNMNT*!$o%+2l~7M^K*y44~4 zffLtt@;c9^z^j!=3QP3S0_f7_@HrHeqW|9(s`6u}QsX8ptJ`Zu2yF=LfvPt7(kZ!% z%U%!Nf2+O99hg3tR-vLr9N<%<65e&0igGJ%42c^POB2ligf5v-r~n$iOp^jAspg;h z{gXo`AIrlbt8#M*3dS{gP$_}-WbDC{!m{ltq?zn-QCzkwJ6f}Bl zb%VMkhh%Q(_npmq4Lvq_jsJwl2xWgnhESRN^zp=DgBTYX7+6e)13|HIWbfYf7k6n}t3>{KusTQgKY)aKMIz ztUbzO;FSx8q%^_B0+MRc}q2V({TF_9iPp&Qa8VFW^9}BO~;580J_=aDc-P^nR_FR*HyINMN z;fSsBWa>&N&PNERfUs}Al(n1fhg(ionZssWGZC&1=v)h6$$_HGFTEg*9jc;6CdGW1 zQ~JjIWNc_64Cd7n%S zB+R1S!ly}fjaLRpouqAoIQHcyu}h5`PepKBWUTn~cZOAT*pQZzu4?FaVcG;8s+u7<@D#HjRjc|AeJ=Ha_|44L%NqS2`2s63ch81j~7O?QL*_Idf zXB>YcbcO@<5Q@g$!+Az+U>~?SN7_#Fjy!rtoJhR=(3FEg0J!UPIa-_$z-mF*mys~^{vyoiBZRn%V_CqjaFy?c zeJ^tT{q=EruC8&$4|WTm-%S0b4AGOpd&O>N8FW=myv^myqyu#IW!}L?mkI}Dh9kgI z9eD~4^z{}0enwZTt0;M<`~>X-%`yM(H1^7n2aaMC3ucfO+ss^Oz43;TTbpxz|Hene zJ_Q>?N1d9b{4~=?Gl6A*cW%Hs56H-E{mTUTvpkj_DkRLE%c(SWm_gWPB4NqR+Q zZfFmt(PP*hNDt(iZT4SOBL}r*p~;!zoT7$A2B%j4^<5V2RajO1>1zu%Vn}7Nr2_n> zUjnXA(5zDZWp0IYXX`8~K+CXN^^O>x%#cQ>9zU$Jqd`C&{5M8H94D$+lWRU~wH!+; z{){eCS?-yF#jU3&7$#fs^Cp@i3WXVen0n^$Lj{>Jm)9EaAvw#605Y*oFb7wl?DYkX z%d_-$jP;%Mi4pVcrJ%e)nDnR!VqA(4CB3}5Xwp+&v-H1!$yw=oR7k~=)VSl%@PGW% zoW|H1=am@{cv(zfO>4XxC4EC5qaV*8(e5hR1FF&5z8TFWU6xJ z0@6$W-9HfG*aY_AQ@xQY?Y}v7%OrGU9jOB`i35p%Wg6vRP!U3pkq6c%WTy>x`weS9v=Eh(k zw_cW!sb`!1A$u?$Kxcc=gg#4JbL1L$B9vWFKRjWeIdKNp&;`%&=$Bb ztoJ@nL5J!)7q!H1(ajk7H|3iF>+i&-qfq z^dsJ}F4QG>f340cSYJ^9>k|<bFI&+-TFc~^70$@s?FjjFGV2hM& zf8zFg=HO~V2MEFP=?K&SY?rSMBUAV_Us=3e?9j;AynMIVEBd&VXoL?uz4nkKYOhl4 z+A+5GHZ0=rLF+R9#|{;OxyHv4DskavPJd^t)I6$Y8Bfjb<(zP3)oI{|$qqfUj9%5i zIbGHyY3^Ott$cY-$3yc2c4M!n{0FeCJ-MNS$*b|=^L5g7p}T8ts_YUBn*c>wBDeqx z(C;+NAjM29Xi8A?sJ;WX1sV*FuAx;AT_Fxw(Z7YMPU|I8?7#rY%|@+?ZdkXIH?DWZ z<gNl!Bj7wAVK67ZAqBrNSvYi#N>fy6W-w65chzG<2E?F14SnKIM(BK z<&YH}Fkw2iu5OZtVit5+@TWsJhs%z=6c*!>2UQdbd#;&dTMFYO%eYYcJiQVn$PdH# z0K_ZiMC&__R+c3#8%)O1&9qd;Dx8OA(UmAbgO}J>>!UKWL6C5j-1QuR=^<{r0Z=(MV>J> zillQ@k@4Ekn~;2KB5+Z~_N@6&CM%*g_>Q74IuX|7#snCml^IWxG)f{caS=B6WXxa# zAf`E9y>;2-t+1PfqI`a%F+%HsSZb9j?@&pRO~(EDwcufl06khjm}aAS0aU>Q&QyUTB;=mTAH5g5HbwF9D9MzLtF;69nRqg5gB3lYq6HN zsQynQp|13zBC5KYN*wAx6vZ@1pEd`T-Af)4`rqs6M5XNT z>3>Ki@y%0!ZEtT){ZrArZ4@W_7Y{6T81W& zrn$N$VF8j_56Wog&c${$^d{yrL$z(fd@43=uaYJFa$1XKXtkpA=u_Fc2Rg~=lF3)T zIKK|5uEPy7q0@xU@rC$r8%QZ!T98oALF|u9Zh(z?FB1uh73}$)LDJ$1N`t39^}an~ zx>5E7;^Byp$L)yZ=NrCzXrAO=bymg;o&dV z=Pik@{7CX>B!qWO_CZHO(y9O;HH!_nrU?d8# zk&)wW2O0OE7FpgAS~0G6Xx?x<$mTRs^3=5A38*a%Da|D1V*-$-}eqoL_md4SNC@RjX42$Z0- z0UbIB6@z`>xzeob?5I__e!FUNXmZ`kZSg-FyHQSw-<(YOo{@E-FlG9MPM4qd}s2kSr*qJ{4$M>9O_TrB;btX z3TH`u<2_g;|0UoeN@J-S9Iu$6F}M8#8y8heO6%y8NLMtO{_Q`am({gc8HjdhpHX9W za}^+(GV*M0fGv5Ri^C3sm_;7+A}X5(1oy^6ygBspB%fdLX9jLO2fTec?-yL>QvnVj zX)&^Q|9CjQCR9$h+KA+m&gB#JSp3ixmjHFg8(?aKjQ!m<=ldfxq7Lyeze{0$4>K?w{m?xkhQ5;hR4kU!~%tdb`$N0>&1kR};2jf`qIc;v$ zP7e4r2fdv*fa==gMLQON_(k^~KCNg|68roYfq+BjnuGZm@`#YudFe(qhhFN{fkC^t z#++K9_g*_$$z0r1@%m?(9zNm#Z|Hj$v9+DzI&n`6lVv13ajy9meeD zUVeRfw2s=&u2hZRVLj55>(wKa>}mUQ{M7^ej3&h@ENrFr+2@Bj7YAHs_9vS0TyqDb+>nU@;7Bu0Im%2w@R<=Pb#$)U1 zH^1sGZ`PBJVVk>vxV?IUEC3WQ{jyc2QUo?mO$S@FOqAXmeT(WA&7Ct$#hR>{nHg~m z&|L~2TfiA+2c9*Qq_e?G^2ti4>M->h@KI&R+nEn$f-Xpgn&(ff4?7o)OH?>Nn=t0# z5v=+n|B2N+3`p;!%-tY{4#QD_!S^qf`D%hB<#EMf?azOojKFqUXT)($*)BcoZK>0; zBQf$mvVa>DDRn$=$?LtZaDvpTHlp~QO^KE|W3#*FMBN`Ur5T20uVL|6AH7|%b+vxB z5pIZdrq-B-;uNpAPpzF_QyRDS)XY$Z zjA5KC28U;%!X8%w$LGYhyz0EVa4lL64rJ7se3XcWM8&IM5FT|hyH%>|FG>;4VgsUyIpX~lrK1M^q-*^_u{o-%U zWC!WFv&T(rB|cNwi3Q@lS*E-G2^FEj$DJy+HJlVyLRGqgeXGt>Y{SIN;)-E|I=i9r zZzTJCj-G8qYCWOrW&BmKeg9q5tRU3ZT3Y#qL{i!0JMY)W^TC``hgW3J4N)h=HV;-f z9a_yhJi_;qBpB;e2H6vWX@>^2DqRe5zyS2Y_@H2c|{>*B@|7xa_ulYg0l0 zGdO@{K^VeH=;uHue3>L`l8hwCQ|(ZmdY<`BF)(a7Bg1u^=~YT z$8FrexHB{WHBc|6eQ`T;K7r+Uxg;n!2Dvw;4o0luFjCS;%izZPN{S~J zRbt}BozK1z^V}(({AuZI>ww*b32uVy{oy%~H`%8?5Xk^So|X9_+>X2!arC5$C6zh2 zVb<{qfZyjZSVrvv=CALP&!U$rwIW8y z$tLp?odgs8G~7_m^lFi1%kBo^gu$L{N&h$cl8@e_P|4c&mqvTr3Whs>AvLz5K-O2! zYv~u>Gau1B9Do_V zwe|PXD1y{P1;XOCP$A1x>$L01Q!Hiks=ekYj!{InrNvZik40|VN?W5~B2q(Hjz34H z;K$nem>~g-GgF5tpw*e$U-==)!$FlPuKy?0_24nL)YgfAs#$T57;2(=`w_`xK)mHj z`rRbMqHpp@THQpDxlJ||%fZR^t=T_Ojt%;yUGXIiaP7^Nc2h;Uu4A>7YI6rFjG z!e^?8a&-eH%W^4=;t_zLG}^-TeC8+zRfDu0ggU4}Gv1DvGgb>Gs#|ylF)OX^H8k?C z2dYqoFXjMl;nxEUK_Bj2oG-}8NJ=RTqy9DRV~QIUNbjp-zh&mxdt5W$u_UU z78zH@prjGv`18800*dpl;6~OJJRhDZsL52Tr9#-YbNvAdXn@tOOX~IOEDXo&o8#RM zgGt_89C)RIe8VW?P8SSU{^j8v(}5WCw!Qp2QaH z-_nTUj|&olT7dENQYo7p*;P4j3T8Dnjxg9oHHHAi-49ES>*~PxZvX^NPV&#_-czL0 zL4?0G_t*M>eW~xPG@A|*6D3mxRRGJMoe>-%N2lWyyz=kXs}9+)GF$Gsfr(g#`Ow^_R_mS_-!57-wpd(sro+gj*_Dq1@$&;24utQ{(>voPPl$s1kh*&2X0 zbBCTX8arY}^(2X(2YqTAem7Rgm=9Eobvt}L1FhGE>FdgcT(IVMyrgPqY=M#~DvW*T z2R?|$;F-=9qEf=!Jp5uLM>-*bM?30ElpX}LJW7#S3O z^FC~3ZNX%q9w&Zd6RppEzC>4FmoI5N+&KnTg!w|XZp`lc3mcr+W_KixKWtjZRiqH$ zF&R5nbr3kax>-~V5P*Q0hax!R&vgihikF;UGfM_kYca-}@)#$yNXq@rG@4Y3ij?Zt z7BruIULWd^!mMr)j-=c;_TYLfk$A4P!E%FxeojPgN@sTau5gqfxo|7QkHcGjmm+2g zVz828ci@OxL-6!M0`Bi(Yf?xhpROj{GD&GD=SUAQd6#hMWX9DWaGF!S+)nJZh4w)g z(9T!{9#n7x6-bmbgsGQK--4G zx&4r>(8PzNjOIm=YJYVpa5Gv_QVus6KL`MLt+JKJ+;2ZvLafG}bpr*7G1`mE`&vDb zME24u7eY$(zRC1eL+kEzHW2_j&CSi_;FAX3D7uS3eHEo_|MPFYk#+J8sFH!@_Kwi* zRgpJmrkU99*g??GWr-U@aU{3dl68(pou7ZgKN)SUzSc)3wV+cl5T?#G^y!w2&jkw? z8GkW|=tc(F#qB6*xQb44wXk84;b&GWRIAI22c9{ z3_=jRUbIhF_Ii<2U`LmVDbsIJNVAGnkwB_wzxdaSO)wbw)lrTfio<3QQl|#R6wsMoyvR0X10eq?gD<-(Q@Na}?p}FhEM!LBfa)TNDFui-qcka4>yytupa~W&fj-ZdKB_kSlSz zZ${t&K7d>$DoQb&vYn&gAG0KLYIh}2Ci=eiG;%?`MxJkNwqwB)-#NA&ig)mX0SP9} zr~JT3vT4jnWOiL3OUF~vrlQ^>U`!y_JStU5&9UBpgt#;=`cIMm_V%t)SP-xN;0N)} zAhQ`JzEisL#il}D956e)N|4ALI1}dcF0+|thHamS)V06De}j44#3h(0&`=rbdLVyXx&}Y~GDW+=8L9 z*sex%EXEcwuw3QaNdwLuKbFpUvejgZFJvrUII&aBWFF^iS)ye z7UJwt8wXV#-jba0575)-G8~=e}}&oSc%{}D|e zk*Xr0^d!s2R4Z;WkZ*20Q&vl5xWh&>&H&`XD7MKL*2Zm zKaiucLND-FdqMyINr0G6bb8YPHRZqVy&erCw_Bp0|$x+#flhbP;YB09l zu~>T@AmT5l-2y_RVl9fmz@TDkemP?R%en$RzE-cKcMh++m!TT3!e9D^ucJYNfPr+? zSU?wEA=8Ke-qDPj#h3%)7Y*sGU&1_k zpnBtCCYvaqT|L=dTrj)?D|2C- zUi%3D)=OLG8+jx;UN+ z5{azTn!K(LeX&vlP3jg=T9EtwaTLVz=EJ|kKRya%4tdGUPn2#I9g0t092SG0r?C|OSW@@s>(8+|evMML1f+FdHAtu;` zfxzalS||yEuS?&u7k{r20B(sJF}o6K#nD9SS`=DeZPEmgx*R$lgUlV~)E zqgN$!^oG^gyda*yvDreirq#f9E&p-bBmv1bH|lzaQOw<#jZEWR(e&U>Os)YdRuWIN zk}9LfF5pkLYlvN%cFf-NIJ=M)ACc);5{&SXgsg~d*8*>Ic{Zj8NfuM;|M+581;IKYeEGV}w zO;HZl_I${hjjrcN=r%-20|-<{{DF;OB$8xbSe&W+(5mbZ=_3!1YyA0KhD`ticZSrj z^q1n}xyI#i6>|CvB7(94P&g>$?L3HOC|>7y%|K2*&_v4UGUynWst74L|C34k$XEC-eYkRr~AO$yB_S+sAI5d$C z@)vb8WI|luk?H2RI%0#;?w(5Tat-B<#28(4d=Gc(1D91;1))p1K9G=V?!HuycHQ(XXZ8{@I>@hj1!qnL}l@WU;pqC(O zJN+|Jm7b!VS)rIRs<3mt(5X0mO>2}%$NyX(Ek5^D4o~dH(p5jfbf6ley(;I{PK;p& zkhDwfuu2a9Pl$|H?1gE`X!NZM4=w6_qD7^a`9ZRe?r?ks5I_qs;cmF?Jj zNbCRE17WKnBL_RvCzC}g1nK9UKgRd($Wd*Jx@J;+Nq3={n^jzXyFMz89?K8ta-7IH zV9g{9CwDof0*pIFb7}P;MmUR{%yO_BJ+MN&4%;b#8qfnSm$1W@FX zZUoT){^|X0zJ@;Iuyyc*Dqw7}!Rz`=G#|GCLO;eaB;#Kmw?})q9COyi*$G|aN^{Uk zdk;(+b-cN{g|vR&GH%U%*%rIL3 zN)3fIvg8qF%#b7weK0?NFABcDz&o1>xXUzIxrQxg$h6wtp!ReUB<%FQ0o63v?ER)T zm7x2Y07T>~|9a;TbhJX)&&!Qi)?B~ilHy{AM4f$8MY$GX`EG+&yvH~0EdEQVweJVf z1CLMBJMXmRU{@4>tRHZnJWq6g+Q4YckW%^7l-MgZx1S?h^l`&}kEaIgr}P#XEs{&& zgB4)B1{*sKEAp)ce4UN4<5gA29vh{$1ub>EDZFG1<2bDF{V>bo8?Z1XQ^U%GN+*j> zejl33b`6e6NcA4jC!DpCkjU3RQER{X)hrXG-`b2AMiGWUYf#N7zoHf;A!DY?d+JP3Lvbe_S(@9w&R6J4X;Fg8aS9Y|xJgyt z*#QXfbRRf!$8FssX|=cYJ_Wb0G|B~{de)Q3Mb{#13OYRA=v|TSPZ*i<8zY~#LbXKJ zid!dvwNV&>xKiW^Esz`SG&Ioe8ge;zFx<(pp1HZRoWB-@{UoZEgX1>cuh$5PP-3R# zRya2meCdvH!lwk7gG7rsjct6eLi#1)6o4$%eC}7hRRlh$Df}BUIxr_b1aTmhM-t`l zVF~7>o1oFoV!!DTyWmetDxrPvmBu#902?dP(@_TFd#?$asz!ow*a34|7&OvPc+7XY zw3VC7?bw&19IjU9UF;&VcTPZ5E?`oNJt0}|Y}aHEd_%=uQc&nHD~n_50x7+GZ6G#kbD9?30EM#T^j4_ zuxB@zV@A7K*-;1We4Tz=ZA+Jp;za|+_b-WV3W|aW>JO8ku4)aaQkTQ>ztmo}_HZ{6 z1xZt^pQBBTvznzeN-sBHL=kzkRyT=zA-~(&EbZ^0F~>pZ5Jzdcb?}#Hv~uRhWf0ar z8w9q*bMBNZa*q(fRPj0!%jXddtnfpLq8!PB*pC$F!ZXs%dc&eyxrAsy%2bnoPR{XS9(9}zR<|lYJ(j#pNC+JSzJwjcY zTYbE<5d3RsGn7>Rjej0pNA@MqHtrA4F*8QFka0O|zJ6Pobb9=b51#r>VI#tbMVC75 z$}T{1%`)Ad#a5PHFS8!aEvz?mGou`kNs+J>7bU;09%7p3b=NHB64RTT?2oEs=keda z9Qo(_ePFT)6F(BU<7eSpN81Dd32&XDp*uuV2|Uk(YM`3|9e~gGPcBK(ZiR^xmzF}* zL8{pxXQj92aq>(BZFkkq?0Y5OeF2fG;L*$pM)|v{_zNj&i+a8vf{=1>3-*w3crJUS z!OI{!@&-HIXtvh<(GBCXCFX0f`UvIX~feH1b_@oW*{n_KVMFxuPbj0AcUYt6;x>UnENWQPo8c~4*_Uob4 zQu>UohnQzK_8+n+1R+l85u8qSTZ6bJy?=K=C-=^v@XL7a%} zUomcEmxbJEB!i~~Ytm57-`h)@qfOCZ-cB^NnmBsq{EAKtc_uq&O7lwIE1(8?KM!;W zOBF5lMSN^ZmlmO8eTI)H#i6sb>4N{RlM~g8HSMkRfUXf=W71x@QwFRl!NB|K#RNwH zBH?jAeCB*1-mzwfHA>(zYi^`Uls({%d1>-qT-x)3G$W`qbs%r#dt`jEJY!}p8k*SD zsxu%d@JD9nZ$uyy`F#J{h>;;F&SH9syd1sY(O7d*O}6uT#V%l;w*f~cHAFSzHr$3D zS@q{a`PGkCT!moX$2|n1(HO!PSyE5ZDzF^E>S{udZ0Rw4iH4kSI;lq5B>@JWNeB2-ai#KI9)0VMumRfKb_zeuOlO72pc;nw$x>P! zquJxDB-G=5n@gya2gb-GV6>qWL(6FY)rZEPqTC=Dh4$*sX2R1%j*sUuG<=0*Jlf{j zp-VOfI_BmCEWBm9>*-k2w^~?BulI>x@w!k@U-G7l>tcvA z2~+g@2}N0TE=rFHieeKxx>V0{zzn?c3gEuWd1D-yz(~V@Y5oBEEQpWBiscRdpY)!i zBoXo)ZXw1aEw}C-=S~iQYy`CoMB;2#(3qM*k)#hNvI1x2{$o9!Unzbx>@N>D(E26V z`U?WlyIhbzEb4qV=ru9B|CQ67SmDr?@wc@`iQ(S=xK6}MZnkE)_%efpo?ThKb1&T* zHgI;&b6CC~wSCtB{pM^eah23aJffC!w9!k# zGU;wywP0K$uP(iom2T*D?O3ZhsL(U$0RO2*1SE(K2ZHLZci)JW zvu$wxjx8C^|?_ATP5grUetxYnbV;N2`tX<}tflb~{Tk`Vy{ z*t?wG{IsU40nqm&VCrB(9RZ6wov$ZX$!<#KI@i4WS`=sLptw^y`tI_?tr8|P;IFnt zD)D=Nc^bzpaw`RVrw)cJcfnOB@FVAt+1V2Ec>>?JpP;PZd$6%^i_FJ<&F%;>5H}_& z0tIh(dUDj6VySyrTRSHOhYSXC`S{V)bfMjT-#M7?#>xB#3QsoaHm@oi9qbafcn=l+ zFC#6S1h)R;BJ9)7u>=p$3=CLvrF^R`ux{oX+t3@bI!JRbL7bLh=qXLG*@ry<%0T@g zC0d*Kyu6=dS6||s#O8HP(cDgh=Aty6E$hY&P!D?jgix*)5f2U$1WPotSH)d^8{>Tv z*S$0xih~U0U`+JoI4#Y$C*Sw=wZiU%4Wqq$R#AJI3rV>NkQhO z{4wpd&)p`+(PqGURaMT(WBl*6P6e52u*eeh)tMc>5v2tn@V!F_k&9-X;G}E3$4af| zSa1@KYBa}*3~Ttv+xIpRPZSPNQ#KR*A-1sP|IXw))e3n57BP0gNBw?w09QA$3ZPjE z%(&sm$$A0+#90c&drm!@u^IJsW2<~SPAIPWWDK5mwaMtQ(D(QLji~+O|9}h<#^|3G z+vv8xYxYrU65iVEK{KgnEVrxaH*rpKqPJq0iXy#d#`yS*TBjIEQ!*$rt!VQ(DuY=3U+B>)-ba3e+Gl= zNk?J6>vbt66bW2lxSWj@8Z4qZEgeQcd#vt3Gw62hHoHFw5W(7{^76Us5^;~MH$2^ClkFj7HSLKin{XIjS8mKdJW6HsYA3_g=l0+NzzQ<6?yh9}NF?dZ*aez!ShS!hA zTLEx3y_)0~MaNN32YV(&cEpdifA7=L(B&>fWfn;0E}q99t^$+p2evqtr+W)hS>~C*doaTV0_P-zZor&?S)FCSjq6h4UPUTBT4Wgjd}=R$1|h*DH3UU!2?*2Z7M&RY7fiF-xMPn3kj`WFEVA?? zAJ@$o&0pz-&as8=i1r5c^<;FA{1y&K4Zo%6n*j3{_3=V)GeV{-HrK|YwV!72%>r)U zV?OE2eNR~shr4}Cy@H4Cae;;ra*-~Tl6+?vz-r8Fq`Ya^YpIbVw?r)ce21O9*M&+a z+C`Ie~9A>$z-8g7^ z)tDqpV4r5E$HqAJHHS^y=p>Y{-uBUZ0`BCPwy;S=CD;7?~lrjX0Iq_5na{E z0BnVM1O@Au+y?9}lRty&wCpuv0I7_dO50_2}H)4VftP6kIi(Jc#j z$P1Bh7Qf+8$*+0Mo*9y(s926PI?vM3kZFBs6^|!IRm*^WnHw?fcIE*#Pz`ktPdQx1 z+C=Mt`>X$geBMP>g6jpLJ2cx8W2;CQe?PtQ`am z$!&3r7h4Gr$cdi6$?;+u^z}<8c28A8$yDqqd#%fMdX>K$R6`~Xb&=#keKHS3v_%BI z=?J&^6$dhV$VO%5TS#)p+)vb)Mork)9w?-iCa}QV7Y@_yLeI>U%Z4d^qh(^^!`+a9 z9>a)l`QLvbSqxjVeaCT{Z0?@<|1QC~6wvy@&|UFApG3?~zNkt6?&29n-ZLPu2qCwt z+fX4$7}(TJG7uYvaV=OIe_z!|S3O-^bEwp2za|i*`P(t=;qIir3{HBLH~MSY?t-cJ z7EZ>%=w{!0gu;Wky~OeHg)END7a<3KE2`KDl#h4k*YG%yb7L$K{QaOxWrux2KtL}2A+g@+Nas`}M0@e6x6F<&SMeL3c>iCMSq&!^h;gO53g>5|y zPufZwGhC*;+IezF&Iv10-`+5w=aq0f>dPA~XA$?sc)MYNwIl_JtJ8?9h*>4XWUzbO zDduzz3~EN`FGBfc!VMW3%KoCpP=5RXRt7SoGrZ!xemlPC1V2hr$f$uK8|cN0lMYo0 z#bT?|V#=59`%{#9VgPtYu@dk$4Y6^XTKho!=H43vHXZ<%0%;{{%bmjsY69ioximbM z{zpihr{L(bfRUYSw8!XT`bVWvAFQMG;?NC7Sy`<%0^lnmms%zJwpo~KxZ>)t8ISu* z{gmQo3>eIuN&7S5f*2ofIM3QFQsTc+3C}a)hzIE6ZSwegRWR-P;|1Y|FbATi;HjXJ zFAWKx(R0M3yPyyw7n%fl?HTozPAZds03Pvw#9hXu9|IDsEra8dwulUvjxgv;$9OjI zo_|~>i@P^!AHRbpgIbfYEiMvPq$|BcBbGbaCXrrc^y`u=oa$AZwubC-^`@K5bF>q8 zj347ooAA0@H7Uj*EDlZxB_-MQZO1>Y7z_b5Wu@y?<#rgqKq|`_t3{@X$eLb$U3)NB zW+V+I;vN2_1Mq{1$1`OP$JwjfK0B!O`b$zUYAb2jnzY6>6%nZ^KCj#pN zr3*0my#fuqM)!I?b`?f4@go~J-+ zf$u^V#pQGY2YK0f8;{P9>=RjoUB)!x<`qN9qVr2V9_1orT4@Fgg0Rb7SrZ9Y{~--V znr+L2g#72eWfg1L;sN={q}BXf)?6vXyKf{(;RG`#c&-f~K83(36Bh<0bPsKlPuI_Z z)j>|mUSX;A{V8u$I?WrNcBj$ZwkGgczVKbm#Vxn+sCC`L^fcoN?l6yfMGJpCEKcCe zdZcrTxwH3v?k9A<;ail=s-YABK;KTH7&09Or(p(i6uNgv&Vsa@nC=d*2Bi@+1gxWs zOv&S%tQwg@_{3F9wOhvY2^?Sfth9l`#G}pmo-)X7GKeC$@iv%Qk#0#Q1b#8eA(_ED zorTTr^byEb-NTPmfJH|Ou&u!sK_XT8KZsOL5+NpJs6HrGPt!ENl^UH<(yn2T-G1E} z+T*UCB)L0oq&EWQC|1Y5I|mt*4Lbl1b>#%Bi5~A0$uGsj12JkTDXtq7;A{w=Aq>08Pfa@tJ8!~Cy(T0b3RM5uJ?1NPm34r^ zgozV^j^>*_cAVPsiNjcqo+6Y{%)5s5vd~Sjxdi?X(&~i%_3zAQax`8q3ywZHYV|4ejydq82X3#%$WeaG9d*1B9A<+2T(r{>LobgD+PoQ-n8>y6rbUPgkq{ z;0Cd6o8=Emc2`2E3X?+#Ica!`zs}Nb82>ZjK4DXc8>G=v9!@7cv#TJ`FS*@L~n5ji?`-zzFtuEbYO(AZ<5}Ll_ z3vvL<#AonP=lGJE`H$4yiQhe)=i8oG?1AN(6kM`*zOs%jQ*_?Lo5v zDzs@o(d8jUzf3rBph}oT{bmq_&WxJYR(9F%;3Mm+OZHBN!@BpXc*9ZL@Fx za`yY#PP8KAKb!_h)dz`^xE3{Ndc(gTzT-R(bW4jq+78@N_rLo*)3p=d=9nDTm~5q2 zIW7$WJgV4Mb3}wJh>|Y8oinY8!50QP%?=;wKY{Mz1(-IRldmqAG2Y!5VW6PIMLeFv zu~juZ@7^r`A73Srv%M8&@pCgsDineuF&)?>wb%=Z53R7wDqDh)=nX6HVkQR6PjLnyW-?c8X>jKY9HJ1MRL7-$u(*_Fs8$Mgl>Z@oH4& z;s|7iFyiD5nuSbU4B;5(y}jkgfj5%m>6`~Q*J+6A7et#Ism>D&dneO4A?-G7pym~2 zDQ{8?6;`1fl5x%ktibMvMg8;>i zWzo{jEawZk@I6ZoCit0(F_p_EekFWF?A(EAJU0tf9#2h=;2dX8`;lkTxN)b1zL`LBCFQ&YpVON z&yI}e8SJ`oU_^BzquqI=T*bQPJk9efweD@&?F(0;8D%Yt zANh<9%So9OTHwN7;d_>i82Pj7{qT=m%>5zye51Uog*F}J=rn-JJ;+9^fY;U`=MOqBAHWc_6NwaLp5X|!uy0X~CiFo?GsHBa zCQ^L2i?sM1{+7jdld&Y5iW5ewxlEExK&tNp7D0VqAoK@-#ssTRh$NxDmaL}cS8}$ab zP-~hfqn}B(^7e(oUShh3-!rn$LjyLu3Ud-cGcTf%Uz(9+Dl&d}-x+rY2y9qRsKdt> zTzpJ4B)Gg^g{Zk6G&BwRyy3}vl~b3`N1TisccO%WLHR0bAMY*EmF8V3KFf~91rr?Q z0p9SXI^>wBzQS10(I=W7itOpFw=ngN!|xB{dYW7oqgCGe)qy=pQ$iVYqb^QEPRj{- zjYKIcpv#>?nJ262kFa!Qj%Vddj2dI` zY8j)(C8+EpVD9p%yzzAI_?gxnA5cBf`X@((QT;k!Z{D?MD#`+w#J3Rx_%m%bD~YiYDWAjA;oqp`$geO7P%T8XqAuANF-dE23{ zhSFY#yjPwOG#r6)gm6XnKIYxHyOIM8YL()h#Y4{MUmEDvVzeUc2y?T?Sd;BLEf={5r8qU z5!WBIo@Geo)M0`8&!$OOoKCvAKLfZ|u}Q3$fF}P;2-`A}U2^cBJEi|cvlDWR5km1} z?+}c!Uc3gKlJuk?YoY4Kit~|qyA1*o_o-?=78nTTM8t}<3#vvNeZ%n%*PR=eFC9j& z*@~6+6%(A@QwG%hQY7$2UPuaU_1<8*Fh}irLsxp^Jg#j&aD_499rrhbNb>MoI6D=N zv7fb@}iEK-Q zu(2Bj!sh9zW+1<9dE{Se{e)M#Yk?-g=2qqw!$+IG4i^lax{Y|1Px$W6g^C?MqG~*R zmI(+Z$;G1?lj6a$^Zy0<@QPjimC^-V8$hp@W46O51>#xccieC_ego?{rde4Z%u zVIvD};Mg6*1hS8rUO?KAU{)@%lj>eo+_>6%J zQ!BueA=JylBJ-rG?S9QR*%#e;tq-hp&^aLF7xZjN#Hutxx?|Hr_HQ`aJC=3I&?FEy zT??ciy|~3U=hwAC_f$|u+)tV;SS3f-betx)XO5Tb#c)tje<#X62npLSWLXYlOhRW1 zty`H7U|Hr*GQ?M7+#0Z&68LgC+#sv`eB8y#oJ7dJkth43{qwi}XqLC=PN_QR46{ap zbTD)rf)SF{PD^3XBi@(T{n*G&GDC*F4q(jC!>#0V^+m@Gm8WAZPO-7fv)n*+CF^%_ zaNY(sAekdj@@8B-#ty^aQ7fq8@E4~t53yl`F*ecp3kwT=$Fhb-RS+}Hg+Pzim+^?o znrM1jw17~cbI}DV^awWUSylLBN)c| z-Q1aCJWjA|k;_1;$VVX}sdt*vSQ%qemJ4#OYG(smV?wUpx1C7yz912nFDj!|vTMCs z_LpYV>4V?&XJw}wW;>;rL~ND@EWtYo=kW*5IHS*dbI6U6OsjxI^hSI%Dk2^+)k4ClUEDM}3xi+g0~6-i#g@Qpn4s0lEifyOiwsosoQOe?v7 z{HmEwfixiHJLV9t_91nKvho|Z`HDPQ`|;*AT?8D(yi85rHO3DcIH{!F6XhGzBeI;) z#~)F(W9iU*F{`EB7&FWxUd+Vr@#{e@*s#v99SikLExE8{zvL z!X|59aw)sf*V)qwZc`h-W|NCI7UfT_&Ejg73PMVmU`AQRryMdqL8I{?{QK2Aaz^8- zJi&$4#(z4C(lzohJoEG97&|>7);l0p4hyB72HTuhC0YpYVCu%p3jpvg@Ng`M$v!Ix zZ?_b|pZ^7Tz&r(lxHERcq3btx4r2T!wbIcn)QX=HVq>mo6choqf`Lei|A?jcy~2g_;f${>xHd;n7EuX8}# zdhYqoL!W^OBv9JPjz7i*88^1LYCDu@$U#iVk67KuyvtLOsQl>W?maQF_}Eu&H(FD2 zncBNSvK6N&MjnijEEd*IcU(>7z5;*DeJw>nXE-LbX4qN+zD^~5a?<5o zNg%2Lv<;d;XSG)WW$5;V5{0x(()rRUt|pPNmInp>3uTvL!(2><-g^q!e^L#{ZeQ(- zvpA|rMh*(ruWCMMxwx=;@?hm?5k}`ACRS&@Rc|lfm1l%AR9)f3y|Ty$i+#0LYr}on zUTJuclBWlfU^CUTjf9}3E3#05hPhCj#vb{)m1Nx2?RkSaC!u{;A~gLZX>%R_`;hjo z^bylLrjT@WCVPI&s3uZe6a(vwDZ}7fugH8gKtXqUVE>>OO7|-~f@QR;i66SF$Y5>m zZ=n^57urPUMY?R~9D@6!mhB9l?$w$%eTEn*bKsCau46q5$+{q{W%wF-GS9dMM9FPtb zk*z`)k6~O(J=3yC|7olT479Oz_#!7Wg>JAnaZ*KpNYLf_F{A$zVec()6AzQEQ3QN}^0b95AQO@fp>E@yCM}6&p73!=jnBkKmOn zr$?Qyg%=5=N#=%j;^L1=z*_1w3}ZQHa1ar8EKQ=r$YAiVWQ(Mq7CagQ-jirx-|kec zrkVix(=y#JZ-ul5!i?4aoie9@{ld@9yyaIE2~=>p#%6G+uJCAtJlX_<_W5+E#K&$H z#E@KCNKzG51%P0*rgWHYvr{S-UO#e7Du8pK3*Xe}@%I0$Ek~m~CeUDklb{zHNkQ_= z>zoB*ZFML=SclOSywd_?!xX;HRlh_#0sL5TjoAbZ-M4Slz$u4vVtCu)dv4EAmruXn zGJBX-D8ecgYywtScb{m3@Jq{g%?Y%sqaq&eovu_!UnULO=1V{>>*KDr3e}|3{4gMkZwjQxiGqlNvu_2KHD9RWgvJJxm0I`&F7r0m zf~1F>QZ;KH&A7El6HwW1_;Mm==|RdgM50@fc{ypEQD`dbpl(^{n$9ZvFPA@l1BPJIrDuly^(4;X>P{HvRW9El`r(IVD|!e{I~$S-bAw*e>q5H)5n zCqqShG5VyB2efj!H_0SsVr@V~g{IvVj^Jlcf(r;_(55&s^;K1i{1?qU=h;pqkaeQ} zsc+@cUKpF#0$pdD>J>NH*cyc7M8x-33U5_MZ55xpk!^-+2IxV2rJe}#?M ztTjmMx6TrIia%vki5lU4ahN2y2YMBL{dx}o$Sp;hY983q$70HB_#kh(QsMbEMdE(z zg?v*Ii3mvqD1(++=1&`d>D+c`o=!r+t;5Ej4<6diSL!jQ*R7vFoXiCFA;6^`Jl529 z;E_tgCsl-x4{0wo)`meXk)-1qx}w_dFYn7S2$^n%zCF%}#2pFzo4q#Zrp@e?XbQvf zc6KK?S|&_^Rw}kpxNCIwRIjQJQ@t|M;Hr=X3YbE018+Gh!`I1Jhl!-XhUt3n;^-CU zgBiDY2?N@6rHx+K<5Ca4&yK_Zmd-{o=($;|Q{+)f@^TfaN;LM~FS~eF3}BflZ@q)t zD!%@k|LVGwTNz7$Z{4m^=DOH=x;A%KvENRsHo{f-99rf~`#Z$Wpu-)TI`{_wkC?b6 z*Nag-_GzAsr>0I(sCr3TwtM69)yW=xfPusrHaR-K4@`KH)S#}<5|*$ZkJr95c(uxz zL5c$KcN2jws-#P;d#m1vvNi$prWIrner*U$DU9K3Ieb~9iL)seaV?YVKDrDlwGOmW z+>fzVskV~m+=%d+=G1st!|a))$E8jYk!4&H8L2BiJ)+mY>?jMZ%^sGXWS+2}GABsS zwO;loJ%xYs5I|iO*VE&XT_pNss|DR!imkQ$CX&2nM1XG$l;P?vEP4{R)FglYZ$l<- z8}PseA>`X)pafgR5A5GpCPy;wEjtT$g-RAQ@CHCr=Nh((-jdx_ls?4#d{estd`o0% zgv?&^TWNe07V9_5DWRKT=m-wlOq{SoDIZo89!+XSFlyScwq>w=nv}X>?BR3so&3Z4 z?y-t=*+eAjFNxCKR}Uc&V1bh>m(@O%tC;M(-xAlX<~HuLrA9M&e?Mn8^wQs5%P=UK zqKJ)<=OaaB$F>jr{dL=8=qEnuBhAEQO<_zV@(l5m z+DM{iyC|UXJ&wDcl{U4NU=!GQ`?2;RT@<<(@$WO=*iwro{9{ROOBC3GTH7J#i=eyW z*YXJ%FT9PY{CR*3kZry#N%~oXT@&K^mU_aW;fatheEx)7GeM75P{&n z2CQ`WTtV$;2Ru2N@J&dlzNU%iY43TIx4)iQdagLq1cII`zMT>sK^n@`HY3zsQTuB- zz-jc$xFfIHKCW;!tfUVaUYVNI<>>h_T0YU7Cq`!jhJGIza^pQ|8b=nQ?T6yd{Uld$ zsbuypAl~p(=N0N1tv*P+GxZkflfT8#N&Iy1DHvxgrMPbn#)FmozCU^#UZ6@bwe+b; zu}y>I&%^(2OyLQy{Q%-3>>(JzP3`oW-^ju^50dqX8Wf&j@lVQ_0{n8jmlG@oTT|01 z^bmYr?t`X+cn?s`zUacrv!cOOVJZMG$C(?M?px2L^C)D~A;x}Ui5-~3bbF+1 zYw;L;I;Dvu_cYFtA7@iC;4u@-)&e4~H2Z@7O2hlG_)QY?^WD{RIvl{JD$AopG$$TN zB(w9T%y<5dt`P|i!n-&*6METdQLd2U z&TOVB5kqMIN$PB#2{hQGER!ekcUqd5BBzF?3nX6529Dtfr@mC_gFjh)@dOF{k$1ha zqr>Qo=dom;k4HuQ1NWN|)Qz@nCh6&COq3AMe(Z1HwC?aO2t!#+)KKhu8BZvMMOESP zq+WfQAd7+?^1%HOZx%uhZ=Cc)TXd6FPKHqkEAC_j9c?p80dkAP$E!}PO>irV&jCry z0n9SBwiJOU8Elqy!WP1r5``LKyD}ca6aoRpMp6=rm4;Xf=G^dm` z6}RaXEn}o)KqL+re8<{=mvpaWZ;nF-Y)Yu6*_+<_f*S40u$MiebDoCX*H}<;0-MDs zl>Dk;hP*8KT^0U(osq^`67tuGuzk0+wzpwm7v36--|`**4Fcq1Ycnmw&3-SKVX!s` zo3P?*QjG3+sA*8}DsO8R==Twgq5mK|U}@79k2Qrl+~evx^0jVx5)j>M*AV2=#- z`=djTU)9lN`hof}NuxN4y~TVTlv{COCTnMb19Bp66HnHgx9ge8f|KZt7xLa(M#eTX-5FD&NY~C+@2}QnDS%T?IS9l$<;9QC z{yr-bx|VR6QE%CG+!*Zhh86ip^S=A1ns{C7V4l8eFd!mmSZwj7TNbn=nq|!D-iPZc z*#r{L;3LbcpAI@phHH!|^5ylo5#$Z1(y6c1CK-00FagwRholxy?a zLD_%r<^}F*3dqa!f!~KdX2UR6E(y~11Qvk#m9e=;Te`&o5?QX0*>iuTBgbP&WaNk^?x4B{EW9>2~k7PT)rm9^d_d+OP zbgFg}DDEzFR|}XSh*e!lZ6rH|ROHoacmlKbY^)6y{`Li37Zg&%r4SqJrkf3qV3J(C z0r01JvJtW^7@ECiza#2zANcNAP)mFAFR1|?YnBsC)Kz>NWEjoN1|k!`y8it51w#$h z_lwlO0d>4=(?_s|B5!kZRS(MhrB7VtNq^_-yz_Z)oVU@4e0{$x zL&iHCV{Z_~Nb-G3jVC8*<0242py*ca=|8u02=-4QZ?qGyziLwstK&aeA==Hh#b!(Z zw_T?3U|Y4Y1{$)o$jFkwCH0g%p6s@hUhaSSR0*^}Rk$XPE@?CQ&&dxvIj=8P#o*3- zt_o`GYdMekMfOll81Q}gUrOottmgx zQNqUO@ZyKv&S#H1dBXh;;?C!w(d;X`-xtlAX3igWJ0O{^a9rJ*E724NBo(AyBnt4D z`IVf~v*S8xuVbICTWdDF%mF^p3f{b*!DRnjC9)-0lYI__ts|;Z}61P-#4+v`rtEbnsaP z!-b};qw-{4=TjMd0Sw(v2A{j&Q5B9;TY2lc#9+#zpfIe-(Db0l{(B+o`M;~qoz}}# zY$d3#PNcg)lp_)NSLnlJa=05UC_qH0Vu{-m)<(X3#+g|uWx7<{3M5!w+oscc#u3gfi5)RXWlkz$PVGU|;R@8GR&vyX~>ws#%`*=tj9)Xd2G z?4^i(Ctb_*B+7Nd7wAH5W6EG4=Txj~CFva;0RShfrE83HxHz0pKo6C5q8p(N2V(d5fpWb{rwJ zrz#h<+FMPB$|A2uZ+d=M)o28e%$R9H_N37gkJlK*uUdw%TKfAgsy%5WO<1Hy_wU-K%1_#ssQkKgv&8A zG#CRdB$x&jNACWNO|h|jz}eUno$D0HJ9L}ULigUQgQ%>--tciZ(ir@%-@9jdDKzRf zu|HZ1Q{vndS(mZwy@=WZUS3==u{V5$VW10gX9x9zTRbSI#`G3a*9eD2=p0Wnd{9mT z_0N6oB<@kN*Ia0&vZj#s>mcN^C^8dfEJGcGLbQ*Mt7GT)7h-`a)TXr z>UH@c%@rG^ihJp_&l(0&-^+4>^xLx@UXsAlUQJ?C9~6HtsBqckeP|1b+dPpD>e4>& z1%gKis0>QXERTL+d*7Ha_L`XQ2_HaYD;BoZti{TY_GhsCiK3g<66@1^^N*<^uSXKU zk$#UNtDL3EQ3aVDpeYfy932#geLFiaA(`hR0RT`N8x|8kQ=J}3&gBaI6^Q16Y0y{b zq5I;|4b935DEKoLcKn0j)oTc3dC~a#ql_1Q+nefRSSc`LTcREc_Q52I9BxQ>8nykl z^LnB?wsihjNhg@LR3RPrd2m_#N}%O5U=S!rFX~Mq3cHU&V@>M`ILPzV(tmnG`c3d* zFfd3M4o05>k85t^h#o*i%>^t0FdM(v?`|*gDoDX221d+r@lY}(-|QI=cm_e_>_+l- zOs?F7H}M%84}6rr0I(pT6}gk2KyA$W<_?ng=)|t_lSe&GwhtD8b^nwkkQLn9@1R!! zQnf2JxFXn+0MvP|L7(oQ{D(~&2}Z^Yec6A}+|OAbe_0%0}O!El%mJ3_!DKUX^VM)W?4g*U5tM29;~;M*a{^=wrDCEg5;)#=xmJ^f=uBweTBVM!OFihObCm0Kjm`@L1qno_+{r3^dk5p}~=TZAB zeggxx$OslN%T_hO!N?Kb7oml1quUV>U!ub`wwpG3N0(^^E)j^ z!K?_UE+%H{Bo2iho`D;K$OXT_!71bd!LC7+=}e)1P~n%q2$*5q0-`&W2XB;GGg$mg zx~G2r7wG$Oi}(Ld%d4Le32_HGnyKYie&mrLDyC7*`aG7Y2}DiZWA~Qx0U>@}I4BL? zg(gUo!Iah({7|4lBdKNNlUa=*4CH`x20u2{B@_E#J^3U!SRl@wr0x*VK^-fw!s;xp z+&wA;*&!mBGHu*4{O)9)6791r_pk70@~5u~%CLeOlIR{%&rrGD(h;j03NX#nuKVv% z`(oMqFJDccjY|Z<^II#`p?>&CdhyG%Feqath_b^$f&okvuqW zQ#_are_M`r6tadr%wH`9?wbf2>w;HeciLiQAz)BpV|OmY%p$k~@Kp)DkM z?%ZgBRcaXp4boglXF)j81N(>7b$uk(=!qzyq{h<3(Pg*QZ*InNI1UP?c8>PKVXQay zvV44_H_Yg+YWP*nXgk8H`_j=Z!*y@|-Jfc17_?PrAA`E?5xD^Dem2!CK637MZbzd+ z;Wv3?%|q=TN~E$v<--9aiq;NumLiYL4`pl9cPF3szfhog4r(!y&uKyoZH=hMF7m`G zEE3pdVLAxaxFi`-k{UFDA@Y0wW(6nv(3}#=^iNT^0Z#o=_)}(Q%lkMso(?b$U^6Zx z8X7Tza$UwE+E!lIj4*`p|2kl)Yq0RHu6DPZxZ zw{cD%7t*l?m$>6)XrmmV_l7mz$;(TyHG$ zoGZ)%n^zMgF%5c`0DMp7yl_4JeM(E4_ddjFo^~@ER`^>92rR)>u6A{UFC;tohF%Gr zR_Gwbrl7L$_mLdQ@#lKkDGwa!PJNMx=#|>b75COg(XT{$5P;U7PL%hTOeKWytAOLJ zc`InLq+Cd#7%V9R@hGIW%L7!4UiaO&<(~U!eIN7N_#Emrp)hgRSKoeoeD!A_5t7o= z8TXu%1So1=Qb7Po6Upy`x4Rcl%yz^WGihCp0Moz-U^$8HY%hlP{8Na{lhC_T=Smr%*GWMul!0OOga0_qT#C*>A3={2KG-R?hr_kc%%px!Bhf$nMp3(q&xijf z^_+{Iw)O?h0dZ2n6L<#srB-Q#5#{=uqt{Y29s-7P*XE~YKjsTxqfy=T%_~39jNsi# zNFZ;+(SU6;)_PYlN^0TrGVtVJ0xyT0aF zKWNq}Vxp{wDtG^HJlPc|7lgfNFY&Kj4_@J5A~rc9a#v`a*N$%zWIK}c=A?fwu^JOe z|9SGy7+kTTG?d;`o&d+IKYo9JVa8BU{IY3i|NK5C(~D5`*!RvEUca;ItGCdb6)o<) z&;VrmNt1eYcQK9$AjfRA1EqLh}XRFP7m;CL37M46# zRXTHRwb&>V)7!F-RSZt&-2-pFvuVE`wn#<%Y&e6pOGrg*|1e zjdY)gWd)hCeH6+Pr$w*A&>H@a`G!`Jhxv6BF7za2Nw#hPUn;|_8-x+rY)^4ZAbGWS zgPjK)>1=h1(oR%!3mlg|0K_g@*bD7C`GB;--2JEyNBgsD!;J{@<1&mPj8JZOx!wQY zh1RfcYbQRU+F1l-w%e)T8lDXzMMP~!OMK%IdWT!#@BjeM{-Uq5VUJ+LHLh8x7X0Ms zy1iLQL(Dy*9LW7)SfvIsT3dzumJ{fpv5|j{rL5|?F0+I7!d6z2Wn`%dUHvZflg9+!(C$2&)LR3qM+@?--KE| zlGP3%M?(ooXD54-IE2kS!@FlXHL$3*zFb3&eC?h3O!x*!JyZ-aCSH#ZoM`+lQ3i-1l>w;CN39k-@zE&dAbLHoXQa}c75^6GYpl=W?@!C_c@3I2E(Q1_C< zP!f35#8gFxoHr77Y9=(J>lIVTP_8VYM<)5SyoX0WYE$e*~fqq2777i8m0GWCki1Q{Y@Gs{p^t_CtUqyEwl z7*^`GsNv<#44>^_iY!|*DCDvM;)aTNSxR~l4hgqW6a-QO^WqYenu}rIPJj2_?d26y z>pjYMS9MFl=^w^1Z94|=J-*9eKqs9sj;}hQdTEx@z|%ewxViKRBe13>@v_mF6uY&# zp(D73flF(P9Vl$2?LX$3AW99=5vtnVR43!_d3SwJFI1PP-8u+dHiliz?TrY6%8%pN zG~T9vFFo_V|Ehw<)-v@)H_%i=Ptl+X9b2-XOS*+mb^yS5g6daf$~$A>3}rOYaAHDJPVqocPE8D-29}qSJHq{+d-FERJSrC0GQC({rs zc=P&Nr+h(PycY03`BU$%&FUogO?vcZpi&R3L(K+ch(nYQ6|QI4z-r_}YKV(Ux*k}_ z2|Sjm%5KnHj-w17!RUro;}h+hF*qh`bA^+6Gt;NBcAQXjFC^F2@;(z?5i&kOH9^6{ z(?X=4koBbw>I!a}mB6)ONv%&aN^+{+f{}ws!(bp*M#y0$EOUs^k^NCSKU=0Olq}5#l{Lf?ToOh7d#^>j;fn{qepk@^1E;)NSPL zdt&MIrGc=Z(K@{j+dh9J>W)Y#EH49}quNBvV4%#f)?|K(pDp0+5G(y!1!#^n+2~=n z-7W5H-v0tvcKgLRibyDduYikKqOR4XW~qCZeZvGMe1nAk zH}Ru4pl4H|SFk5@{65XLs1f2Ye;(u}x@@R1kTv_kOwLyXP@3sr@N)NfcI>XF3nV9N zl4@A_^x65VZQimEqFdgd6#`3Wo4ln2q&t~95lR|HFbr@ZUZy~N=a9I#+{*Vx?#fD( zu`#?9-Vt(7e0Gn|q9e+f)4GN)GH}Hbva{CHp!V4}WAiiSUIz!0aCA+P_7Za0f{d&A zO`h}$H09`VJY)vwZ%UY0OR7z?P`t(Ka6s_DradsqJ0ua``7CR!dy8G87cwWBm{vrP z)?*>KZ4p@Dj+e%Cdq3^xK$hYEr-@FDgR=#}kV9U=xw;6oWh7SPH9=jnP8< zR;Xy;*V%$$)4r}*I5=-LR?h|$UikLID^y}z{W1p``QmfuEkEUm0+j$1D7t^;sj!Z) zKoul^+WGdDI_b}vi~P0;dJT&HJ7ta}ivc#NSYT~dVuI5ZFy`!$w1M&?$w)-HJ|uu$ zjma8iMp$XtG?Z%2sk-}*zQ+?}ICaCaAoqT@oZdX2seqOb`3l8u+Ob8?M=!xz1t{^m zhU0K5i+l($^c&7O=Gc^qRz!}zkrEC|z4xSDEE_Nq=LL=A1Zy)ReJUs7W7}hf$$d!h zhHDrf_nj1J(6>YPa&$k@zh4c}Mwgfn_^Q*axLnb|ddp($7$tTi=mZ`l4-jh#o} zX20^i>>8vTEmo)6?q>ZZj#d_TSeIdFb@6fvBxaz1I{xO=mfLbX=MA6Rgs8|#Z8>o~ zBsVp-9*6wd?vnzAMdn>-Jf%h>8k)YBYm;zB_PDFXtFC(-&l>UPEImGF-6^=Mj_a94 zd!#}Xp5eQX>MhRb*heNF5CX*n$lhB)hRS`NaN1_t=ViS~J=!{~GZ&keH09Ms)a+%LfDU`TRk zkWvrb$3%cjy{N}1vZXwGTt#o8$tU65*|^-};4|U=!zPm&FIqQ<88unY0i2WP+cHIy z%V1fMuYNrXdvJjAZja7+Nn49867Fu1V!C9tgbDpT&~13qllj_g<}vK&Z#TjZl<}H^ z_2@(~(;M8pGs&_(`>qX7m3638I&wlhoF9IjFwdYFKXCz<0!6$NbFW3ICmKpQKX`|e zhHG1`s=pOgS}0sKeS}UnPwcsQ5yAC251xV+_D@lu*JZrnE(s5eK zimrvArsQRBJNhxq^_vEoKDU#K;@MtHWq@%x@iW($Kaq~Y;ur!_O`S76q|&?Ovzo%R z_lXeCSKXZonOW`NOs{$00~A-Bf3n(nzukI$4XHUECRTJU-z^0gzKO1Zui3X?16>9F zhD=<5{ym_uTM5srCn!zZ)pwhPq)Aj@L(kp0^Q;5BHh~PDzz}i1m1STk$X>U!B>G`* zDET|TLIxD8!sk(ol8BlBS=*nNYKetLx+xdxV)An$sE@)f%=#Gc!enqxprfnQxQ+vo zQ$_DL%CLM+jS4Aa?dL>zPPIkuPQBv?&C%{T{ zku12DIiwup+lc7t`MRiY-$J#}Zo6HG(GkFlA7J-{;ap0qACXM-T;GszkmQ42T-D8=iT`Y$qAE|#Q7XL?bPZ6Gd69HC!ZY1#z1RTGZ zzzb-Ejx^tw{;Qdv2P2qKbM`-nEJ;E)F}ZeTQs}eRbZk>G4GFT1ZAi2Fml~q7(x>VR zgh+c`+T?u^#eAUfEdEa}@Nt0rp0zQ${CMK0E*~}{(P$%WxhGVKL&wGtHpfM2C<>HE zlW;5qL{;n?@hGwXxm_k;Vz~#`ahp|ljj@WTM|W`H!=fM@FN?P7!^?qmRem%aQ1aza z@HnIcz<=ljoA}F~W}gsVXf-~z&621H@l)(-csHTrW9+@6hRIo(lDb%l8a5m1DP+~< zRO5V3B*EpOXiOX_!NC`0L>W-G0qmhq*%?w{h=!fspDoVZ^7n`PS9-c-&06p1C?4aG zc<+ER{XOjB9FXfqVgDN;U;x1IMq4%|Zo0^*Epai(v;Dd7-q6^K;3~bkoeST8TL~K( zHX<5)_e%HMmb^3-!R8Jqw$5wzr9Q8VGWswy-a}T!#|T1{v~2~EQSqe-id~%k87B(@ z;XFJD2mraFLCY6H2R%XScmo{;kZE`e5*oaP;?gHBab8Zf33DNoS%>PA8sg*^X&)?_ zt!6jbjIrHS<(_pNUBx>OJs3H)61*B-h|rj$dY>~SKhpjKO@>9yV`OnA1{6bd38JPV zA{L$axTDB4apIb6^RIgi-*fUd%nu!{5>BV9dEpB-{U*hhE=CGk$Vc}LGnA2)y4<}H z=$S$etzDXq{U0vTnljE<&1d%WVM})(!>0PzpHTZQX&$bIId@_gxy)}|M1L2a^DnoC z{-<&I7LeoRavJd9_`ZMsMnNY>K~u9XN9ANgk;PU zrCJhEJWJM-fSnOy76;mI0x@7oR9tDy?~=u)ORMwjEH6A|D{5pAajqXh*H|!48i)&3 zz5XJDaM#wl+b)Fu$8%B>J>5%G8Fwh;^ONx5Y4}|OitI0gm2kT)rz1mX2-+A4PQ}sn zE5)>r@ntW4GyBahA^@>@h04AJxl@;?0p;$kxBWUmm!GezBXP`Rcv$H2cIuvPqIxPq z;oO^L(T4>&x?kdQ{iVf@bJTMOkc+x=Mfp?%9PF%M?wh{Yk79dD7ud?UQ8vV>Z0stz z`qf$cNi(_re@BgBAGi~2fxUow?b8Wi+RV!Gvh&gMr95?$<<@G1kXF5=<>@?((8U_r_Bl74Ba-whg{lyz=)nE`;dv1KH4$pt6N*XHBoP z`wzuM1YgGH7dY#_&qKXOkX{m7Ih5?s6N?Vyo2o_PQAH=yUr_NC^w|avS-6nXr7*1_bwAzGh+u*R6MeSNa)(NWNWZ!2k1CZ#~r=(Uai^; zJeH_kt#np5<{Q6SHN*EvS9^%gS^N^edMO@mJte*o4Q<;P1Cwr^k5|QzNChyKZfkXs zR22<1RD_#Fe-CQc?I|>&08K!$za8CtGy%oGpQKuxD=5n1nzA=qzQzJ~q3n|14ChpC zdo|AEUo-OTP_{HyjUK@s0V4!AF)$m}LleH4kF~^!N$hmz58=(^3EtsckWVCyi0?m&BunU{7^3i(N^*D~cCA ztVJx?zjO+(R?Y5iZ9(n~A0z$@WQa}FR|n)4hx4vf?cTKT6WP14#g%ypA093FGU&&y zS?0EcpNb1$0bLD5A)X~$pbU0W%!-*nw4MkJkT1N!9HRAk zuxjSS=C^&|T4E%?l!-&>BwkoJM5J)KSOu-aV6U}V>f;QGMss}Wol#u~KPH;~8$oC2 z7l3| zN`riuM#!5?D9xBli{50=1mS~Oq9>~F-CTvY!V-l`+xS4MG$wK?!fwmVjcO*4!S3eM z{(V5eGaktKmQrbYvpBwyn<;?_oU}_8coJV@~}zf!?$2n>4mut#rCk$&#JW>TPojK_cPD2xI4Tdr^H42 z)Q0yu^N31Kyfslve=U%QjaW*vT!wY34HL+ZCr5<&n!0u%6t4>MV8Mkz@9UU4=pv?& z@vOYuV0|cU9PVwbgC2QnyvXEUQdU_%U-_gdt}YCuQq3^5biKf)u(mtSP-FxF^jeyV z$%OmQloN(@g0xT2aEJyy?Q$r8TbDcQ5e7qD)&_jChP)j`dHZe7-bF-Yd%VEFDdlor z{G_pThp&3r;&z)gT|Kmj(boUw#Msc02hH)-rY5`KJ z`m8$psQzJpnyDLRxa;5sPEUF|_IhV_1LK?3YyVLlDPHcH#~m8?u(>p<<x zqomk;_dm@+>5MqDb8KGeq_k^V`se}-mlH(^A~iDm^bCTSrVpux#_5z^%3@yM?7snm zcuu&68xqCMOLCe0L(d;6yR?#2UO9M(X3dCN46l{@xe)F^zDHGfbVJZV(yWa6EHQnyVtE;jd9%$2ZhRqic(r^ zIycC|1iOh_ssh}TBlxRbE+#ky4cq80Iq%B164Rc~O|~&Mc^`vxk-unaxDOjup(H?4 zvrqN6obelz>~@_WJQr2W7)aRL6?K6*yEq|X*Em)@oi5E0*4SKCy*TKIMsmb7tU=b= zj%ZFD1J2P!29j~fSr<5iLW!pGN-(wz6jNdx^7yEL&3j#N%x zhefsa#9Byh%ifF@Hh!IQKQt!3*n~klukWq7_`$_9N#IuWnf{;y){Je3w{v!Qk3zkD zKsavA+-C4#pF*WMmj;mO-WJu@3R}u0kSn?Ag5|E=8-^n2?nC480Flft>m!vF7Fe%I ztYBW|MzV5=6jG}xyf5%i1tyW3QVh9KyPkxMx()^lIVaZf(@OdJZWsSuYW0FL3?;Aj zqTMDA{Ga71H_S^o@P#diS*N@x(B^&~0uGh-R~E&s8~3_i zF8zf1M=xrwJ!Ka^;q!R~K^ckDC@TDwcSC#8rk42(q&2FV58-t5)}ky3o9WsA80#ny z3+06g1HZc#wnX}eve_yaS_jkTDo(k56qWVruPdVP+tycvALg7!c;C9ol>gePc z`d@^P0E=e{N6Ssb94Eu&q_Y1!y#$n(d<0CnRc@AjnqT5}NiN$6oJtwAIVF<* z!|zyk$29C*#GY%I;K?*=#>D@>A8zb|ONoyVQ_W3_lRPr#AwL_zUcTR-RR%XP`zKK_ z7!L^}2x;=2Rg|K2D^K%EqOt_d*WL4sAM4IUEpkJHKv{M z!?>Jdwmb4Ir!5BH;Q+*p*eM$ul}_0z(Q#k(65hlVp>2CC&gI{TzzpBl1eQ?DI**Vr zf(v1y?$K^DU0PSa8!yI(C5Sn-v}9Hy*_~msw9j&5Sak$`PZ`l!gKh56 z(4#-5BT2qx&Xu{`McFGML;O18%L!kZ z1RLV*OK|_*`4|C-z)bQW*Z+tyI_O^HK0H=MbR;Y$)r%*j&1eW#D(k=umV5%3RSzeg zV){pPK+TB#YeW`XCD6r^U5Q$O)~*f+$604XF9vl!&A}1N-N<7wFHcntO$#@ATni6- z29zU*7ZH5fblA8~ySvhuit;j&SB}A|ma8vW62Chj-DSP{uSFA8!3vC&w7*x5!KH{s z7w@;==twBJQ&}r^+XkfpwM+v-byr-G!OveXXWbj3@>Tqi>llwm)i%FRXQlDC4K1jW zhz#iVjgyT zFQ^0?j}>nF*xb7Xdt;gWM}G6Y#oDK47009tGq|iMbQPn&aI^&VRC&s=bIAFn9YG-vna$23+J)Y z&x3gmx3ol|p4X4l@>sUi{k_#zF&grB^8y<}?Ko8Mtxs)gt$GgvbU_tRH$x&LyL_Pt zk%g6*W#ao0Nt@XlNfl3-hb>QztLl*aW_eqFjeVbXyFNc`S^zRfZl&IUydE@|tU=;# zto0y&Zc6v@8r%TJG-=l2<_Q`#80o(hPb;?2%cA ztF-OPYn*W!#17x{CQemZ>O}asi7cL;V^MX1K6l|A(OZqX+7TSn_B^JBq2^OoG+vs! z8u2Ff5NI2#53Z)kBsqH9FJy!?Y;nHE!-Q~1AaZqekYo(86JUFxK_!XcRUEh|lVQ1+ z-p~{dLLM7kyCrKCj1sC9zvY3o{t638t3UZAR$#VXMb`GZNEILkK%0<-4Bs7FCE~|A~B^rA(W6aZ9U+tGQ>;a z_jsP$Hm8%c63lSy5IE%ylXVAJ&nx+A?TK=f^cVFo78Dk)E<~@&iy~rB-~aTdPW2Sc}0(&H4ovTDszM z05r(r73ca>uFrh%TTn8iPaX-hnP@5VhP;gRv_1lJ1-CE-ffanYDwSu8c~3cmbek?t z0EBWkjWR$SdjJySFoSXhp8{9N81q)vr}-Ny{?jl(dxp}U`FIk_cReu(mu}cbGklc= zf)}F;<-P>H!d@B=z)}?dGObGTy~h;|%9d2_f|;Ye5)z6pGc)vtS-I(f7@4=XW=It9 z+nq!%Grl?^hi|DnBQ(_0839}gL)s`Tk{G4>=9ygkv*v;Lu4t*jCF?^;pGD}@T2nSH z59>b^M3KSf5KI4XKB8qGZIKB^abq{=?$i6&8Em=Ul+iKa>%x+KHNIK zB#!J9|3YrQGr$a%3Uorm2o%164w)C}$eLgSJy{s+r~i?MuS*WAy0nocbUEKI2n#;) z(Ni0>SS7dS-sUkylb~&#keDpx#iX2>M7i(`HvjYrwwz|9bBe~gdS*{9TJR4*jBtt< zE8$R-1fIxAqo%-#_-@lr*U5AX>JvE}<%b7jLmn2MY=D`|&+x8>Cdh zk}sTaEDq?oPFdf~15lx~99{ndSgalhE+=5hyD6IxmGOcR(kw$_kX!AbgU5WJ<>Oy*@>;p2&L8O1 z=^U@tgL z4t=7wAzw1tw&<+jJ2x9X=y^*=#1W5SE0DrX==bSrmk1KndpG9I6Iol=sIfxo1% z3cfkfcw_BaC5`Mo%H3N^%MBa}(T*WEn_}n$vH{Vc>a7#|J0UsNvgTG*x`}E!5(_;af)md}3`>{{=vLGoVz` zbGJeujT3=y2?|&fhv5*CVGTvj7;Q@O_)FLS2|Vi4!4L_uL^5-3+2hDV_#EgmbIVBlSpN6R%c$#K`vRb z0`DQd{)}1qoG@rZFRYxcKct|02S|SkmEXl+Uv(`Edzcf&X6|7+)S|kL<|?q>R6|{m zYqpEGBbcn!RNpXP5|Gm$XF2H(;;bE|m^!>B_d9_$mHo^y3}oj7GxZ6w@MPSvN6!Ht z$ULP#E6MgzyTpQc;&S=aRx(akWyG2UFc>s~&OB1@!)iTRO+35ojU~xKrAZV)EpAtd z9dY7=XuHWzgem^n6}FBi;uqfq2Aj!$APVqU>C&V(QKi{Z2=MX_rxZ&J=9u!F6}4aH z+NAUpP#+&{i5A!(E)Q` zmog?b{@udXw0M~3NE6@>Md<7DoXZKIF5SdAy7z>EN7lb{ODq{ua2a_YG^!m-(}alL zNKZYA?SgN~ZwCr+kI@Q3fGE zY-zsYZ|+-2_#*PKvsZjZSl69->@s*c8q5s8Frl+oC#~Y)$b(Mk;4LNM4aNirn)$rta))w?SHp3ST&{MG}yMRnaN= z+brY<&w)XvJUX(YP;hP_ggGAXaUDdrkHU5kV27k5MRw|yrG3ArkHYaQ==%l3>VpEc zh5f@p!rG)PH{nw~9ROLK{6Sp_eXR`4A^t6P4=5mTmOmO?c^6(ajIMG5$l}1m)-!>C z(?_M+TSk@zW_tUPQ8w^6^3jKRYHm3Vmu?VK6xEcBrEjE8(aVr$Vqh2qM7VMD5sDgo zb#n%MaqJ{!($1<@M%WnP1dVyuVl+5`mYp)n%KZLDkQc%&R^;E<1@UzW6RsUTlo(6b zlx4I8nau-Srvybl8qTgusnxf@*jgjyBwA^}k@?p}wnQZzGj^fuE#)8Gj@%TOZab|pMm2|g8m?$Um(J0Vk z?Ik(N@YV?Bt{A_hnloGmvTYV-bJ_t1IB$~jK-hDR*F#2i15&(<7z&fcdh}6Q5&lxI*(_71j9CJ$zy4m%bHz>SRl6QNe@lTZ3 zTCNQC+xTOfZ-MgG4wGap<_bFLOj5{o-T&O-*OUfVA1k%V_#`3V&JKY@M2+0vR?PL{ zXW8mf9;IWEkl=C55@aA@4^?Lv6EmyHcU8Qzq{}+hp5lt z_J{bPsdJr@pC0&YB7DJCq$itSBux@5$DF0WmO}&uCN_Quvo5LN;fiRu772t0Hmop; zpJfDyvD;6f@Qu;Aisc*;8GUzCTa<7DGKLKkGkw6ZXd{W+Dr%@BZt`&UHfU6dJ5&3i z1u~ru(_-!e2A?!o(;JWS>j}4)1n{zO)f!)lb!ud&4RX}1z{+C~`o)wUH8=y16M~%{ z_8$L^q%XL1y$v@Z_db|aP7(Lts^_@cg7qZd>_6wa@K}(j<~92;a{W>7K6CGxgqp$w zlMH9(M1Ae_NOV;$_YGLgg#Wt#WI_{R_i~Bw)$syGZ&!+ z_YV}XtLNI?*%4AHcY9bQ(I?DQBr<^-`MeJ%8_Yf;%UQ+nQr)&)$-C9`Nw?4fygw^V zH_jxEp6({M??dNi(SdzFn`PkM#roJ_;?EqNrU_wmARGlsU)c58i(F=}1u3ou8*Y0S z#xly{n0Z;Ue+2BUbOhik{GbP9G(^BBv9(;KcQmbz@gTPRuJb~?_&oI`)%Hvb&ww;p zUyw~cGfxg4Mr71I#!kDW73Waa=d-?7Z&8>(B-BMZI@38&B^2_^m2z%*Jkk^nmJ*E< zFo@vq3RCL|1HnqiACTzyph$NUEj_k)jVq)Ct$oCYeL3p8bPHsz;K#@4%mxiM@YS?~OBM+p3WWq<-*A{OuXI^Q#y@e#0irqROh>oes|G|B&9|h+ z3@gJk-$VL3-`e(fs)wge_^HkcvlJJX_{cpv4sJrf=OC?Da@RUR901()Fg0ICtD17N zH+HPab?1|a;E9N$!%Ff0lt3X0?jYNA{(VbmUkNxKV@{(`kd?<`V+rI23_14m@GQ*} zV9Fe2Z5Qd|D5(%LYV-}!08p#tiLN(guU9c2`lyJJx%4_76ID;V=JMGGvh}?+eF7J@!sFT?Hb*7y$wBhvD=rpA!RT%?m7iRTVS`$^P3_q1543*s# zEInp*c*#ioe9bSVaQ*gxFMgEo9`KQcJOCWLOnq;#|(5#Ieh^gw}!=Cf~0KUOg zAVD2_vn-V7RTH%+d?aNB7K*xHAJ|(H_f-u?43o!0Do_dWKZ~HdpNMHGa>|W=$;Fjy znDQd&kUJSx#itX#levab#O#g+eVP=T>bCU+>Rp=y@fOx0-Shwo37Qp95L1pbYNf!J0%P6yfw!l#bn)L}fI1qyDMDUY{l2TJgu&MpZLX zJR?$*1I5mlXejt#C|dCvZlVN@%ra2;_rv2hW@F#=RBKLSJS+;}1ikwBp&nxg)tCHn z9m5aXDMMV(qh~meKYN#?YOLP$?wJoh*G?(TcqVOTL^obvGuLtl+?ErxjMd3BCw_pN zdCkTn2EgQp!$dttWTPjE1p~1@Ar`GbYk$Tt)U}(RvF!3eYWcX9^I%rYe+HudhEl)= z9j8HEo7^XV>=2(}NrV<&c@{I}9V^rUvFQz3n|=`~NlkQFO6@~5ZRtHsMsj@Y!DKQj zpa7E=$N+z>oa-tjI!dD_y|M-qpZlTld}SgD3B)Lw!O^=cu0q0KjFMo(U7KI0t#Yuz z9vO#O`sT5a5Bt8c#WoV{vzIPwANQ%BPLpK(iGlmIH|YoOE@UM39DVp0c8b!ij@3f@ z#QT8C6*di|aNCQ=2s^-w30{>tqKT^K8+potynMfIAG$OrDE;bsCupl3Ei)+@L-Ym) z0um}?sHC+dUCqVu-bE@V56qDD64hRnZ|=}2Azi6X4INyuyn=JY9wo!2fAJVBPwq$(eo)h_n%xa$IkZL9NH(uh#+jiBhbvKpFvy*?50m68uZ z;H7l2qye}7h-K~3yBbHUb{4hG6hAJxq?zF11c+E|ryLUJZB^(PWEa*tg3sIASdW$w zW^<;g&EX`!vuBH8k{*XP3>PoPXA{u*P8G+++b<(tiM^`xq~T7m1J9-h&R&GLiqsM( zH86gKCgJ@if76y!D&OpL%H`xXhF+B;O@3_ZHPCee5J8C-0tkFCx<99{XK zN9~d54H`yd^!ka>EPz!_$tBVJ;|%fR7@`s(!|p$%eYGtAVIo$3>JX$xmZml~v$5(% zl7U-Fx3;AI@)GeD#ol<(v-O0`-HC6?riI!JsejdIQ4$&*;pvBeCdswgJR)GyfOME| znukKl5$_NRNv3N7NZ~%yhCFx5oz z&dz+d1dKUQOH9({(3^(<-t?ZHJAxe>$7pZco0k|`4o zpV^{F@WEtJL~%4B6&dzgrsnB8oV5%UZPL~p)$elA{mJorX$yuTQ#=Eibmt6z?6z{* zr_0wk=Oqv#RRQAe@;a5yptyd_2%|T@D!qeTCGnxAf!!so2T2H?TZHyey-ZI28f&8F zI=&TyaMhib7t`daq6#v>&h&wbcrQp~Taw%0EGep>c9`NkQ!DJ0=}~RKPG`~brYO+H zdZBq0^5tAWRF@ z9n1gf`iG*4fjLH-_BsXjx6QbV9%wMp)bOynP&mX=q6CtqgM)Q4H@DM;+l4QdMVhm- z|3?Hy9ckMv-OEfCR;3F&+OP?d{($`}#%f74zi{W)`-~(2taqT5un}c!Hc3 zVaK0!t$9o;4^I!|e_%u9{j0|niD)EJ|C_VBo;3ytgP_nMe@kvt=5ia}fa!@29q z6f;4m%gA=@49?DZ_(QN?Y^z_0J;_m&o(z1W z^BfPVcSK`(!AGu9V$eID+pV(-Vz*8C6(f3c=4?6+<>)ckdEd>^^A{{*ObYo3@ zzJxz|g+S!szgWS7E!~z_=nfQ2R)|FC#i|f~_(SM7ZQZ7E^nHP_u=pYIaba5xEP;so zQ^Nw)oyn-Ive(S8R0yx1U5R*;C63+~qRyJ*!?JIN|I`eW|7v;40bOweNamLA;y=Gf zuD^_62486PT#A(K08yrPOVcIsd^V=zWZBm+*x0y3+P}W3z;cl=f&N z?Pg=L>HSQ=!LG9Un%$`{i>3S11&-#*glAK#?VOCZlFv&LjLa}t{wY2`)yyoT9=u z6`Hxc&TLQAcH+@eKGnqbrzb`^rv`gX?F@!lOoM25hfxeU$Fz(qk_2O) zFqM3>79vdFyLyz_(OP_~DDEcn8AUssPAdX$b5$2mrSl;2ZsHm)Q!)YdC|Tj*t(6wB zK|={2lTbac2_>uSDrf{Q)~F04c@;rxY%BtB$*Pan3emfUx`J1d|?? zl9HfrgMIGvRvbPpC?;`jDssL>Xepb(&)}M9nFzrv4_+RkqBU~W+|yn++eaap*A+hx z5#$ow7V=Lo0hSv>4R)FObDK~5;Or@-8rEyEPRGJ$5)5i@<(wC z@w=mf2*Arb@ZU_x*I(Y2@zSk!ic+sH$StNLycdBpgkLhfCMMM-Db-*z0}e^1FFra@ zmzx`Y$&uDC@(0I5WSam+s2TgL_4+ZB0+{okZUoOJa|ECd{TPRHj^i7OyT9#1TZQa{ zGN1)<(p)-b&pcH_tYebqS#tuHMw(+Lwodmiq`R-_s0_Yl3dxEmxL0b~km(lGGN&9) z$8MNc?@tL=DjT+wdD&{)hZmLlvs!p?K8|%G2cLj#x0X5{HvV zrfkKSbT{yo}c?!9%d^tXjev+%WQ71d9ma7!Gs)qW)+ zxf4Tld9~eg+HED_Vv98S164sHfFwxqD?g9Tsn#23Bj3= z&JsySW4ufD8Z3f1AU8BypX*=KO5L2YkAJt9+ywnsyEoLI(V*j^1Pufkh-ODlXs42Y z5>C&QB2-t62TOCd6yenWW68Kbz=x2gh*@5#21KLMa0fmiEvAP7u3$H|?@?JT0Q1Ln zUr!R=Kt8Gj1K|75tNBe6?;*so;{s0=cL7R1n2kV#Ei4WN zX?KhOZO!+WX(+>@tJV7jdn#@1KkP%NP8sAN(h+S7U#Pri44j~b31=A`4=0ftv8{mn zt4aI2RjNKrKN-F`qEw;Wo=YUvL{=1{?)aw(di>4PuxHz-C-6$E~K( zF<4irK_7k2m0XWruo$AGUUCcpp!u}tGvb&mLAA{&liJ}#)(HoFSJWkF*DT@%w5Mio zzo8V3u%sYD*@5%EOwY*qdjA`rqga;;oWmDW@|zDjD#Uaw=r&b_^QX|){$7|b?^1V; z$3L(!d+{|~F_=_HClf@T(u$Yvc`9RHm|c^O--dc~ar9Et$rKh#_~>TCPr)TTw)S;I z6$TY2`G=u_VI9Ze4_NfpOv?iQ3R$Hxo+n*0n4_&&5K0g>IQSZ!(qBriACgAnfK%_A z%)l-92=(P11P5_}c3xf5uU8Cl^!`wzC*4u&xm=wb$21Wu!On8}l+uiKHO-wUOit?L zV=1X>sp_%J49T-Ko#9eV;X~cEW!$$Aak8E^5+r1#`)N6`&4kqQv0r2^liJ1!{H*vE zORn%OtP+RaG&r5lnJ0yyB`Qqpeiz}p^fVp&AVL{^fk*)=R_VR)I^Wh-MJ#fFej}>{ z(VS%lhRLQp#ja5A~3ELifAJLi6*b-}tm_RiuJ7aRk zvn&$+{*aAf3CGiqZ2Z&GEY4?4LnaD2e1CQ5cIPVb&qBlhFbohfZ?9dKh)tBppPHOx zfNjkFXK&ZGS}&VKV&d3`^vX(W_Q1m{0Qd>;=_FhxPO}&^+taRxrYc7XEEX z9i8aWuG8(XYF8=(;6-AQc~uqpiN8vVZT1*G9l&JwDWA_t`t#|&K@Yhm>&|alOtP`l zJlqM%&8bFXohzjYj|h+3eJ07&X72v3z@jM2RX?RZ)Z|OG^*T2xeMZ(>FFv?ZU(cgQ z8r?pAAla-wB{1Pl566+QFKBUi5kO;`$KT^^_o$lu-&Ho-D1`|2Y^g-7SP4!{&J$kr3%vJ2WV# zesBDaeUZ1BJJ{Ih{+pcIE(eY56D4ev6=Ob3m*qr)t|`V?0-iY%fY6?0C7o&3;8BZE z0h#F(c9!8}s~41XED!6b zD(Si=K%4IApWkjcDNS0A@*T=8^PZX8|uKJ&bq(5QXJR z54HFdGOKG!(M3s#JfU;&GoR^5d3a*jq=k79w*Aww*$YU`~Z>x7bRS3;i zU_01rD>Zq66)DI|0!p~ITpnoT9_-lA$5Ehu!#$-e{Z;Y^Y6mUuPcfJ)=y|xF1w)4m z(K>PMR;_ia2&)8`BOb}IbL~su1ZO_*0B8Bnf|L`{09?Vn!099gXLaU|u6{%jnn~!X z_0BeJiS7|`!PvZ&3)no4aFjWuL3n7VjfHHLR$5HhruDw_rS`u^Pt>3KDmx$NOQH$= zDBWQ$CokU_q~CxWA9taGjKglg6HHYj~KpN3x$H+Dj0-1WSTH%@)aZNXHbH5 zs2%Hm#b4c>6n+anZ&|2NlLm_a97UxX%`w`2`2SB(;|4>8uCi+vH zgkz~zZ{zh29FHVsdmr9dM@;qML0E*8!qO4qI^GI~-cME0L@!@H>9CJ8FfXuGDnPjnilh_Xv2zCwFfhAqw z6Hq}5o+L41alzWDA*F>G`(#e<&#m{IEpLzQ#3qCueEZHQrTom(uD45G37!$Dv(9 zxCiL229qxvcY|_9Gga!-8SbZ)dj*?`vDa}VW^*N58 znZFE)x&B8O1o1w72X;X8J);g?_(Dzi=6v8Lt*i+-&np^tKJ1smLDB}Wro}5YL0rB+ ziP#IlLV>`f!F7QQ%qeF8G_lBBO9HouOV*fpm*y@yk*^bRy>W{nvfghwPL1OdNE^u< znMSI+sNoLTUO1upm>sHdj+J2{h7y!|%vwNjh#jsL<1D9Dt#Zyea= zX@Cbjjp9}z-di5Ca@_^WU(JxK&FJ)xUv@4`v?A~i27@QQ#LVV!WF{aNVY?3ogWd+j zaRk$cGuB5hV&rK!$gI5vocx?7N2Bh=OL$;&a+pXi{Ca)h2ti%cY4(1_G7@#J zAFIg{$YgDm9iAHDt_?p99jI7gg1L2iOga`^;Ww+6-={afttQNjaarry$M04b5WSzu zk^)ic82CUzteQ*q^y@XJz=5m{XgT*%^7go%QJW=c9Ff2xHGh!v8v79(R(SWMq$J3I zaO!Z|PtrHVQ8oYDF@VbRF?#u6%HCL6Klh zC4J5Ct7pC<)5eixNGi*Xl9%93{m^sV$@))=GS!-jbyBHi`2g13Cx>jjV}7U|bPMAt!i#BD6IzJwm+k<8r;7Ec#`*TJpnQ*4?%I2l&b{QY$WZUf%Cugxd^C25}EtPd1p zgGZ8c8ThPttJK1E>$NJntHX+w&)rs(dYy_v*j^M~_Av8@L_No?f;Uvy(w_ToYc%%tQD!v#h6zFqH182hpr|Fv2hi#m( zU3`L1G_}%#dg#PQ!hzm0uGHEZv`M7h%!eoa!xNiLXVa{!wu!djgcedcJOCu zO$oIsTG1+M+5y}>4v&is4}x4NLdyNiqya5YzkXW9rK4PQwt68FNAz3t>7kbks6vIv zE&uFmA*=?AmdQ=D#JnRCuvy(0W=2A(ZWK&GO;O{=`2$V7J5M2`*p4 zY~Ae3sKDoFOG9Cz9_X53!IIT5K1v0E`J&NfDb|Y&*IG>180~2}`a)=^8kf;Y16f~b zj{N~Rms&}bvX(!k-qv5oArP&}`*PEnBEc}-uKGbJ9?WTq-555`;V7Mwaf`pKkDdcU z=EA5D_+t_fEm!yZ^${H$h+{(^dc>1q&1QcPSlPe1fng6vDKfv4_)MQ}rYiz1tl$U8 z>`>lm+%x>!ZDL4&RWN?+3>ZAL=9HkHl}*N2wsY4PjSJ!Q*p-%uyFWTaK)8fcp0+0g z;IE942V{1`TH!FADsHo!`6X#;g=?4*RPk~bnc9E+nk&SJ&EQ&k+k{82$gTRMB1?Cm zc4~2GEb?QjBwqN$LU52j`yY1+&t8Rb0G*-~sQgtImJ15s@@<2*Wn3Zk{!#g|QWI&s zxS?IVxpb#c*71iKCPE*39zb&&6u9C1+i9D<&=eDYmXT(}#~o$!RB?|#N;=jWK?v&{ zk~bZN2IP?H!1@{NRyLkq-5B|F#14kK50`+{Tol?ja9Up3RH^ZLWR@fW!5WMdKhoQu z)k9cbQ&JMwLXBbEA3%}p!UxqyLM(Q5f$ES_L#-rAL6CGM0Y6UUVNiTG6QLlh=xQDl z#E}Y1i5rtvZ8!))jq$p<)o3##ug5fZ1ihnx=K$ve?-Nu`X%vhdPC4$s(d}aO&jHE7 zC+bo#YK#SXK1Z8n)aS|ztmLQDTUlSzD?1@xA1iG4ZyC^g!T@qfaoh-=ib)hjHE#ew z{&v)C)i2oVib&DxD-}{BIIP1rT&t+n;GxSR%^JN^mcj2nHMS5Co}$-Akt3V$ zyn`C9fK191Xw$P}RAS0FtouT-|AYh9flH^Ow!cS#Fg`0=zK_^2>~fFV_0{XOLw=VZ z^fq94|8ZP~p&^G#qaZt8=UVskd{fATQA)7{)KwWmuRQ1bf@N__DyV!UPykjCMQ;(1 zMtN(XCIDmE-?g;MF1tI;wW9DrKn+E~_ANw<kr4VohnaeZ! z)j>JFwbNoDk}n|>Q0hU(MYqWAX>ky}ez1@k1wfywSHe~~b5YNkv#8H7AGL;fWwx}! z^v6jEYvya!B?6+OV2KW;ZAoM~59OwH9Ic5cGWm+@X~&!WeR`Wg&~{OwPi5Rdj7uuH zGnz?kvGl|0rS?;f7Bq*_c972^x+eRL*gg;QOeqt*7!E-yfrb!ZH31P+q(F>u#g3a0 zIv>-!l2(DPU7X$hd?!)HS6qIe z=x}bCXZ2HZTl!FTLt)gr@EHjgBfWhJjkq!;Ee$3Eb!zH#H`m;7{@3Uf`3RFin)8eK_MZ8YpbY-yR#t)3K|ZU<`98h>iW)VE1B& zI9Egd!bP#TZ7>PwQtyqU|90b;%j9}|l1Z~FzzTpuc87%yST~g5a^psSEZo7Csz}Pe zFONZBwQV(w&9~LH99A$0B3+Shpj#0&uj(Q8qetO9v!Nuh?} zmFUO5<}8z9&>(lGD0@@IwTx=kGcIoA_ z6EZW#pv)7Ci)N~{>jZ26Up~hPR;9=~NtSi^WnJ1H+VzCct__xkm&?EjSQHo~b)zw9 znH-B^P(|`i-!p^YC!OcfGfjNbI*L3jBkVr}8$0(Fy<{fl>i}ylCZ;f7QqgX_Q?+RHVJpS zUYtc<9>StaFa_8*@I??0^E(iPSp{Ha4$Pll4 zt@)pgiRp9GJ5p{Z`%4UWSw#$H387G1 zudItdS^d@~$)vK65P4R~g&`7_kqtFTOsGVLCEbR<$WNZ{wtH8ZWvQK8Xw=*-O$Fim zT|y(o0S`9>qvz+QiRG2Y2xpxJbzY%}%axqz;b0d(#5OglDY2(u-VkXcNJlCy#$2%h zfO_ZrbFsh~7VVH#fVLFm+m{+~p1WyEN-046n>nb?PHzQ&;q=inYe`a~;`u%O!vhl^ znRyE8{KNLG<0#T$#wcxWZ*CpbPAfWR`d2+U}MWk@cj}*28D<}Q@m8Ey-?gfA~ zxS=d@`Znn5QTO`DmAAPN`9bAfev*DwPsL(daE`jMl#)=XdK;c|0ZQ?S{)hPz+OW6C zzT16lvz^jD11~Ds0n?_{l6xRe z)(x{PUKYxv9s;2OGyoWFgcml>x#6~sh4#^Gp6i!417((=&GW%GJUuKo?U`T>sPk9? zuxx_d%iRyErnv~>^wnTy-$#1anT5c5r!RIdf*E!Rp7C^|xQIqFA1Gd%?qdnEy{E4; z2rnR4e=H@d3bC!M1{qv<$!n_=AI5oNC-cE{G0$~n*vgpLf=NVOa}>LjpUwTdE-3&# zK*GPDWW#jh@AV)V%;2fYQYDI8qPfd>VFo04BMtJ>mnP zGFP{09&%XE>YGygiN((jxqtHE_xOmQWNt$Aa~VAp4Dre+3QxU*fHvLk*FmI|#nyI$ zV3}vJ4cJEw=(1;rh|XcPvERDo=m_rTx#9H&XSBDUMMRsdqWr8u3%K-0HDeSwfAs$l z&C^`yNjA-_3iSUhWcNKSvjl86%+*`oGw^*N>|sgQ%0D1-pS?)2mfVxnwKqtg&sK2J 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

    nU`4k4Bxq2I8SFC=i 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 RydR)na?(m4%RZQV`#;W*f2sfg diff --git a/docs/images/qrcode_binary_utf8.svg b/docs/images/qrcode_binary_utf8.svg index 977f1496..34288ee5 100644 --- a/docs/images/qrcode_binary_utf8.svg +++ b/docs/images/qrcode_binary_utf8.svg @@ -4,6 +4,6 @@ Zint Generated Symbol - + diff --git a/docs/inc_header_pdf.tex b/docs/inc_header_pdf.tex index edd00c3e..e22030f0 100644 --- a/docs/inc_header_pdf.tex +++ b/docs/inc_header_pdf.tex @@ -43,3 +43,7 @@ %% Make footnotes go to bottom of page \usepackage[bottom]{footmisc} + +%% Stop xeCJK putting space before CJK char in double quotes +\newXeTeXintercharclass\dquote +\XeTeXcharclass`"=\dquote diff --git a/docs/manual.html b/docs/manual.html index e44a59d0..15e6671c 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -1246,15 +1246,15 @@ Characters -$ +$ (dollar) Insert leading zeroes -# +# (hash) Insert leading spaces -* +* (asterisk) Insert leading asterisks @@ -1303,10 +1303,9 @@ your PATHEXT environment variable, i.e.:

    class="sourceCode bash">zint.exe -d "This Text"

    For compatibility with Windows the examples use double quotes to delimit data, though on Unix single quotes are generally preferable as -they stop the shell from processing any characters such as backslash or -dollar. A single quote itself is dealt with by terminating the -single-quoted text, backslashing the single quote, and then -continuing:

    +they stop the shell from processing characters such as backslash. A +single quote itself is dealt with by terminating the single-quoted text, +backslashing the single quote, and then continuing:

    zint -d 'Text containing a single quote '\'' in the middle'

    Some examples use backslash (\) to continue commands @@ -1324,6 +1323,10 @@ class="sourceCode bash">zint --data "This Text"

    The examples use a space separator for short option names, and an equals sign for long option names.

    +

    Long options may be abbreviated up to nonambiguity. For instance +--compliantheight may be shortened to +--compliant, or even --com, but note that +future additions may necessitate longer abbreviations.

    4.1 Inputting Data

    The data to encode can be entered at the command line using the -d or --data option, for example

    @@ -1331,14 +1334,14 @@ equals sign for long option names.

    class="sourceCode bash">zint -d "This Text"

    This will encode the text "This Text". Zint will use the default symbology, Code 128, and output to the default file -"out.png" in the current directory. Alternatively, if -libpng was not present when Zint was built, the default -output file will be "out.gif".

    +"out.png" in the current directory. Alternatively, if Zint +was not built with libpng, the default output file will be +"out.gif".

    The data input to the Zint CLI is assumed to be encoded in UTF-8 -(Unicode) format (Zint will correctly handle UTF-8 data on Windows). If -you are encoding characters beyond the 7-bit ASCII set using a scheme -other than UTF-8 then you will need to set the appropriate input options -as shown in 4.11 Input Modes below.

    +(Unicode) (Zint will correctly handle UTF-8 data on Windows). If you are +encoding characters beyond the 7-bit ASCII set using a scheme other than +UTF-8 then you will need to set the appropriate input options as shown +in 4.11 Input Modes below.

    Non-printing characters can be entered on the command line using backslash (\) as an escape character in combination with the --esc switch. Permissible sequences are shown in the @@ -1563,8 +1566,8 @@ sequence “\^^”, i.e. by doubling the caret.

    (ISO 15417) for the details on manually switching Code Sets.

    Input data can be read directly from file using the -i or --input switch as shown below. The input file is assumed -to be UTF-8 formatted unless an alternative mode is selected. This -option replaces the use of the -d switch.

    +to be in UTF-8 unless --binary is selected. This option +replaces the use of the -d switch.

    zint -i somefile.txt

    To read from stdin specify a single hyphen "-" as the @@ -1640,6 +1643,9 @@ will be created if they don’t already exist:

    zint -o "dir/subdir/filename.eps" -d "This Text"

    Note that on Windows, filenames are assumed to be UTF-8 encoded.

    +

    For another way to name output files, using the --mirror +option, see 4.14 Automatic +Filenames.

    4.3 Selecting Barcode Type

    Selecting which type of barcode you wish to produce (i.e. which symbology to use) can be done at the command line using the @@ -2382,8 +2388,8 @@ being applied to the X-dimension. For MaxiCode, it is multiplied by 10 for raster output, by 40 for EMF vector output, and by 2 otherwise (non-EMF vector output).

    For non-MaxiCode raster output, the default scale of 1 results in an -X-dimension of 2 pixels. For example for non-MaxiCode PNG images a scale -of 5 will increase the X-dimension to 10 pixels. For MaxiCode, see 4.9.3 MaxiCode Raster Scaling below.

    Scales for non-MaxiCode raster output should be given in increments @@ -2484,12 +2490,12 @@ the approximate equivalent of 300 dpi (dpi = dpmm * 25.4), specify a scale of 2, since 0.33 * 12 = 3.96 pixels, or 4 pixels rounding to the nearest pixel:

    zint -b EAN13 -d "501234567890" --compliantheight --scale=2
    +class="sourceCode bash">zint -b EAN13 -d "501234567890" --compliant --scale=2

    This will result in output of 37.29mm x 25.56mm (WxH) at 12 dpmm. The same result can be achieved using the --scalexdimdp option with

    zint -b EAN13 -d "501234567890" --compliantheight --scalexdimdp
    +class="sourceCode bash">zint -b EAN13 -d "501234567890" --compliant --scalexdimdp

    as 0.33mm is the default X-dimension for EAN, and 12 dpmm the default resolution.

    4.9.3 MaxiCode Raster Scaling

    @@ -2547,12 +2553,12 @@ alt="zint -d "Áccent" --embedfont" />

    4.11 Input Modes

    4.11.1 Unicode, Data, and GS1 Modes

    -

    By default all CLI input data is assumed to be encoded in UTF-8 -format. Many barcode symbologies encode data using the Latin-1 (ISO/IEC -8859-1 plus ASCII) character set, so input is converted from UTF-8 to -Latin-1 before being put in the symbol. In addition QR Code and its -variants and Han Xin Code can by default encode Japanese (Kanji) or -Chinese (Hanzi) characters which are also converted from UTF-8.

    +

    By default all CLI input data is assumed to be encoded in UTF-8. Many +barcode symbologies encode data using the Latin-1 (ISO/IEC 8859-1 plus +ASCII) character set, so input is converted from UTF-8 to Latin-1 before +being put in the symbol. In addition QR Code and its variants and Han +Xin Code can by default encode Japanese (Kanji) or Chinese (Hanzi) +characters which are also converted from UTF-8.

    There are two exceptions to the Latin-1 default: Grid Matrix, whose default character set is GB 2312 (Chinese); and UPNQR, whose default character set is Latin-2 (ISO/IEC 8859-2 plus ASCII).

    @@ -2891,22 +2897,24 @@ not usually required, as this is the default encoding for most barcodes, which is also active without any ECI information.

    4.11.2.1 Input Modes and ECI Example 1

    -

    The Euro sign U+20AC can be encoded in ISO/IEC 8859-15. The Euro sign -has the ISO/IEC 8859-15 codepoint hex "A4". It is encoded -in UTF-8 as the hex sequence: "E2 82 AC". Those 3 bytes are -contained in the file "utf8euro.txt". This command will -generate the corresponding code:

    +

    The Euro sign "€" (U+20AC) can be encoded in ISO/IEC +8859-15 (ECI 17) as the hex byte "A4". It is encoded in +UTF-8 as the hex sequence: "E2 82 AC". Those 3 bytes are +contained in the file "utf8euro.txt", e.g. on Unix

    zint -b DATAMATRIX --scale=10 --eci=17 -i utf8euro.txt
    +class="sourceCode bash">echo -ne '\xE2\x82\xAC' > utf8euro.txt +

    This command will generate the corresponding code:

    +
    zint -b DATAMATRIX --eci=17 -i utf8euro.txt

    This is equivalent to the commands (using the --esc switch):

    -
    zint -b DATAMATRIX --scale=10 --eci=17 --esc -d "\xE2\x82\xAC"
    -
    -zint -b DATAMATRIX --scale=10 --eci=17 --esc -d "\u20AC"
    -

    and to the command:

    zint -b DATAMATRIX --scale=10 --eci=17 -d "€"
    +class="sourceCode bash">zint -b DATAMATRIX --eci=17 --esc -d "\xE2\x82\xAC" + +zint -b DATAMATRIX --eci=17 --esc -d "\u20AC" +

    and to the command:

    +
    zint -b DATAMATRIX --eci=17 -d "€"
    zint -b DATAMATRIX --eci=17 -d "€" @@ -2915,30 +2923,29 @@ alt="zint -b DATAMATRIX --eci=17 -d "€"" />

    4.11.2.2 Input Modes and ECI Example 2

    -

    The Chinese character with the Unicode codepoint U+5E38 can be -encoded in Big5 encoding. The Big5 representation of this character is -the two hex bytes: "B1 60" (contained in the file -"big5char.txt"). The generation command for Data Matrix -is:

    -
    zint -b DATAMATRIX --scale=10 --eci=28 --binary -i big5char.txt
    +

    The Chinese character "碼" (U+78BC) can be encoded in +Big5 encoding (ECI 28) as the hex sequence: "BD 58". Those +2 bytes are contained in the file "big5char.txt". The +generation command is:

    +
    zint -b DATAMATRIX --eci=28 --binary -i big5char.txt

    This is equivalent to the command (using the --esc switch):

    -
    zint -b DATAMATRIX --scale=10 --eci=28 --binary --esc -d "\xB1\x60"
    +
    zint -b DATAMATRIX --eci=28 --binary --esc -d "\xBD\x58"

    and to the commands (no --binary switch so conversion occurs):

    -
    zint -b DATAMATRIX --scale=10 --eci=28 --esc -d "\xE5\xB8\xB8"
    -
    -zint -b DATAMATRIX --scale=10 --eci=28 --esc -d "\u5E38"
    -
    -zint -b DATAMATRIX --scale=10 --eci=28 -d "常"
    +
    zint -b DATAMATRIX --eci=28 --esc -d "\xE7\xA2\xBC"
    +
    +zint -b DATAMATRIX --eci=28 --esc -d "\u78BC"
    +
    +zint -b DATAMATRIX --eci=28 -d "碼"
    +alt="zint -b DATAMATRIX --eci=28 --binary --esc -d "\xBD\x58"" />
    Figure 24: -zint -b DATAMATRIX --eci=28 -d "\u5E38" --esc
    +zint -b DATAMATRIX --eci=28 --binary --esc -d "\xBD\x58"

    4.11.2.3 Input Modes and ECI Example 3

    @@ -2946,31 +2953,31 @@ Example 3 UTF-8 encoding by default and do not support ECI. In this case supply UTF-8 data and use the --binary switch so that the data will be encoded as UTF-8 without conversion:

    -
    zint -b QRCODE --binary -d "UTF-8 data"
    +
    zint -b QRCODE --binary -d "€"
    +alt="zint -b QRCODE --binary -d "€"" />
    Figure 25: -zint -b QRCODE --binary -d "\xE2\x82\xAC\xE5\xB8\xB8" --esc
    +zint -b QRCODE --binary -d "€"

    4.11.3 GS1 Data Entry and Options

    The following symbologies accept GS1 data:

    - +
    --++ - + @@ -2978,98 +2985,98 @@ Symbologies - + - + - + - + - + - + - + - + - + - - + - + - + - + - + - + - + @@ -3084,37 +3091,37 @@ all of which can encode multiple AIs, require markup in the data to distinguish AIs.

    The traditional way in Zint of specifying GS1 data for these cases is to delimit the GS1 AIs in square brackets:

    -
    zint -b AZTEC -d "[01]09520123456788[10]BCH4[21]07" --gs1
    +
    zint -b AZTEC -d "[01]09520123456788[10]BCH4[21]07" --gs1

    (Note that for the matrix symbologies the --gs1 option must be given.)

    Parentheses (round brackets) may be used instead by giving the --gs1parens option:

    -
    zint -b AZTEC -d "(01)09520123456788(10)BCH4(21)07" --gs1parens
    +
    zint -b AZTEC -d "(01)09520123456788(10)BCH4(21)07" --gs1parens

    If the data includes opening parentheses when using the latter format, they must be escaped and the --esc option given:

    -
    zint -b AZTEC -d "(01)09520123456788(90)Var\(34)" --esc --gs1parens
    +
    zint -b AZTEC -d "(01)09520123456788(90)Var\(34)" --esc --gs1parens

    Closing parentheses may also be escaped for clarity.

    For matrix symbologies, a GS1 Digital Link URI may be used:

    -
    zint -b AZTEC -d "https://example.com/01/09520123456788/10/BCH4/21/07" --gs1
    +
    zint -b AZTEC -d "https://example.com/01/09520123456788/10/BCH4/21/07" --gs1

    A further way to specify GS1 input is “Unbracketed AI”, a GS1 Syntax Engine format10 that uses carets (^) to indicate any required FNC1s.11 The data must start with a caret:

    -
    zint -b AZTEC -d "^010952012345678810BCH4^2107" --gs1
    +
    zint -b AZTEC -d "^010952012345678810BCH4^2107" --gs1

    The final way to specify input is the related “raw” mode using the --gs1raw option. Here FNC1s are indicated by Group Separators (GS, ASCII 29, escape sequence \G). It does not start with a GS:

    -
    zint -b AZTEC -d "010952012345678810BCH4\G2107" --esc --gs1raw
    +
    zint -b AZTEC -d "010952012345678810BCH4\G2107" --esc --gs1raw

    4.11.3.2 GS1 Options

    Apart from --gs1, --gs1parens and --gs1raw discussed above, there are two other GS1 @@ -3123,8 +3130,8 @@ options.

  • --gs1strict, which enables the use the GS1 Syntax Engine to strictly validate GS1 data, including GS1 Digital Link URIs (by default Zint does not validate Digital Links at all). It requires -that the gs1encoders library was present when Zint was -built, otherwise the default built-in validation will be used.

  • +that Zint was built with the gs1encoders library, otherwise +the default built-in validation will be used.

  • --gs1nocheck, for use with legacy systems that have data that does not conform to the current GS1 standard. Printable ASCII input is still checked for, as is the validity of GS1 data specified @@ -3143,8 +3150,8 @@ Setting the Input Mode).

    a separate barcode image for each line of text in that file. To do this use the --batch switch together with -i to select the input file from which to read data. For example

    -
    zint -b EAN13 --batch -i ean13nos.txt
    +
    zint -b EAN13 --batch -i ean13nos.txt

    where "ean13nos.txt" contains a list of EAN-13 numbers (GTINs), each on its own line. Zint will automatically detect the end of a line of text (in either Unix or Windows formatted text files) and @@ -3167,15 +3174,15 @@ Formatting

  • - + - + - + @@ -3186,8 +3193,8 @@ Formatting
    Table 10: GS1-Enabled Symbologies
    Symbology Implicit AI?GS1 Data Assumed?GS1 Data Assumed? Supports GS1 Composite?
    Aztec Code NoNoNo No
    Code 16K NoNoNo No
    Code 49 NoNoNo No
    Code One NoNoNo No
    Data Matrix NoNoNo No
    DotCode NoNoNo No
    EAN-13, EAN-8 Yes (01)YesYes Yes
    EAN-14 Yes (01)YesYes No
    GS1-128 NoYesYes Yes
    GS1 DataBar Expanded (including +GS1 DataBar Expanded (including Expanded Stacked) NoYesYes Yes
    GS1 DataBar (all others) Yes (01)YesYes Yes
    NVE-18 Yes (00)YesYes No
    QR Code NoNoNo No
    rMQR NoNoNo No
    Ultracode NoNoNo No
    UPC-A, UPC-E Yes (01)YesYes Yes
    ~~ (tilde) Insert a number or 0
    ## (hash) Insert a number or space
    @@ (ampersand) Insert a number or * (or + on Windows)

    For instance

    -
    zint -b EAN13 --batch -i ean13nos.txt -o "file~~~.svg"
    +
    zint -b EAN13 --batch -i ean13nos.txt -o "file~~~.svg"

    The following table shows some examples to clarify this method:

    +fixed width-to-height symbols.14 @@ -3746,8 +3766,8 @@ resulting barcode symbol to. Must end in .png, .gif, .bmp, .emf, .eps, .pcx, .svg, .tif or .txt followed by a terminating -NUL.14 +NUL.15 @@ -3962,22 +3982,22 @@ see 5.16 Feedback.

    To alter these values use the syntax shown in the example below. This code has the same result as the previous example except the output is now taller and plotted in green.

    -
    #include <zint.h>
    -#include <string.h>
    -int main(int argc, char **argv)
    -{
    -    struct zint_symbol *symbol;
    -    symbol = ZBarcode_Create();
    -    strcpy(symbol->fgcolour, "00ff00");
    -    symbol->height = 400.0f;
    -    ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    -    ZBarcode_Delete(symbol);
    -    return 0;
    -}
    +
    #include <zint.h>
    +#include <string.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_symbol *symbol;
    +    symbol = ZBarcode_Create();
    +    strcpy(symbol->fgcolour, "00ff00");
    +    symbol->height = 400.0f;
    +    ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    +    ZBarcode_Delete(symbol);
    +    return 0;
    +}

    Note that background removal for all outputs except BMP can be achieved by setting the background alpha to "00" where the values for R, G and B will be ignored:

    -
        strcpy(symbol->bgcolour, "55555500");
    +
        strcpy(symbol->bgcolour, "55555500");

    This is what the CLI option --nobackground does - see 4.7 Using Colour.

    5.8 Handling Errors

    @@ -4096,30 +4116,30 @@ occurs.
    Table 12: Batch Filename @@ -3257,12 +3264,12 @@ Automatic Filenames below.

    The finished image files can be output directly to stdout for use as part of a pipe by using the --direct option. By default --direct will output data as a PNG image (or GIF image if -libpng is not present), but this can be altered by +Zint not built with libpng), but this can be altered by supplementing the --direct option with a --filetype option followed by the suffix of the file type required. For example:

    -
    zint -b MICROPDF417 --direct --filetype=pcx -d "Data to encode"
    +
    zint -b MICROPDF417 --direct --filetype=pcx -d "Data to encode"

    This command will output the symbol as a PCX file to stdout. For the supported output file formats see Table 4: Output File @@ -3280,14 +3287,27 @@ useful if you are processing batch data. For example the input data "1234567.png".

    There are restrictions, however, on what characters can be stored in a filename, so the filename may vary from the data if the data includes -non-printable characters, for example, and may be shortened if the data -input is long.

    +non-printable characters, for example,
    12 +and may be shortened if the data input is long. So in batch mode your +data must be unique given these restrictions otherwise files will +overwrite each other.

    To set the output file format use the --filetype option as detailed above in 4.13 Direct -Output to stdout. To output to a specific directory use the --o option giving the name of the directory (any filename -will be ignored, unless --filetype is not specified, in -which case the filename’s extension will be used).

    +Output to stdout. For instance

    +
    zint -d "1234567" --mirror --filetype=eps
    +

    will output to the file "1234567.eps":

    +

    To output to a specific directory use the -o option +giving the name of the directory, indicated by a terminating slash +/ (backslash \ may be used on Windows). Any +filename after the last slash will be ignored, unless +--filetype is not specified, in which case the filename’s +extension will be used - e.g.

    +
    zint -d "1234567" --mirror -o "dir/subdir/mir.eps"
    +

    will output to the file "1234567.eps" in the +"dir/subdir" directory.

    4.15 Working with Dots

    Matrix codes can be rendered as a series of dots or circles rather than the normal squares by using the --dotty option. This @@ -3314,8 +3334,8 @@ and data is the data to which this applies. This is in addition to the ECI and data specified using the --eci and -d options which must still be present and which in effect constitute segment 0. For instance

    -
    zint -b AZTEC_CODE --eci=9 -d "Κείμενο" --seg1=7,"Текст" --seg2=20,"文章"
    +
    zint -b AZTEC_CODE --eci=9 -d "Κείμενο" --seg1=7,"Текст" --seg2=20,"文章"

    specifies 3 segments: segment 0 with ECI 9 (Greek), segment 1 with ECI 7 (Cyrillic), and segment 2 with ECI 20 (Shift JIS). Segments must be consecutive.

    @@ -3341,8 +3361,8 @@ Data Matrix, DotCode, Grid Matrix, MaxiCode, MicroPDF417, PDF417, QR Code and Ultracode.

    The --structapp option marks a symbol as part of a Structured Append sequence, and has the format

    -
    --structapp=I,C[,ID]
    +
    --structapp=I,C[,ID]
    zint -b DATAMATRIX -d "2nd of 3" --structapp="2,3,5006" @@ -3400,22 +3420,22 @@ These symbol structures are created with the ZBarcode_Create() function and deleted using the ZBarcode_Delete() function. For example the following code creates and then deletes a symbol:

    -
    #include <zint.h>
    -#include <stdio.h>
    -int main()
    -{
    -    struct zint_symbol *symbol;
    -    symbol = ZBarcode_Create();
    -    if (symbol != NULL) {
    -        printf("Symbol successfully created!\n");
    -        ZBarcode_Delete(symbol);
    -    }
    -    return 0;
    -}
    +
    #include <zint.h>
    +#include <stdio.h>
    +int main()
    +{
    +    struct zint_symbol *symbol;
    +    symbol = ZBarcode_Create();
    +    if (symbol != NULL) {
    +        printf("Symbol successfully created!\n");
    +        ZBarcode_Delete(symbol);
    +    }
    +    return 0;
    +}

    When compiling this code it will need to be linked with the libzint library using the -lzint option:

    -
    gcc -o simple simple.c -lzint
    +
    gcc -o simple simple.c -lzint

    5.2 Encoding and Saving to File

    To encode data in a barcode use the ZBarcode_Encode() @@ -3423,30 +3443,30 @@ function. To write the symbol to a file use the ZBarcode_Print() function. For example the following code takes a string from the command line and outputs a Code 128 symbol to a PNG file named "out.png" (or a GIF file -"out.gif" if libpng is not present) in the -current working directory:

    -
    #include <zint.h>
    -int main(int argc, char **argv)
    -{
    -    struct zint_symbol *symbol;
    -    symbol = ZBarcode_Create();
    -    ZBarcode_Encode(symbol, argv[1], 0);
    -    ZBarcode_Print(symbol, 0);
    -    ZBarcode_Delete(symbol);
    -    return 0;
    -}
    +"out.gif" if Zint not built with libpng) in +the current working directory:

    +
    #include <zint.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_symbol *symbol;
    +    symbol = ZBarcode_Create();
    +    ZBarcode_Encode(symbol, argv[1], 0);
    +    ZBarcode_Print(symbol, 0);
    +    ZBarcode_Delete(symbol);
    +    return 0;
    +}

    This can also be done in one stage using the ZBarcode_Encode_and_Print() function as shown in the next example:

    -
    #include <zint.h>
    -int main(int argc, char **argv)
    -{
    -    struct zint_symbol *symbol;
    -    symbol = ZBarcode_Create();
    -    ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    -    ZBarcode_Delete(symbol);
    -    return 0;
    -}
    +
    #include <zint.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_symbol *symbol;
    +    symbol = ZBarcode_Create();
    +    ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    +    ZBarcode_Delete(symbol);
    +    return 0;
    +}

    Note that when using the API, the input data is assumed to be 8-bit binary unless the input_mode member of the zint_symbol structure is set - see

    5.3 Encoding and Printing Functions in Depth

    The functions for encoding and printing barcodes are defined as:

    -
    int ZBarcode_Encode(struct zint_symbol *symbol,
    -      const unsigned char *source, int length);
    -
    -int ZBarcode_Encode_File(struct zint_symbol *symbol,
    -      const char *filename);
    -
    -int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle);
    -
    -int ZBarcode_Encode_and_Print(struct zint_symbol *symbol,
    -      const unsigned char *source, int length, int rotate_angle);
    -
    -int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol,
    -      const char *filename, int rotate_angle);
    +
    int ZBarcode_Encode(struct zint_symbol *symbol,
    +      const unsigned char *source, int length);
    +
    +int ZBarcode_Encode_File(struct zint_symbol *symbol,
    +      const char *filename);
    +
    +int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle);
    +
    +int ZBarcode_Encode_and_Print(struct zint_symbol *symbol,
    +      const unsigned char *source, int length, int rotate_angle);
    +
    +int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol,
    +      const char *filename, int rotate_angle);

    In these definitions length can be used to set the length of the input string. This allows the encoding of NUL (ASCII 0) characters in those symbologies which allow this. A value of 0 @@ -3494,13 +3514,13 @@ Memory (raster)

    In addition to saving barcode images to file Zint allows you to access a representation of the resulting bitmap image in memory. The following functions allow you to do this:

    -
    int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle);
    -
    -int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol,
    -      const unsigned char *source, int length, int rotate_angle);
    -
    -int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol,
    -      const char *filename, int rotate_angle);
    +
    int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle);
    +
    +int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol,
    +      const unsigned char *source, int length, int rotate_angle);
    +
    +int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol,
    +      const char *filename, int rotate_angle);

    The arguments here are the same as above, and rotation and colour options can be used with the buffer functions in the same way as when saving to a file. The difference is that instead of saving the image to @@ -3522,23 +3542,23 @@ method shown in the example below, where render_rgb() and render_rgba() are assumed to be functions for drawing an RGB and RGBA pixel on the screen implemented by the client application:

    -
    int row, col, i = 0, j = 0;
    -
    -for (row = 0; row < symbol->bitmap_height; row++) {
    -     for (col = 0; col < symbol->bitmap_width; col++) {
    -          int red = (int) symbol->bitmap[i];
    -          int green = (int) symbol->bitmap[i + 1];
    -          int blue = (int) symbol->bitmap[i + 2];
    -          if (symbol->alphamap) {
    -              int alpha = (int) symbol->alphamap[j];
    -              render_rgba(row, col, red, green, blue, alpha);
    -              j++;
    -          } else {
    -              render_rgb(row, col, red, green, blue);
    -          }
    -          i += 3;
    -     }
    -}
    +
    int row, col, i = 0, j = 0;
    +
    +for (row = 0; row < symbol->bitmap_height; row++) {
    +     for (col = 0; col < symbol->bitmap_width; col++) {
    +          int red = (int) symbol->bitmap[i];
    +          int green = (int) symbol->bitmap[i + 1];
    +          int blue = (int) symbol->bitmap[i + 2];
    +          if (symbol->alphamap) {
    +              int alpha = (int) symbol->alphamap[j];
    +              render_rgba(row, col, red, green, blue, alpha);
    +              j++;
    +          } else {
    +              render_rgb(row, col, red, green, blue);
    +          }
    +          i += 3;
    +     }
    +}

    Where speed is important, the buffer can be returned instead in a more compact intermediate form using the output option OUT_BUFFER_INTERMEDIATE. Here each byte is an ASCII value: @@ -3550,26 +3570,26 @@ for blue, 'M' for magenta, 'R' for red, 'K' for black. Alpha values are not reported (alphamap will always be NULL). The loop for accessing the data is then:

    -
    int row, col, i = 0;
    -
    -for (row = 0; row < symbol->bitmap_height; row++) {
    -     for (col = 0; col < symbol->bitmap_width; col++) {
    -          render_pixel(row, col, symbol->bitmap[i]);
    -          i++;
    -     }
    -}
    +
    int row, col, i = 0;
    +
    +for (row = 0; row < symbol->bitmap_height; row++) {
    +     for (col = 0; col < symbol->bitmap_width; col++) {
    +          render_pixel(row, col, symbol->bitmap[i]);
    +          i++;
    +     }
    +}

    5.5 Buffering Symbols in Memory (vector)

    Symbols can also be saved to memory in a vector representation as well as a bitmap one. The following functions, exactly analogous to the ones above, allow you to do this:

    -
    int ZBarcode_Buffer_Vector(struct zint_symbol *symbol, int rotate_angle);
    -
    -int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol,
    -      const unsigned char *source, int length, int rotate_angle);
    -
    -int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol,
    -      const char *filename, int rotate_angle);
    +
    int ZBarcode_Buffer_Vector(struct zint_symbol *symbol, int rotate_angle);
    +
    +int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol,
    +      const unsigned char *source, int length, int rotate_angle);
    +
    +int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol,
    +      const char *filename, int rotate_angle);

    Here the vector member is set to point to a zint_vector header structure which contains pointers to lists of structures representing the various elements of the barcode: @@ -3580,30 +3600,30 @@ rendering system with prepare_canvas(), draw_rect(), draw_hexagon(), draw_string(), and draw_circle() routines available:

    -
    struct zint_vector_rect *rect;
    -struct zint_vector_hexagon *hex;
    -struct zint_vector_string *string;
    -struct zint_vector_circle *circle;
    -
    -prepare_canvas(symbol->vector->width, symbol->vector->height,
    -               symbol->scale, symbol->fgcolour, symbol->bgcolour,
    -               rotate_angle);
    -
    -for (rect = symbol->vector->rectangles; rect; rect = rect->next) {
    -    draw_rect(rect->x, rect->y, rect->width, rect->height,
    -              rect->colour);
    -}
    -for (hex = symbol->vector->hexagons; hex; hex = hex->next) {
    -    draw_hexagon(hex->x, hex->y, hex->diameter, hex->rotation);
    -}
    -for (string = symbol->vector->strings; string; string = string->next) {
    -    draw_string(string->x, string->y, string->fsize,
    -                string->rotation, string->halign,
    -                string->text, string->length);
    -}
    -for (circle = symbol->vector->circles; circle; circle = circle->next) {
    -    draw_circle(circle->x, circle->y, circle->diameter, circle->width);
    -}
    +
    struct zint_vector_rect *rect;
    +struct zint_vector_hexagon *hex;
    +struct zint_vector_string *string;
    +struct zint_vector_circle *circle;
    +
    +prepare_canvas(symbol->vector->width, symbol->vector->height,
    +               symbol->scale, symbol->fgcolour, symbol->bgcolour,
    +               rotate_angle);
    +
    +for (rect = symbol->vector->rectangles; rect; rect = rect->next) {
    +    draw_rect(rect->x, rect->y, rect->width, rect->height,
    +              rect->colour);
    +}
    +for (hex = symbol->vector->hexagons; hex; hex = hex->next) {
    +    draw_hexagon(hex->x, hex->y, hex->diameter, hex->rotation);
    +}
    +for (string = symbol->vector->strings; string; string = string->next) {
    +    draw_string(string->x, string->y, string->fsize,
    +                string->rotation, string->halign,
    +                string->text, string->length);
    +}
    +for (circle = symbol->vector->circles; circle; circle = circle->next) {
    +    draw_circle(circle->x, circle->y, circle->diameter, circle->width);
    +}

    5.6 Buffering Symbols in Memory (memfile)

    Symbols can also be stored as “in-memory” file buffers by giving the @@ -3612,26 +3632,26 @@ Memory (memfile) member memfile instead of to the output file outfile. The length of the buffer is given in memfile_size. For instance:

    -
    #include <zint.h>
    -#include <stdio.h>
    -#include <string.h>
    -int main(int argc, char **argv)
    -{
    -    struct zint_symbol *symbol;
    -    symbol = ZBarcode_Create();
    -    symbol->output_options |= BARCODE_MEMORY_FILE;
    -    /* Only the extension is used, to determine output format */
    -    strcpy(symbol->outfile, "mem.svg");
    -    ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    -    /* `symbol->memfile` now contains the SVG output */
    -    fwrite(symbol->memfile, 1, symbol->memfile_size, stdout);
    -    ZBarcode_Delete(symbol);
    -    return 0;
    -}
    +
    #include <zint.h>
    +#include <stdio.h>
    +#include <string.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_symbol *symbol;
    +    symbol = ZBarcode_Create();
    +    symbol->output_options |= BARCODE_MEMORY_FILE;
    +    /* Only the extension is used, to determine output format */
    +    strcpy(symbol->outfile, "mem.svg");
    +    ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    +    /* `symbol->memfile` now contains the SVG output */
    +    fwrite(symbol->memfile, 1, symbol->memfile_size, stdout);
    +    ZBarcode_Delete(symbol);
    +    return 0;
    +}

    will print the SVG output to stdout (the file "mem.svg" is not created). This is particularly useful for -the textual formats EPS and SVG,12 allowing the output to +the textual formats EPS and SVG,13 allowing the output to be manipulated and processed by the client.

    5.7 Setting Options

    So far our application is not very useful unless we plan to only make @@ -3670,8 +3690,8 @@ href="#specifying-a-symbology">5.9 Specifying a Symbology.

    height float Symbol height in X-dimensions, excluding -fixed width-to-height symbols.13 Symbol dependent
    "out.png"

    To catch errors use an integer variable as shown in the code below:

    -
    #include <zint.h>
    -#include <stdio.h>
    -#include <string.h>
    -int main(int argc, char **argv)
    -{
    -    struct zint_symbol *symbol;
    -    int error;
    -    symbol = ZBarcode_Create();
    -    /* Set invalid foreground colour */
    -    strcpy(symbol->fgcolour, "nonsense");
    -    error = ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    -    if (error != 0) {
    -        /* Some warning or error occurred */
    -        printf("%s\n", symbol->errtxt);
    -        if (error >= ZINT_ERROR) {
    -            /* Stop now */
    -            ZBarcode_Delete(symbol);
    -            return 1;
    -        }
    -    }
    -    /* Otherwise carry on with the rest of the application */
    -    ZBarcode_Delete(symbol);
    -    return 0;
    -}
    +
    #include <zint.h>
    +#include <stdio.h>
    +#include <string.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_symbol *symbol;
    +    int error;
    +    symbol = ZBarcode_Create();
    +    /* Set invalid foreground colour */
    +    strcpy(symbol->fgcolour, "nonsense");
    +    error = ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    +    if (error != 0) {
    +        /* Some warning or error occurred */
    +        printf("%s\n", symbol->errtxt);
    +        if (error >= ZINT_ERROR) {
    +            /* Stop now */
    +            ZBarcode_Delete(symbol);
    +            return 1;
    +        }
    +    }
    +    /* Otherwise carry on with the rest of the application */
    +    ZBarcode_Delete(symbol);
    +    return 0;
    +}

    This code will exit with the appropriate message:

    Error 881: Malformed foreground RGB colour 'nonsense' (hexadecimal only)

    To treat all warnings as errors, set @@ -4129,13 +4149,13 @@ below:

    class="cross-ref-group">Table 5: Barcode Types (Symbologies). For example

    -
    symbol->symbology = BARCODE_LOGMARS;
    +
    symbol->symbology = BARCODE_LOGMARS;

    5.10 Adjusting Output Options

    The output_options member can be used to adjust various aspects of the output file. To select more than one option from the table below simply OR them together when adjusting this value:

    -
    symbol->output_options |= BARCODE_BIND | READER_INIT;
    +
    symbol->output_options |= BARCODE_BIND | READER_INIT;
    @@ -4157,15 +4177,15 @@ value:

    +href="#fn16" class="footnote-ref" id="fnref16" +role="doc-noteref">16 +and between rows if stacking multiple symbols.17 @@ -4215,8 +4235,8 @@ Memory (raster). +any specified whitespace).18 @@ -4348,11 +4368,11 @@ CLI and GUI, which is UNICODE_MODE.)

    FAST_MODE, EXTRA_ESCAPE_MODE, GS1SYNTAXENGINE_MODE and GS1RAW_MODE are optional. So, for example, you can set

    -
    symbol->input_mode = UNICODE_MODE | ESCAPE_MODE;
    +
    symbol->input_mode = UNICODE_MODE | ESCAPE_MODE;

    or

    -
    symbol->input_mode = GS1_MODE | GS1PARENS_MODE | GS1NOCHECK_MODE;
    +
    symbol->input_mode = GS1_MODE | GS1PARENS_MODE | GS1NOCHECK_MODE;

    whereas

    -
    symbol->input_mode = DATA_MODE | GS1_MODE;
    +
    symbol->input_mode = DATA_MODE | GS1_MODE;

    is not valid.

    Permissible escape sequences (ESCAPE_MODE) are listed in 6.6.3 QR Code (ISO 18004) for details.

    5.12 Multiple Segments

    For input data requiring multiple ECIs, the following functions may be used:

    -
    int ZBarcode_Encode_Segs(struct zint_symbol *symbol,
    -      const struct zint_seg segs[], const int seg_count);
    -
    -int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol,
    -      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    -
    -int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol,
    -      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    -
    -int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol,
    -      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    +
    int ZBarcode_Encode_Segs(struct zint_symbol *symbol,
    +      const struct zint_seg segs[], const int seg_count);
    +
    +int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol,
    +      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    +
    +int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol,
    +      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    +
    +int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol,
    +      const struct zint_seg segs[], const int seg_count, int rotate_angle);

    These are direct analogues of the previously mentioned ZBarcode_Encode(), ZBarcode_Encode_and_Print(), @@ -4400,44 +4420,44 @@ consisting of "segs, seg_count" is given, with segs being an array of struct zint_seg segments and seg_count being the number of elements it contains. The zint_seg structure is of the form:

    -
    struct zint_seg {
    -    unsigned char *source; /* Data to encode */
    -    int length;            /* Length of `source`. If 0 or negative, `source`
    -                              must be NUL-terminated */
    -    int eci;               /* Extended Channel Interpretation */
    -};
    +
    struct zint_seg {
    +    unsigned char *source; /* Data to encode */
    +    int length;            /* Length of `source`. If 0 or negative, `source`
    +                              must be NUL-terminated */
    +    int eci;               /* Extended Channel Interpretation */
    +};

    The symbology must support ECIs (see Table 8: ECI-Aware Symbologies). For example:

    -
    #include <zint.h>
    -int main(int argc, char **argv)
    -{
    -    struct zint_seg segs[] = {
    -        { "Κείμενο", 0, 9 },
    -        { "Текст", 0, 7 },
    -        { "文章", 0, 20 }
    -    };
    -    struct zint_symbol *symbol;
    -    symbol = ZBarcode_Create();
    -    symbol->symbology = BARCODE_AZTEC;
    -    symbol->input_mode = UNICODE_MODE;
    -    ZBarcode_Encode_Segs(symbol, segs, 3);
    -    ZBarcode_Print(symbol, 0);
    -    ZBarcode_Delete(symbol);
    -    return 0;
    -}
    +
    #include <zint.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_seg segs[] = {
    +        { "Κείμενο", 0, 9 },
    +        { "Текст", 0, 7 },
    +        { "文章", 0, 20 }
    +    };
    +    struct zint_symbol *symbol;
    +    symbol = ZBarcode_Create();
    +    symbol->symbology = BARCODE_AZTEC;
    +    symbol->input_mode = UNICODE_MODE;
    +    ZBarcode_Encode_Segs(symbol, segs, 3);
    +    ZBarcode_Print(symbol, 0);
    +    ZBarcode_Delete(symbol);
    +    return 0;
    +}

    A maximum of 256 segments may be specified. Use of multiple segments with GS1 data is not currently supported.

    5.13 Scaling Helpers

    To help with scaling the output, the following three function are available:

    -
    float ZBarcode_Default_Xdim(int symbol_id);
    -
    -float ZBarcode_Scale_From_XdimDp(int symbol_id, float x_dim_mm, float dpmm,
    -        const char *filetype);
    -
    -float ZBarcode_XdimDP_From_Scale(int symbol_id, float scale,
    -        float x_dim_mm_or_dpmm, const char *filetype);
    +
    float ZBarcode_Default_Xdim(int symbol_id);
    +
    +float ZBarcode_Scale_From_XdimDp(int symbol_id, float x_dim_mm, float dpmm,
    +        const char *filetype);
    +
    +float ZBarcode_XdimDP_From_Scale(int symbol_id, float scale,
    +        float x_dim_mm_or_dpmm, const char *filetype);

    The first ZBarcode_Default_Xdim() returns the default X-dimension suggested by Zint for symbology symbol_id.

    The second ZBarcode_Scale_From_XdimDp() returns the @@ -4449,13 +4469,13 @@ however dpmm may be zero and defaults to 12 dpmm, and is assumed. For raster output (BMP/GIF/PCX/PNG/TIF) the scale is rounded to half-integer increments.

    For example:

    -
    /* Royal Mail 4-State Customer Code */
    -symbol->symbology = BARCODE_RM4SCC;
    -symbol->dpmm = 600.0f / 25.4f; /* 600 dpi */
    -symbol->scale = ZBarcode_Scale_From_XdimDp(
    -                        symbol->symbology,
    -                        ZBarcode_Default_Xdim(symbol->symbology),
    -                        symbol->dpmm, "PNG"); /* Returns 7.5 */
    +
    /* Royal Mail 4-State Customer Code */
    +symbol->symbology = BARCODE_RM4SCC;
    +symbol->dpmm = 600.0f / 25.4f; /* 600 dpi */
    +symbol->scale = ZBarcode_Scale_From_XdimDp(
    +                        symbol->symbology,
    +                        ZBarcode_Default_Xdim(symbol->symbology),
    +                        symbol->dpmm, "PNG"); /* Returns 7.5 */

    The third function ZBarcode_XdimDP_From_Scale() is the “reverse” of ZBarcode_Scale_From_XdimDp(), returning the X-dimension (in mm) or the dot density (in dpmm) given a scale @@ -4470,30 +4490,30 @@ the type of scanner used, the intended scanning distance, and what media

    5.14 Verifying Symbology Availability

    An additional function available in the API is:

    -
    int ZBarcode_ValidID(int symbol_id);
    +
    int ZBarcode_ValidID(int symbol_id);

    which allows you to check whether a given symbology is available, returning a non-zero value if so. For example:

    -
    if (ZBarcode_ValidID(BARCODE_PDF417) != 0) {
    -    printf("PDF417 available\n");
    -} else {
    -    printf("PDF417 not available\n");
    -}
    +
    if (ZBarcode_ValidID(BARCODE_PDF417) != 0) {
    +    printf("PDF417 available\n");
    +} else {
    +    printf("PDF417 not available\n");
    +}

    Another function that may be useful is:

    -
    int ZBarcode_BarcodeName(int symbol_id, char name[32]);
    +
    int ZBarcode_BarcodeName(int symbol_id, char name[32]);

    which copies the name of a symbology into the supplied name buffer, which should be 32 characters in length. The name is NUL-terminated, and zero is returned on success. For instance:

    -
    char name[32];
    -if (ZBarcode_BarcodeName(BARCODE_PDF417, name) == 0) {
    -    printf("%s\n", name);
    -}
    +
    char name[32];
    +if (ZBarcode_BarcodeName(BARCODE_PDF417, name) == 0) {
    +    printf("%s\n", name);
    +}

    will print “BARCODE_PDF417”.

    5.15 Checking Symbology Capabilities

    It can be useful for frontend programs to know the capabilities of a symbology. This can be determined using another additional function:

    -
    unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag);
    +
    unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag);

    by OR-ing the flags below in the cap_flag argument and checking the return to see which are set.

    Table 16: API output_options Values
    BARCODE_BIND_TOP Boundary bar above the symbol only.15
    BARCODE_BIND Boundary bars above and below the symbol -and between rows if stacking multiple symbols.16
    BARCODE_BOX
    BARCODE_QUIET_ZONES Add compliant quiet zones (additional to -any specified whitespace).17
    BARCODE_NO_QUIET_ZONES
    @@ -4522,8 +4542,8 @@ stacked symbologies are not stackable. +href="#fn19" class="footnote-ref" id="fnref19" +role="doc-noteref">19 @@ -4590,26 +4610,26 @@ symbologies.
    ZINT_CAP_EANUPC18 Is the symbology EAN/UPC?

    For example:

    -
    unsigned int cap;
    -cap = ZBarcode_Cap(BARCODE_PDF417, ZINT_CAP_HRT | ZINT_CAP_ECI);
    -if (cap & ZINT_CAP_HRT) {
    -    printf("PDF417 supports HRT\n");
    -} else {
    -    printf("PDF417 does not support HRT\n");
    -}
    -if (cap & ZINT_CAP_ECI) {
    -    printf("PDF417 supports ECI\n");
    -} else {
    -    printf("PDF417 does not support ECI\n");
    -}
    +
    unsigned int cap;
    +cap = ZBarcode_Cap(BARCODE_PDF417, ZINT_CAP_HRT | ZINT_CAP_ECI);
    +if (cap & ZINT_CAP_HRT) {
    +    printf("PDF417 supports HRT\n");
    +} else {
    +    printf("PDF417 does not support HRT\n");
    +}
    +if (cap & ZINT_CAP_ECI) {
    +    printf("PDF417 supports ECI\n");
    +} else {
    +    printf("PDF417 does not support ECI\n");
    +}

    5.16 Feedback

    On successful encodation (after using ZBarcode_Encode() etc.) the option_1, option_2 and option_3 members will be set to the values used by Zint to create the barcode. This is useful for feedback if the values were left as defaults or were overridden by Zint.

    -

    In particular for symbologies that have masks,19 +

    In particular for symbologies that have masks,20 option_3 will contain the mask used as (N + 1) << 8, N being the mask. Also Aztec Code will return the actual ECC percentage used in option_1 as @@ -4633,8 +4653,8 @@ members of zint_seg will be set accordingly - the unconverted data in source, the data length in length, and the character set the data was converted to in eci. Any check characters encoded will be included,20 and for GS1 data any +href="#fn21" class="footnote-ref" id="fnref21" +role="doc-noteref">21 and for GS1 data any FNC1 separators will be represented as GS (ASCII 29) characters. UPC-A and UPC-E data will be expanded to EAN-13, as will EAN-8 but only if it has an add-on (otherwise it will remain at @@ -4651,15 +4671,15 @@ member using the two helper functions discussed next.

    convenience functions

    As a convenience the conversion done by Zint from UTF-8 to ECIs is exposed in two helper functions (compatible with the -libzueci21 functions +libzueci22 functions zueci_utf8_to_eci() and zueci_dest_len_eci()):

    -
    int ZBarcode_UTF8_To_ECI(int eci, const unsigned char *source, int length,
    -      unsigned char dest[], int *p_dest_length);
    -
    -int ZBarcode_Dest_Len_ECI(int eci, const unsigned char *source, int length,
    -      int *p_dest_length);
    +
    int ZBarcode_UTF8_To_ECI(int eci, const unsigned char *source, int length,
    +      unsigned char dest[], int *p_dest_length);
    +
    +int ZBarcode_Dest_Len_ECI(int eci, const unsigned char *source, int length,
    +      int *p_dest_length);

    Call ZBarcode_Dest_Len_ECI() to get the size of buffer sufficient to accommodate the conversion, then call ZBarcode_UTF8_To_ECI() with an appropriately sized buffer @@ -4671,17 +4691,17 @@ is not NUL-terminated. The obsolete ECIs 0, 1 and 2 are supported.

    5.18 Zint Version

    Whether the Zint library was built without PNG support may be determined with:

    -
    int ZBarcode_NoPng(void);
    +
    int ZBarcode_NoPng(void);

    which returns 1 if PNG support is not available, else zero.

    Similarly, but with opposite sense, whether the Zint library was built with GS1 Syntax Engine support may be determined with:

    -
    int ZBarcode_HaveGS1SyntaxEngine(void);
    +
    int ZBarcode_HaveGS1SyntaxEngine(void);

    which returns 1 if GS1 Syntax Engine support is available, else zero.

    Lastly, the version of the Zint library linked to is returned by:

    -
    int ZBarcode_Version(void);
    +
    int ZBarcode_Version(void);

    The version parts are separated by hundreds. For instance, version "2.9.1" is returned as "20901".

    5.19 Debug Info

    @@ -4759,9 +4779,9 @@ entered a leading zero is added by Zint. A maximum of 62 pairs (124 digits) can be encoded.

    +alt="zint -b C25INTER --compliant -d "9212320967"" />
    Figure 33: -zint -b C25INTER --compliantheight -d "9212320967"
    +zint -b C25INTER --compliant -d "9212320967"

    No check digit is added by default, but can be set the same as for 6.1.2.1 Standard Code 2 of 5.

    @@ -4785,9 +4805,9 @@ check digit is given, in which case the check digit will be verified. A standard GS1 check digit is added by Zint unless already given.

    +alt="zint -b ITF14 --compliant -d "9212320967145"" />
    Figure 35: -zint -b ITF14 --compliantheight -d "9212320967145"
    +zint -b ITF14 --compliant -d "9212320967145"

    If no border option is specified Zint defaults to adding a bounding box with a border width of 5. This behaviour can be overridden by using @@ -4799,9 +4819,9 @@ can be achieved by explicitly setting the border type to box (or bind or bindtop) and leaving the border width 0.

    +alt="zint -b ITF14 --box --compliant -d "9212320967145"" />
    Figure 36: -zint -b ITF14 --box --compliantheight -d "9212320967145"
    +zint -b ITF14 --box --compliant -d "9212320967145"

    6.1.2.7 Deutsche Post Leitcode

    Leitcode is based on Interleaved Code 2 of 5 and is used by Deutsche @@ -4831,9 +4851,9 @@ encodes a GTIN-12, a 12-digit Global Trade Item Number that includes a standard GS1 check digit.

    +alt="zint -b UPCA --compliant -d "01234500005"" />
    Figure 39: -zint -b UPCA --compliantheight -d "01234500005"
    +zint -b UPCA --compliant -d "01234500005"

    Input up to 11 digits may be given, to which a check digit will be added by Zint. A 12-digit input including the check digit may also be @@ -4845,35 +4865,36 @@ zero-filled.

    data separated from the main data by a '+' character or a space. For example, to draw a UPC-A symbol with the data “01234500005” and 5-digit add-on data “12345” use the command:

    -
    zint -b UPCA -d "01234500005+12345"
    +
    zint -b UPCA -d "01234500005+12345"

    or using the API:

    -
    symbol->symbology = BARCODE_UPCA;
    -/* Using '+' */
    -error = ZBarcode_Encode_and_Print(symbol, "01234500005+12345", 0, 0);
    -/* Or a space */
    -error = ZBarcode_Encode_and_Print(symbol, "01234500005 12345", 0, 0);
    +
    symbol->symbology = BARCODE_UPCA;
    +/* Using '+' */
    +error = ZBarcode_Encode_and_Print(symbol, "01234500005+12345", 0, 0);
    +/* Or a space */
    +error = ZBarcode_Encode_and_Print(symbol, "01234500005 12345", 0, 0);
    +alt="zint -b UPCA --compliant -d "01234500005+12345"" />
    Figure 40: -zint -b UPCA --compliantheight -d "01234500005+12345"
    +zint -b UPCA --compliant -d "01234500005+12345"

    A quiet zone indicator can be added to the HRT by setting --guardwhitespace (API output_options |= EANUPC_GUARD_WHITESPACE). For UPC, this is only relevant when there is an add-on:

    -
    zint -b UPCA -d "01234500005+12345" --guardwhitespace
    +
    zint -b UPCA -d "01234500005+12345" --guardwhitespace

    or using the API:

    -
    symbol->symbology = BARCODE_UPCA;
    -symbol->output_options |= EANUPC_GUARD_WHITESPACE;
    -error = ZBarcode_Encode_and_Print(symbol, "01234500005+12345", 0, 0);
    +
    symbol->symbology = BARCODE_UPCA;
    +symbol->output_options |= EANUPC_GUARD_WHITESPACE;
    +error = ZBarcode_Encode_and_Print(symbol, "01234500005+12345", 0, 0);
    +alt="zint -b UPCA --compliant -d "01234500005+12345" --guardwhitespace" />
    Figure 41: -zint -b UPCA --compliantheight -d "01234500005+12345" --guardwhitespace
    +zint -b UPCA --compliant -d "01234500005+12345" --guardwhitespace

    You can adjust the gap between the main symbol and an add-on in integral multiples of the X-dimension by setting --addongap @@ -4890,9 +4911,9 @@ be ‘0’ or ‘1’ (the latter is known as number system 1 and is non-standard). Input less than 7 digits will be zero-filled.

    +alt="zint -b UPCE --compliant -d "123455"" />
    Figure 42: -zint -b UPCE --compliantheight -d "123455"
    +zint -b UPCE --compliant -d "123455"

    An 8-digit input including the check digit may also be supplied, in which case Zint will verify the check digit, or the symbology @@ -4903,13 +4924,13 @@ a '+' character or a space as a separator, and a quiet zone indicator can be added when there is an add-on by setting --guardwhitespace (API output_options |= EANUPC_GUARD_WHITESPACE):

    -
    zint -b UPCE -d "123455+12" --guardwhitespace
    +
    zint -b UPCE -d "123455+12" --guardwhitespace
    +alt="zint -b UPCE --compliant -d "123455+12" --guardwhitespace" />
    Figure 43: -zint -b UPCE --compliantheight -d "123455+12" --guardwhitespace
    +zint -b UPCE --compliant -d "123455+12" --guardwhitespace

    You can adjust the gap between the main symbol and an add-on in integral multiples of the X-dimension by setting --addongap @@ -4929,9 +4950,9 @@ defines the symbologies EAN-13, EAN-8 and ISBN (a subset of EAN-13).

    includes a standard GS1 check digit.

    +alt="zint -b EAN13 --compliant -d "952012345678"" />
    Figure 44: -zint -b EAN13 --compliantheight -d "952012345678"
    +zint -b EAN13 --compliant -d "952012345678"

    Input up to 12 digits may be given, to which a check digit will be added by Zint, or a 13-digit input can be supplied in which case Zint @@ -4939,39 +4960,38 @@ will validate the check digit. Input less than 12 digits will be zero-filled.

    A 2-digit or 5-digit add-on can be added by using a ‘+’ or space character as with UPC symbols. For example:

    -
    zint -b EAN13 -d "952012345678+21"
    +
    zint -b EAN13 -d "952012345678+21"

    will encode an EAN-13 symbol with a 2-digit add-on. As before these results can be achieved using the API:

    -
    symbol->symbology = BARCODE_EAN13;
    -error = ZBarcode_Encode_and_Print(symbol, "952012345678+21", 0, 0);
    +
    symbol->symbology = BARCODE_EAN13;
    +error = ZBarcode_Encode_and_Print(symbol, "952012345678+21", 0, 0);
    +alt="zint -b EAN13 --compliant -d "952012345678+21"" />
    Figure 45: -zint -b EAN13 --compliantheight -d "952012345678+21"
    +zint -b EAN13 --compliant -d "952012345678+21"

    Options to add quiet zone indicators and to adjust the add-on gap and the guard bar descent height are the same as for 6.1.3.2 UPC Version E. For instance:

    -
    zint -b EAN13 -d "9520123456788" --guarddescent=2.5 --guardwhitespace
    +
    zint -b EAN13 -d "9520123456788" --guarddescent=2.5 --guardwhitespace
    +alt="zint -b EAN13 --compliant -d "9520123456788" --guarddescent=2.5 --guardwhitespace" />
    Figure 46: -zint -b EAN13 --compliantheight -d "9520123456788" -–guarddescent=2.5 –guardwhitespace
    +zint -b EAN13 --compliant -d "9520123456788" --guarddescent=2.5 --guardwhitespace

    6.1.4.2 EAN-8

    EAN-8 is a shortened version of EAN-13, encoding a GTIN-8 (a GTIN-13 with 5 leading zeroes implied), for use with small packages.

    +alt="zint -b EAN8 --compliant -d "9520000"" />
    Figure 47: -zint -b EAN8 --compliantheight -d "9520000"
    +zint -b EAN8 --compliant -d "9520000"

    Input up to 7 digits may be supplied, to which Zint will add a standard GS1 check digit. An 8-digit input including the check digit may @@ -4980,18 +5000,18 @@ less than 7 digits will be zero-filled.

    Options to add quiet zone indicators and to adjust the guard bar descent height are the same as for 6.1.3.2 UPC Version E. For instance:

    -
    zint -b EAN8 -d "9520000" --guardwhitespace
    +
    zint -b EAN8 -d "9520000" --guardwhitespace

    or using the API:

    -
    symbol->symbology = BARCODE_EAN8;
    -symbol->output_options |= EANUPC_GUARD_WHITESPACE;
    -error = ZBarcode_Encode_and_Print(symbol, "9520000", 0, 0);
    +
    symbol->symbology = BARCODE_EAN8;
    +symbol->output_options |= EANUPC_GUARD_WHITESPACE;
    +error = ZBarcode_Encode_and_Print(symbol, "9520000", 0, 0);
    +alt="zint -b EAN8 --compliant -d "9520000" –guardwhitespace" />
    Figure 48: -zint -b EAN8 --compliantheight -d "9520000" +zint -b EAN8 --compliant -d "9520000" –guardwhitespace

    2-digit and 5-digit add-ons may also be added, and the gap adjusted, @@ -5005,17 +5025,17 @@ check digit needs to be present in the input data and will be verified before the symbol is generated.

    +alt="zint -b ISBNX --compliant -d "9789295055124"" />
    Figure 49: -zint -b ISBNX --compliantheight -d "9789295055124"
    +zint -b ISBNX --compliant -d "9789295055124"

    As with EAN-13, a quiet zone indicator can be added using --guardwhitespace:

    +alt="zint -b ISBNX --compliant -d "9789295055124" --guardwhitespace" />
    Figure 50: -zint -b ISBNX --compliantheight -d "9789295055124" --guardwhitespace
    +zint -b ISBNX --compliant -d "9789295055124" --guardwhitespace

    2-digit and 5-digit add-on symbols can be added using a + or space character, and there are options to adjust the @@ -5028,25 +5048,25 @@ standalone symbols using the symbologies BARCODE_EAN_2ADDON (11) and BARCODE_EAN_5ADDON (12).

    +alt="zint -b EAN_2ADDON --compliant -d "12"" />
    Figure 51: -zint -b EAN_2ADDON --compliantheight -d "12"
    +zint -b EAN_2ADDON --compliant -d "12"

    As with the main EAN/UPC symbols a quiet zone indicator can be added using ---guardwhitespace. For instance

    -
    zint -b EAN_5ADDON -d "54321" --guardwhitespace
    +
    zint -b EAN_5ADDON -d "54321" --guardwhitespace

    will generate a standalone 5-digit add-on with quiet zone guards, or using the API:

    -
    symbol->symbology = BARCODE_EAN_5ADDON;
    -symbol->output_options |= EANUPC_GUARD_WHITESPACE;
    -error = ZBarcode_Encode_and_Print(symbol, "54321", 0, 0);
    +
    symbol->symbology = BARCODE_EAN_5ADDON;
    +symbol->output_options |= EANUPC_GUARD_WHITESPACE;
    +error = ZBarcode_Encode_and_Print(symbol, "54321", 0, 0);
    +alt="zint -b EAN_5ADDON --compliant -d "54321" –guardwhitespace" />
    Figure 52: -zint -b EAN_5ADDON --compliantheight -d "54321" +zint -b EAN_5ADDON --compliant -d "54321" –guardwhitespace

    6.1.5 Plessey

    @@ -5127,9 +5147,9 @@ and can encode ASCII text input, up to a maximum of 69 characters. Telepen includes a hidden modulo-127 check digit, added by Zint.

    +alt="zint -b TELEPEN --compliant -d "Z8000"" />
    Figure 55: -zint -b TELEPEN --compliantheight -d "Z8000"
    +zint -b TELEPEN --compliant -d "Z8000"

    AIM-defined Start/Stop characters may be enabled by setting --vers=1 (API option_2 = 1). In this mode @@ -5139,9 +5159,9 @@ Numeric, where each symbol character encodes a digit pair (or a “digit X” pair - see Telepen Numeric below):

    +alt="zint -b TELEPEN --compliant -d "Z\L8000" -esc --vers=1" />
    Figure 56: -zint -b TELEPEN --compliantheight -d "Z\L8000" -esc --vers=1
    +zint -b TELEPEN --compliant -d "Z\L8000" -esc --vers=1

    However not all barcode readers recognise this mode so check before using.

    @@ -5155,26 +5175,26 @@ digits is supplied, Zint will add a leading zero. Up to 138 digits can be encoded. A hidden modulo-127 check digit is added by Zint.

    +alt="zint -b TELEPEN_NUM --compliant -d "466X33"" />
    Figure 57: -zint -b TELEPEN_NUM --compliantheight -d "466X33"
    +zint -b TELEPEN_NUM --compliant -d "466X33"

    Additionally trailing ASCII characters may be encoded by prefixing them with a DLE control character (ASCII 16, escape sequence \L) and appending them to the numeric data:

    +alt="zint -b TELEPEN_NUM --compliant -d "12\LAB" --esc" />
    Figure 58: -zint -b TELEPEN_NUM --compliantheight -d "12\LAB" --esc
    +zint -b TELEPEN_NUM --compliant -d "12\LAB" --esc

    This method allows odd numbers to be encoded without a leading zero:

    +alt="zint -b TELEPEN_NUM --compliant -d "123\L4" --esc" />
    Figure 59: -zint -b TELEPEN_NUM --compliantheight -d "123\L4" --esc
    +zint -b TELEPEN_NUM --compliant -d "123\L4" --esc

    AIM-defined Start/Stop characters may be enabled by setting --vers=1 (API option_2 = 1). This allows @@ -5192,9 +5212,9 @@ A-Z, dash (-), full stop (.), space, asterisk (+) and percent (%).

    +alt="zint -b CODE39 --compliant -d "1A" --vers=1" />
    Figure 60: -zint -b CODE39 --compliantheight -d "1A" --vers=1
    +zint -b CODE39 --compliant -d "1A" --vers=1

    The standard does not require a check digit but a modulo-43 check digit can be added if desired by setting --vers=1 (API @@ -5207,9 +5227,9 @@ Standard Code 39 to provide support for the full 7-bit ASCII character set.

    +alt="zint -b EXCODE39 --compliant -d "123.45#@fd"" />
    Figure 61: -zint -b EXCODE39 --compliantheight -d "123.45#@fd"
    +zint -b EXCODE39 --compliant -d "123.45#@fd"

    The check digit options are the same as for 6.1.7.1 Standard Code 39 (ISO @@ -5222,9 +5242,9 @@ Readable Text, but may be shown by setting --vers=1 (API option_2 = 1).

    +alt="zint -b CODE93 --compliant -d "C93"" />
    Figure 62: -zint -b CODE93 --compliantheight -d "C93"
    +zint -b CODE93 --compliant -d "C93"

    6.1.7.4 PZN (Pharmazentralnummer)

    PZN is a Code 39 based symbology used by the pharmaceutical industry @@ -5234,9 +5254,9 @@ zero-filled. An 8-digit input can be supplied in which case Zint will validate the check digit.

    +alt="zint -b PZN --compliant -d "2758089"" />
    Figure 63: -zint -b PZN --compliantheight -d "2758089"
    +zint -b PZN --compliant -d "2758089"

    To encode a PZN7 (obsolete since 2013) instead set --vers=1 (API option_2 = 1) and supply up to 7 @@ -5251,9 +5271,9 @@ href="#standard-code-39-iso-16388">6.1.7.1 Standard Code 39 (ISO restricted to a maximum of 30 characters.

    +alt="zint -b LOGMARS --compliant -d "12345/ABCDE" --vers=1" />
    Figure 64: -zint -b LOGMARS --compliantheight -d "12345/ABCDE" --vers=1
    +zint -b LOGMARS --compliant -d "12345/ABCDE" --vers=1

    6.1.7.6 Code 32

    A variation of Code 39 used by the Italian Ministry of Health @@ -5262,9 +5282,9 @@ products. This symbology requires a numeric input up to 8 digits in length. A check digit is added by Zint.

    +alt="zint -b CODE32 --compliant -d "14352312"" />
    Figure 65: -zint -b CODE32 --compliantheight -d "14352312"
    +zint -b CODE32 --compliant -d "14352312"

    6.1.7.7 HIBC Code 39

    This variant adds a leading '+' character and a trailing @@ -5272,9 +5292,9 @@ modulo-49 check digit to a standard Code 39 symbol as required by the Health Industry Barcode standards.

    +alt="zint -b HIBC_39 --compliant -d "14352312"" />
    Figure 66: -zint -b HIBC_39 --compliantheight -d "14352312"
    +zint -b HIBC_39 --compliant -d "14352312"

    6.1.7.8 Vehicle Identification Number (VIN)

    @@ -5299,9 +5319,9 @@ American Blood Commission adopted Codabar in 1979 as the standard barcode for blood products.

    +alt="zint -b CODABAR --compliant -d "A37859B"" />
    Figure 68: -zint -b CODABAR --compliantheight -d "A37859B"
    +zint -b CODABAR --compliant -d "A37859B"

    Codabar can encode up to 103 characters starting and ending with the letters A-D and containing between these letters the numbers 0-9, dash @@ -5319,9 +5339,9 @@ identification of pharmaceuticals. The symbology is able to encode whole numbers between 3 and 131070.

    +alt="zint -b PHARMA --compliant -d "130170"" />
    Figure 69: -zint -b PHARMA --compliantheight -d "130170"
    +zint -b PHARMA --compliant -d "130170"

    6.1.10 Code 128

    6.1.10.1 Standard Code 128 (ISO @@ -5349,23 +5369,23 @@ processing normal escape sequences also processes the extra escape sequences given in Table 3: Extra Escape Sequences. For instance

    -
    zint -b CODE128 -d "A\^1BC\^1DEF" --extraesc
    +
    zint -b CODE128 -d "A\^1BC\^1DEF" --extraesc

    encodes the data "A<FNC1>BC<FNC1>DEF", where <FNC1> represents the FNC1 character.

    If the data contains an extra escape sequence, it can be escaped by doubling the caret (^). For instance

    -
    zint -b CODE128 -d "A\^1BC\^^1DEF" --extraesc
    +
    zint -b CODE128 -d "A\^1BC\^^1DEF" --extraesc

    will encode the data "A<FNC1>BC\^1DEF".

    Manual switching of Code Sets is possible using the Code 128-specific extra escapes \^A, \^B, \^C and \^@ (the latter turns off manual Code Set selection). For instance the following will force switching to Code Set B for the data "5678" (normally Code Set C would be used throughout):

    -
    zint -b CODE128 -d "1234\^B5678" --extraesc
    +
    zint -b CODE128 -d "1234\^B5678" --extraesc

    The manually selected Code Set will apply until the next Code Set escape sequence or until a \^@, with the exception that data that cannot be represented in that Code Set will be switched as @@ -5377,8 +5397,8 @@ digits (60 alphanumerics) are not recommended.

    Code 128 Suppress Code Set C (Code Sets A and B only)

    It is sometimes advantageous to stop Code 128 from using Code Set C which compresses numerical data. The BARCODE_CODE128AB22 variant (symbology 60) suppresses +href="#fn23" class="footnote-ref" id="fnref23" +role="doc-noteref">23 variant (symbology 60) suppresses Code Set C in favour of Code Sets A and B.

    4.11.3.1 GS1 Data Entry. Here we will use the square bracket format.

    +alt="zint -b GS1_128 --compliant -d "[01]98898765432106[3202]012345[15]991231"" />
    Figure 72: -zint -b GS1_128 --compliantheight -d "[01]98898765432106[3202]012345[15]991231"
    +zint -b GS1_128 --compliant -d "[01]98898765432106[3202]012345[15]991231"

    Fixed length data should be entered at the appropriate length for correct encoding. GS1-128 does not support extended ASCII (ISO/IEC 8859-1) characters. Check digits for GTIN data AI (01) are not generated and need to be included in the input data. The following is an example of a valid GS1-128 input:

    -
    zint -b GS1_128 -d "[01]98898765432106[3202]012345[15]991231"
    +
    zint -b GS1_128 -d "[01]98898765432106[3202]012345[15]991231"

    6.1.10.4 EAN-14

    A shorter version of GS1-128 which encodes GTIN-14 data only, EAN-14 takes a 13-digit input, which will be prefixed with leading zeroes if @@ -5415,9 +5435,9 @@ The GS1 check digit (if not given) and HRT-only AI "(01)" are added by Zint.

    +alt="zint -b EAN14 --compliant -d "9889876543210"" />
    Figure 73: -zint -b EAN14 --compliantheight -d "9889876543210"
    +zint -b EAN14 --compliant -d "9889876543210"

    6.1.10.5 NVE-18 (SSCC-18)

    A variation of Code 128 the ‘Nummer der Versandeinheit’ standard, @@ -5429,9 +5449,9 @@ digit is included, in which case the check digit will be verified. Check digit(s) and HRT-only AI "(00)" are added by Zint.

    +alt="zint -b NVE18 --compliant -d "37612345000001003"" />
    Figure 74: -zint -b NVE18 --compliantheight -d "37612345000001003"
    +zint -b NVE18 --compliant -d "37612345000001003"

    6.1.10.6 HIBC Code 128

    This variation adds a leading '+' character and a @@ -5448,9 +5468,9 @@ alt="zint -b HIBC_128 -d "A123BJC5D6E71"" /> Paketdienst).

    +alt="zint -b DPD --compliant -d "000393206219912345678101040"" />
    Figure 76: -zint -b DPD --compliantheight -d "000393206219912345678101040"
    +zint -b DPD --compliant -d "000393206219912345678101040"

    DPD Code requires a 27 or 28 character input. For 28 character input, the first character is an identification tag (Barcode ID), which should @@ -5509,9 +5529,9 @@ a modulo-11 check digit, and "CC" is a two-character ISO 3166-1 country code.

    +alt="zint -b UPU_S10 --compliant -d "EE876543216CA"" />
    Figure 77: -zint -b UPU_S10 --compliantheight -d "EE876543216CA"
    +zint -b UPU_S10 --compliant -d "EE876543216CA"

    The check digit may be omitted in which case Zint will add it. Warnings will be generated if the service indicator is non-standard or @@ -5534,9 +5554,9 @@ standard GS1 check digit may be given, in which case the check digit will be verified.) Input less than 13 digits will be zero-filled.

    +alt="zint -b DBAR_OMN --compliant -d "0950110153001"" />
    Figure 78: -zint -b DBAR_OMN --compliantheight -d "0950110153001"
    +zint -b DBAR_OMN --compliant -d "0950110153001"

    GS1 DataBar Omnidirectional symbols should have a height of 33 or greater. To produce a GS1 DataBar Truncated symbol set the symbol height @@ -5559,9 +5579,9 @@ may be given in which case the check digit will be verified. Input less than 13 digits will be zero-filled.

    +alt="zint -b DBAR_LTD --compliant -d "0950110153001"" />
    Figure 80: -zint -b DBAR_LTD --compliantheight -d "0950110153001"
    +zint -b DBAR_LTD --compliant -d "0950110153001"

    6.1.11.3 GS1 DataBar Expanded

    Previously known as RSS Expanded this is a variable length symbology @@ -5571,17 +5591,17 @@ Data Entry, and will be displayed using parentheses (round brackets) in the Human Readable Text.

    +alt="zint -b DBAR_EXP --compliant -d "[01]98898765432106[3202]012345[15]991231"" />
    Figure 81: -zint -b DBAR_EXP --compliantheight -d "[01]98898765432106[3202]012345[15]991231"
    +zint -b DBAR_EXP --compliant -d "[01]98898765432106[3202]012345[15]991231"

    The GTIN-14 data for AI (01) must include the standard GS1 check digit as this is not calculated by Zint when this symbology is encoded. Data for fixed-length AIs must be entered at the appropriate length. The maximum capacity is 74 numerics or 41 alphanumerics. The following is an example of a valid GS1 DataBar Expanded input:

    -
    zint -b DBAR_EXP -d "[01]98898765432106[3202]012345[15]991231"
    +
    zint -b DBAR_EXP -d "[01]98898765432106[3202]012345[15]991231"

    6.1.12 Korea Post Barcode

    The Korean Postal Barcode is used to encode a 6-digit number and includes one check digit.

    @@ -5600,9 +5620,9 @@ input data: e.g. a three character input string generates a 4 channel code by default.

    +alt="zint -b CHANNEL -d "453678" --compliant" />
    Figure 83: -zint -b CHANNEL -d "453678" --compliantheight
    +zint -b CHANNEL -d "453678" --compliant

    The maximum values permitted depend on the number of channels used as shown in the table below:

    @@ -5659,9 +5679,9 @@ single check character is added by Zint, appearing in the 2nd character position. Lowercase input is automatically made uppercase.

    +alt="zint -b BC412 -d "AQ45670" --compliant" />
    Figure 84: -zint -b BC412 -d "AQ45670" --compliantheight
    +zint -b BC412 -d "AQ45670" --compliant

    6.2 Stacked Symbologies

    6.2.1 Basic Symbol Stacking

    @@ -5669,17 +5689,17 @@ alt="zint -b BC412 -d "AQ45670" --compliantheight" /> primarily in the vehicle industry, is to simply stack one-dimensional codes on top of each other. This can be achieved at the command prompt by giving more than one set of input data. For example

    -
    zint -d "This" -d "That"
    +
    zint -d "This" -d "That"

    will draw two Code 128 symbols, one on top of the other. The same result can be achieved using the API by executing the ZBarcode_Encode() function more than once on a symbol. For example:

    -
    symbol->symbology = BARCODE_CODE128;
    -error = ZBarcode_Encode(symbol, "This", 0);
    -error = ZBarcode_Encode(symbol, "That", 0);
    -error = ZBarcode_Print(symbol);
    +
    symbol->symbology = BARCODE_CODE128;
    +error = ZBarcode_Encode(symbol, "This", 0);
    +error = ZBarcode_Encode(symbol, "That", 0);
    +error = ZBarcode_Print(symbol);
    zint -d "This" -d "That" @@ -5695,8 +5715,8 @@ specifying --bind (API separator bars in integral multiples of the X-dimension (minimum and default 1, maximum 4) can be set by --separator (API option_3):

    -
    zint --bind --notext --separator=2 -d "This" -d "That"
    +
    zint --bind --notext --separator=2 -d "This" -d "That"
    zint --notext --bind --separator=2 -d "This" -d "That" @@ -5738,9 +5758,9 @@ use can be set using the --rows option (API option_1), with values from 2 to 16.

    +alt="zint -b CODE16K --compliant -d "ab0123456789"" />
    Figure 88: -zint -b CODE16K --compliantheight -d "ab0123456789"
    +zint -b CODE16K --compliant -d "ab0123456789"

    6.2.4 PDF417 (ISO 15438)

    Heavily used in the parcel industry, the PDF417 symbology can encode @@ -5831,9 +5851,9 @@ row, making it suitable for small items when omnidirectional scanning is not required.

    +alt="zint -b DBAR_STK --compliant -d "9889876543210"" />
    Figure 92: -zint -b DBAR_STK --compliantheight -d "9889876543210"
    +zint -b DBAR_STK --compliant -d "9889876543210"

    6.2.7.2 GS1 DataBar Stacked Omnidirectional

    @@ -5844,9 +5864,9 @@ GS1 DataBar Omnidirectional and GS1 DataBar Truncated). The data is encoded in two rows of bars with a central 3-row separator.

    +alt="zint -b DBAR_OMNSTK --compliant -d "9889876543210"" />
    Figure 93: -zint -b DBAR_OMNSTK --compliantheight -d "9889876543210"
    +zint -b DBAR_OMNSTK --compliant -d "9889876543210"

    6.2.7.3 GS1 DataBar Expanded Stacked

    @@ -5856,9 +5876,9 @@ href="#gs1-databar-expanded">6.1.11.3 GS1 DataBar Expanded), with the same maximum capacity.

    +alt="zint -b DBAR_EXPSTK --compliant -d "[01]98898765432106[3202]012345[15]991231"" />
    Figure 94: -zint -b DBAR_EXPSTK --compliantheight -d "[01]98898765432106[3202]012345[15]991231"
    +zint -b DBAR_EXPSTK --compliant -d "[01]98898765432106[3202]012345[15]991231"

    The width of the symbol can be altered using the --cols switch (API option_2). In this case the number of columns @@ -5880,9 +5900,9 @@ set using the --rows option (API option_1), with values from 2 to 8.

    +alt="zint -b CODE49 --compliant -d "MULTIPLE ROWS IN CODE 49"" />
    Figure 95: -zint -b CODE49 --compliantheight -d "MULTIPLE ROWS IN CODE 49"
    +zint -b CODE49 --compliant -d "MULTIPLE ROWS IN CODE 49"

    6.3 GS1 Composite Symbols (ISO 24723)

    @@ -5985,18 +6005,18 @@ should be entered into a primary string with the data for the 2D component being entered in the normal way. To do this at the command prompt use the --primary switch (API primary). For example:

    -
    zint -b EAN13_CC --mode=1 --primary=331234567890 -d "[99]1234-abcd"
    +
    zint -b EAN13_CC --mode=1 --primary=331234567890 -d "[99]1234-abcd"

    This creates an EAN-13 linear component with the data "331234567890" and a 2D CC-A (see below) component with the data "(99)1234-abcd". The same results can be achieved using the API as shown below:

    -
    symbol->symbology = BARCODE_EAN13_CC;
    -symbol->option_1 = 1;
    -strcpy(symbol->primary, "331234567890");
    -ZBarcode_Encode_and_Print(symbol, "[99]1234-abcd", 0, 0);
    +
    symbol->symbology = BARCODE_EAN13_CC;
    +symbol->option_1 = 1;
    +strcpy(symbol->primary, "331234567890");
    +ZBarcode_Encode_and_Print(symbol, "[99]1234-abcd", 0, 0);

    2-digit and 5-digit add-on data can be used with EAN and UPC symbols using the '+' character as described in sections 6.1.3 UPC (Universal @@ -6019,9 +6039,9 @@ length (e.g. if all capitals, at most 30, excluding AI). To select CC-A use --mode=1 (API option_1 = 1).

    +alt="zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=1 --primary=331234567890" />
    Figure 96: -zint -b EAN13_CC --compliantheight -d "[99]1234-abcd" --mode=1 --primary=331234567890
    +zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=1 --primary=331234567890

    6.3.2 CC-B

    This system uses MicroPDF417 to encode the 2D component. The size of @@ -6032,9 +6052,9 @@ string of shorter length. To select CC-B use --mode=2 (API option_1 = 2).

    +alt="zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=2 --primary=331234567890" />
    Figure 97: -zint -b EAN13_CC --compliantheight -d "[99]1234-abcd" --mode=2 --primary=331234567890
    +zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=2 --primary=331234567890

    6.3.3 CC-C

    This system uses PDF417 and can only be used in conjunction with a @@ -6043,9 +6063,9 @@ an alphanumeric string of shorter length. To select CC-C use --mode=3 (API option_1 = 3).

    +alt="zint -b GS1_128_CC --compliant -d "[99]1234-abcd" --mode=3 --primary="[01]03312345678903"" />
    Figure 98: -zint -b GS1_128_CC --compliantheight -d "[99]1234-abcd" --mode=3 --primary="[01]03312345678903"
    +zint -b GS1_128_CC --compliant -d "[99]1234-abcd" --mode=3 --primary="[01]03312345678903"

    6.4 Two-Track Symbols

    6.4.1 Pharmacode Two-Track

    @@ -6056,9 +6076,9 @@ pharmaceuticals. The symbology is able to encode whole numbers between 4 and 64570080.

    +alt="zint -b PHARMA_TWO --compliant -d "29876543"" />
    Figure 99: -zint -b PHARMA_TWO --compliantheight -d "29876543"
    +zint -b PHARMA_TWO --compliant -d "29876543"

    6.4.2 POSTNET

    Used by the United States Postal Service until 2009, the POSTNET @@ -6071,9 +6091,9 @@ lengths as used by USPS were PostNet6 (5-digit ZIP input), will be issued if the input length is not one of these.

    +alt="zint -b POSTNET --compliant -d "12345678901"" />
    Figure 100: -zint -b POSTNET --compliantheight -d "12345678901"
    +zint -b POSTNET --compliant -d "12345678901"

    6.4.3 PLANET

    Used by the United States Postal Service until 2009, the PLANET @@ -6086,9 +6106,9 @@ of up to 38 digits in length, standard lengths used by USPS were length is not one of these.

    +alt="zint -b PLANET --compliant -d "4012345235636"" />
    Figure 101: -zint -b PLANET --compliantheight -d "4012345235636"
    +zint -b PLANET --compliant -d "4012345235636"

    6.4.4 Brazilian CEPNet

    Based on POSTNET, the CEPNet symbol is used by Correios, the @@ -6097,9 +6117,9 @@ numbers on mail items. Input should consist of eight digits with the check digit being automatically added by Zint.

    +alt="zint -b CEPNET --compliant -d "12345678"" />
    Figure 102: -zint -b CEPNET --compliantheight -d "12345678"
    +zint -b CEPNET --compliant -d "12345678"

    6.4.5 DX Film Edge Barcode

    Introduced by Kodak in the 1980s, the DX (Digital Index) barcode is @@ -6107,9 +6127,9 @@ printed on the bottom edge of 35mm film to aid in the reordering and post-processing of prints.

    +alt="zint -b DXFILMEDGE --compliant -d "112-1/10A"" />
    Figure 103: -zint -b DXFILMEDGE --compliantheight -d "112-1/10A"
    +zint -b DXFILMEDGE --compliant -d "112-1/10A"

    The data can be in two parts. The first part (required) is the “DX number”, identifying the manufacturer and film type - the National @@ -6123,8 +6143,8 @@ the 6-digit version the first and last digit are ignored, leaving a 2047. The second format "NNN-NN" represents the DX Extract as two numbers separated by a dash (-), the first number being 1 to 3 digits (range 1 to 127) and the second 1 to 2 digits (range -0 to 15).23

    +0 to 15).24

    The optional frame number is a number in the range 0 to 63, and may have a half frame indicator "A" appended. Special character sequences (with or without a half frame indicator appended) may also be @@ -6142,9 +6162,9 @@ respectively, developed by Australia Post for printing Delivery Point ID (DPID) and customer information on mail items.

    +alt="zint -b AUSPOST --compliant -d "96184209"" />
    Figure 104: -zint -b AUSPOST --compliantheight -d "96184209"
    +zint -b AUSPOST --compliant -d "96184209"

    Valid data characters are 0-9, A-Z, a-z, space and hash (#). A Format Control Code (FCC) is added by Zint and should not be included in the @@ -6223,27 +6243,27 @@ input lengths) if the DPID is all zeroes.

    which requires an 8-digit DPID input.

    +alt="zint -b AUSREPLY --compliant -d "12345678"" />
    Figure 105: -zint -b AUSREPLY --compliantheight -d "12345678"
    +zint -b AUSREPLY --compliant -d "12345678"

    6.5.1.3 Routing Barcode

    A Routing version of the Australia Post 4-State Barcode (FCC 87) which requires an 8-digit DPID input.

    +alt="zint -b AUSROUTE --compliant -d "34567890"" />
    Figure 106: -zint -b AUSROUTE --compliantheight -d "34567890"
    +zint -b AUSROUTE --compliant -d "34567890"

    6.5.1.4 Redirect Barcode

    A Redirection version of the Australia Post 4-State Barcode (FCC 92) which requires an 8-digit DPID input.

    +alt="zint -b AUSREDIRECT --compliant -d "98765432"" />
    Figure 107: -zint -b AUSREDIRECT --compliantheight -d "98765432"
    +zint -b AUSREDIRECT --compliant -d "98765432"

    6.5.2 Dutch Post KIX Code

    This symbology is used by Royal Dutch TPG Post (Netherlands) for @@ -6252,9 +6272,9 @@ numbers 0-9 and letters A-Z and needs to be 11 characters in length. No check digit is included.

    +alt="zint -b KIX --compliant -d "2500GG30250"" />
    Figure 108: -zint -b KIX --compliantheight -d "2500GG30250"
    +zint -b KIX --compliant -d "2500GG30250"

    6.5.3 Royal Mail 4-State Customer Code (RM4SCC)

    @@ -6265,9 +6285,9 @@ followed by house number. For example "W1J0TR01" for 1 Piccadilly Circus in London. Check digit data is generated by Zint.

    +alt="zint -b RM4SCC --compliant -d "W1J0TR01"" />
    Figure 109: -zint -b RM4SCC --compliantheight -d "W1J0TR01"
    +zint -b RM4SCC --compliant -d "W1J0TR01"

    6.5.4 Royal Mail 4-State Mailmark

    @@ -6275,9 +6295,9 @@ Mailmark includes Reed- Solomon error correction.

    +alt="zint -b MAILMARK_4S --compliant -d "21B2254800659JW5O9QA6Y"" />
    Figure 110: -zint -b MAILMARK_4S --compliantheight -d "21B2254800659JW5O9QA6Y"
    +zint -b MAILMARK_4S --compliant -d "21B2254800659JW5O9QA6Y"

    Input is a pre-formatted alphanumeric string of 22 (for Barcode C) or 26 (for Barcode L) characters, producing a symbol with 66 or 78 bars @@ -6348,9 +6368,9 @@ States Postal Service (USPS), the Intelligent Mail system replaced the POSTNET and PLANET symbologies in 2009.

    +alt="zint -b USPS_IMAIL --compliant -d "01234567094987654321-01234"" />
    Figure 111: -zint -b USPS_IMAIL --compliantheight -d "01234567094987654321-01234"
    +zint -b USPS_IMAIL --compliant -d "01234567094987654321-01234"

    Intelligent Mail is a fixed length 65-bar symbol which combines routing and customer information in a single symbol. Input data consists @@ -6370,9 +6390,9 @@ are 0-9, A-Z and dash (-). A modulo 19 check digit is added by Zint.

    +alt="zint -b JAPANPOST --compliant -d "15400233-16-4-205"" />
    Figure 112: -zint -b JAPANPOST --compliantheight -d "15400233-16-4-205"
    +zint -b JAPANPOST --compliant -d "15400233-16-4-205"

    6.5.7 DAFT Code

    This is a method for creating 4-state codes where the data encoding @@ -6391,13 +6411,13 @@ alt="zint -b DAFT -d "AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF" --height thousandths (permille) using the --vers option (API option_2). The default value is 250 (25%).

    For example the following

    -
    zint -b DAFT -d AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF --height=8.494 --vers=256
    +
    zint -b DAFT -d AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF --height=8.494 --vers=256

    produces the same barcode (see 6.5.3 Royal Mail 4-State Customer Code (RM4SCC)) as

    -
    zint -b RM4SCC --compliantheight -d "W1J0TR01"
    +
    zint -b RM4SCC --compliant -d "W1J0TR01"

    6.6 Matrix Symbols

    6.6.1 Data Matrix (ISO 16022)

    Also known as Semacode this symbology was developed in 1989 by Acuity @@ -6632,15 +6652,15 @@ processing normal escape sequences also processes the extra escape sequences given in Table 3: Extra Escape Sequences. For instance

    -
    zint -b DATAMATRIX -d "A\^1BC\^1DEF" --extraesc
    +
    zint -b DATAMATRIX -d "A\^1BC\^1DEF" --extraesc

    encodes the data "A<FNC1>BC<FNC1>DEF", where <FNC1> represents the FNC1 character. If the data contains an extra escape sequence, it can be escaped by doubling the caret (^), i.e. "\^^" encodes "\^". Note that if using ECIs with manual FNC1s then the -ECIs must be ASCII compatible.24

    +ECIs must be ASCII compatible.25

    By default Zint uses a “de facto” codeword placement for symbols of size 144 x 144 (version 24). To override this and use the now clarified ISO/IEC standard placement, use option --dmiso144 (API @@ -7069,8 +7089,8 @@ be manually specified by using the --mask switch with values 0-7, or in the API by setting option_3 = (N + 1) << 8 where N is 0-7. To use with ZINT_FULL_MULTIBYTE set

    -
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8
    +
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8

    The --fast option (API input_mode |= FAST_MODE) may be used when leaving Zint to automatically select a mask to reduce the number of masks to try to four @@ -7202,8 +7222,8 @@ be manually specified by using the --mask switch with values 0-3, or in the API by setting option_3 = (N + 1) << 8 where N is 0-3. To use with ZINT_FULL_MULTIBYTE set

    -
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8
    +
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8

    6.6.5 Rectangular Micro QR Code (rMQR) (ISO 23941)

    A rectangular version of QR Code, rMQR supports encoding of GS1 data, @@ -7468,8 +7488,8 @@ or if your data is already Latin-2 formatted use the input_mode = DATA_MODE).

    The following example creates a symbol from data saved as a Latin-2 file:

    -
    zint -o upnqr.png -b UPNQR --scale=3 --binary -i upn.txt
    +
    zint -o upnqr.png -b UPNQR --binary -i upn.txt

    A mask may be manually specified and the --fast option used as with 6.6.3 QR Code (ISO 18004).

    @@ -7527,9 +7547,9 @@ your parcel courier.

    The primary message can be set at the command prompt using the --primary switch (API primary). The secondary message uses the normal data entry method. For example:

    -
    zint -o test.eps -b MAXICODE --primary="999999999840012" \
    -    -d "Secondary Message Here"
    +
    zint -o test.eps -b MAXICODE --primary="999999999840012" \
    +    -d "Secondary Message Here"

    When using the API the primary message must be placed in the primary string. The secondary is entered in the same way as described in 5.2 Encoding and @@ -7542,9 +7562,9 @@ to be prefixed by the ISO/IEC 15434 Format "01" vv is a 2-digit version, by using the --scmvv switch (API option_2 = vv + 1). For example to use the common version "96" (ASC MH10/SC 8):

    -
    zint -b MAXICODE --primary="152382802840001" --scmvv=96 --esc -d \
    -  "1Z00004951\GUPSN\G06X610\G159\G1234567\G1/1\G\GY\G1 MAIN ST\GNY\GNY\R\E"
    +
    zint -b MAXICODE --primary="152382802840001" --scmvv=96 --esc -d \
    +  "1Z00004951\GUPSN\G06X610\G159\G1234567\G1/1\G\GY\G1 MAIN ST\GNY\GNY\R\E"

    will prefix "[)>\R01\G96" to the secondary message. (\R, \G and \E are the escape sequences for Record Separator, Group Separator and End of Transmission @@ -7554,8 +7574,8 @@ Sequences.)

    Modes 4 to 6 can be accessed using the --mode switch (API option_1). Modes 4 to 6 do not have a primary message. For example:

    -
    zint -o test.eps -b MAXICODE --mode=4 -d "A MaxiCode Message in Mode 4"
    +
    zint -o test.eps -b MAXICODE --mode=4 -d "A MaxiCode Message in Mode 4"

    Mode 6 is reserved for the maintenance of scanner hardware and should not be used to encode user data.

    This symbology uses Latin-1 character encoding by default but also @@ -8488,8 +8508,8 @@ be manually specified by using the --mask switch with values 0-3, or in the API by setting option_3 = (N + 1) << 8 where N is 0-3. To use with ZINT_FULL_MULTIBYTE set

    -
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8
    +
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8

    6.6.14 Ultracode

    This symbology uses a grid of coloured elements to encode data. ECI and GS1 modes are supported.

    @@ -8547,8 +8567,8 @@ Correction Values

    Zint does not currently implement data compression by default, but this can be initiated through the API by setting

    -
    symbol->option_3 = ULTRA_COMPRESSION;
    +
    symbol->option_3 = ULTRA_COMPRESSION;

    With compression, up to 504 digits, 375 alphanumerics or 252 bytes can be encoded.

    Revision 2 of Ultracode (2023) may be specified using @@ -8570,9 +8590,9 @@ Markings used to assist automated mail processing.

    +alt="zint -b FIM --compliant -d "C"" />
    Figure 128: -zint -b FIM --compliantheight -d "C"
    +zint -b FIM --compliant -d "C"

    There are only 5 valid symbols which can be generated using the characters A-E as shown in the table below.

    @@ -9208,28 +9228,28 @@ properties that correspond to the zint_symbol structure method render() which takes a Qt QPainter to paint with, and a QRectF rectangular area specifying where to paint into:

    -
    /* Encode and display barcode in `paintRect` using `painter`.
    -   Note: legacy argument `mode` is not used */
    -void render(QPainter& painter, const QRectF& paintRect,
    -            AspectRatioMode mode = IgnoreAspectRatio);
    +
    /* Encode and display barcode in `paintRect` using `painter`.
    +   Note: legacy argument `mode` is not used */
    +void render(QPainter& painter, const QRectF& paintRect,
    +            AspectRatioMode mode = IgnoreAspectRatio);

    render() will emit one of two Qt signals - encoded on successful encoding and drawing, or errored on failure. The client can connect and act appropriately, for instance:

    -
    connect(qzint, SIGNAL(encoded()), SLOT(on_encoded()));
    -connect(qzint, SIGNAL(errored()), SLOT(on_errored()));
    +
    connect(qzint, SIGNAL(encoded()), SLOT(on_encoded()));
    +connect(qzint, SIGNAL(errored()), SLOT(on_errored()));

    where qzint is an instance of Zint::QZint and on_encoded() and on_error() are Qt slot methods provided by the caller. On error, the error value and message can be retrieved by the methods getError() and lastError() respectively.

    The other main method is save_to_file():

    -
    /* Encode and print barcode to file `filename`.
    -   Only sets `getError()` on error, not on warning */
    -bool save_to_file(const QString& filename); // `ZBarcode_Print()`
    +
    /* Encode and print barcode to file `filename`.
    +   Only sets `getError()` on error, not on warning */
    +bool save_to_file(const QString& filename); // `ZBarcode_Print()`

    which takes a filename to output to. It too will emit an errored signal on failure, returning false (but nothing on success, which just returns true). Note @@ -9242,14 +9262,14 @@ symbology capabilities, and utility methods such as defaultXdim() and getAsCLI().

    For full details, see "backend_qt/qzint.h".

    Annex C. Tcl Backend Binding

    -

    A Tcl binding is available in the "backend_tcl” +

    A Tcl binding is available in the "backend_tcl" sub-directory. To make on Unix:

    -
    cd backend_tcl
    -autoconf
    -./configure
    -make
    -sudo make install
    +
    cd backend_tcl
    +autoconf
    +./configure
    +make
    +sudo make install

    For Windows, a Microsoft Visual C++ project file is available at "backend_tcl\zint_tcl.vcxproj". Note that this assumes that Tcl/Tk is available in "C:\Tcl" and that the libraries are @@ -9260,21 +9280,21 @@ to match your setup. There is also a Visual Studio makefile available at "backend_tcl\win\README.txt".

    Once built and installed, invoke the Tcl/Tk CLI "wish":

    -
    wish
    +
    wish

    and ignoring the Tk window click back to the command prompt "%" and type:

    -
    package require zint
    -zint help
    +
    package require zint
    +zint help

    which will show the usage message, with options very similar to the Zint CLI. (One notable difference is that boolean options such as -bold take a 1 or 0 as an argument.)

    A demonstration Tcl/Tk program which is also useful in itself is available at "backend_tcl/demo/demo.tcl". To run type:

    -
    wish demo/demo.tcl
    +
    wish demo/demo.tcl

    which will display the following window.

    --mirror
    -

    Use the batch data to determine the filename in batch mode -(--batch). The -o | --output -option can be used to specify an output directory (any filename will be -ignored).

    +

    Use the data to determine the filename. This is particularly useful +in batch mode (--batch), but also works in standard mode. +The -o | --output option can be used to +specify an output directory (any filename will be ignored).

    --mode=INTEGER
    @@ -10058,17 +10078,17 @@ Error counterpart of warning if --werror given

    EXAMPLES

    Create “out.png” (or “out.gif” if zint built without PNG support) in the current directory, as a Code 128 symbol.

    -
    zint -d 'This Text'
    +
    zint -d 'This Text'

    Create “qr.svg” in the current directory, as a QR Code symbol.

    -
    zint -b QRCode -d 'This Text' -o 'qr.svg'
    +
    zint -b QRCode -d 'This Text' -o 'qr.svg'

    Use batch mode to read from an input file “ean13nos.txt” containing a list of 13-digit GTINs, each on a separate line, to create a series of EAN-13 barcodes, formatting the output filenames to “ean001.gif”, “ean002.gif” etc. using the special character “~”.

    -
    zint -b EAN13 --batch -i 'ean13nos.txt' -o 'ean~~~.gif'
    +
    zint -b EAN13 --batch -i 'ean13nos.txt' -o 'ean~~~.gif'

    BUGS

    Please send bug reports to https://sourceforge.net/p/zint/tickets/.

    @@ -10154,7 +10174,7 @@ characters undefined: #, $, @, ~ (tilde).↩︎

    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 +# SPDX-License-Identifier: BSD-3-Clause +# vim: set ts=4 sw=4 et : +# +# Compile zint with gcc and "-DZINT_COVERAGE=ON -DZINT_DEBUG=ON -DZINT_TEST=ON" +# Run this script in the build directory (same as ctest but with debug flag set): +# ../backend/tests/tools/run_coverage.sh +# will produce "html_report/index.html" +# +set -e + +backend/tests/test_2of5 -d 1 +backend/tests/test_auspost -d 1 +backend/tests/test_aztec -d 1 +backend/tests/test_bc412 -d 1 +backend/tests/test_big5 -d 1 +backend/tests/test_bmp -d 1 +backend/tests/test_bwipp -d 1 +backend/tests/test_channel -d 1 +backend/tests/test_codabar -d 1 +backend/tests/test_codablock -d 1 +backend/tests/test_code -d 1 +backend/tests/test_code1 -d 1 +backend/tests/test_code11 -d 1 +backend/tests/test_code128 -d 1 +backend/tests/test_code16k -d 1 +backend/tests/test_code49 -d 1 +backend/tests/test_common -d 1 +backend/tests/test_composite -d 1 +backend/tests/test_dmatrix -d 1 +backend/tests/test_dotcode -d 1 +backend/tests/test_dxfilmedge -d 1 +backend/tests/test_eci -d 1 +backend/tests/test_emf -d 1 +backend/tests/test_filemem -d 1 +backend/tests/test_gb18030 -d 1 +backend/tests/test_gb2312 -d 1 +backend/tests/test_gif -d 1 +backend/tests/test_gridmtx -d 1 +backend/tests/test_gs1 -d 1 +backend/tests/test_gs1se -d 1 +backend/tests/test_hanxin -d 1 +backend/tests/test_imail -d 1 +backend/tests/test_iso3166 -d 1 +backend/tests/test_iso4217 -d 1 +backend/tests/test_ksx1001 -d 1 +backend/tests/test_large -d 1 +backend/tests/test_library -d 1 +backend/tests/test_mailmark -d 1 +backend/tests/test_maxicode -d 1 +backend/tests/test_medical -d 1 +backend/tests/test_output -d 1 +backend/tests/test_pcx -d 1 +backend/tests/test_pdf417 -d 1 +backend/tests/test_perf -d 1 +backend/tests/test_plessey -d 1 +backend/tests/test_png -d 1 +backend/tests/test_postal -d 1 +backend/tests/test_print -d 1 +backend/tests/test_ps -d 1 +backend/tests/test_qr -d 1 +backend/tests/test_random -d 1 +backend/tests/test_raster -d 1 +backend/tests/test_reedsol -d 1 +backend/tests/test_rss -d 1 +backend/tests/test_sjis -d 1 +backend/tests/test_svg -d 1 +backend/tests/test_telepen -d 1 +backend/tests/test_tif -d 1 +backend/tests/test_ultra -d 1 +backend/tests/test_upcean -d 1 +backend/tests/test_vector -d 1 +frontend/tests/test_args +backend_qt/tests/test_qzint + +lcov --capture --directory . --output-file coverage.info --exclude 'build/*' --exclude 'usr/*' --exclude 'tests/*' +genhtml -o html_report coverage.info diff --git a/backend/tif.c b/backend/tif.c index 3d4cfc47..82d5d976 100644 --- a/backend/tif.c +++ b/backend/tif.c @@ -222,7 +222,6 @@ INTERNAL int zint_tif_pixel_plot(struct zint_symbol *symbol, const unsigned char struct filemem *const fmp = &fm; const unsigned char *pb; int compression = TIF_NO_COMPRESSION; - long file_pos; const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; uint32_t *strip_offset; uint32_t *strip_bytes; @@ -497,12 +496,23 @@ INTERNAL int zint_tif_pixel_plot(struct zint_symbol *symbol, const unsigned char /* End of strip */ if (compression == TIF_LZW) { #ifndef NDEBUG - file_pos = zint_fm_tell(fmp); + long before_file_pos, after_file_pos; + if ((before_file_pos = zint_fm_tell(fmp)) == -1L) { + (void) zint_fm_close(fmp, symbol); + return z_errtxt(ZINT_ERROR_FILE_WRITE, symbol, 671, "Failed to get file position in TIF output"); + } #endif + bytes_put = tif_lzw_compress(fmp, strip_buf, bytes_put); + #ifndef NDEBUG - assert(bytes_put == (unsigned int) (zint_fm_tell(fmp) - file_pos)); + if ((after_file_pos = zint_fm_tell(fmp)) == -1L) { + (void) zint_fm_close(fmp, symbol); + return z_errtxt(ZINT_ERROR_FILE_WRITE, symbol, 673, "Failed to get file position in TIF output"); + } + assert(bytes_put == (unsigned int) (after_file_pos - before_file_pos)); #endif + if (bytes_put != strip_bytes[strip]) { const int diff = bytes_put - strip_bytes[strip]; strip_bytes[strip] = bytes_put; @@ -528,7 +538,11 @@ INTERNAL int zint_tif_pixel_plot(struct zint_symbol *symbol, const unsigned char } if (compression == TIF_LZW) { - file_pos = zint_fm_tell(fmp); + long file_pos; + if ((file_pos = zint_fm_tell(fmp)) == -1L) { + (void) zint_fm_close(fmp, symbol); + return z_errtxt(ZINT_ERROR_FILE_WRITE, symbol, 675, "Failed to get file position in TIF output"); + } zint_fm_seek(fmp, 4, SEEK_SET); free_memory = file_pos; temp32 = (uint32_t) free_memory; diff --git a/backend/ultra.c b/backend/ultra.c index 92033570..804f265b 100644 --- a/backend/ultra.c +++ b/backend/ultra.c @@ -250,23 +250,15 @@ static int ult_find_fragment(const unsigned char source[], const int length, con static float ult_look_ahead_eightbit(const unsigned char source[], const int length, const int in_locn, const int current_mode, const int end_char, int cw[], int *cw_len, const int gs1) { int codeword_count = 0; - int i; int letters_encoded = 0; + int i; if (current_mode != ULT_EIGHTBIT_MODE) { - cw[codeword_count] = 282; /* Unlatch */ - codeword_count += 1; + cw[codeword_count++] = 282; /* Unlatch */ } - i = in_locn; - while (i < length && i < end_char) { - if (gs1 && source[i] == '\x1D') { - cw[codeword_count] = 268; /* FNC1 */ - } else { - cw[codeword_count] = source[i]; - } - i++; - codeword_count++; + for (i = in_locn; i < length && i < end_char; i++) { + cw[codeword_count++] = gs1 && source[i] == '\x1D' ? 268 /*FNC1*/ : source[i]; } letters_encoded = i - in_locn; @@ -284,28 +276,24 @@ static float ult_look_ahead_ascii(unsigned char source[], const int length, cons const int current_mode, const int symbol_mode, const int end_char, int cw[], int *cw_len, int *encoded, const int gs1) { int codeword_count = 0; - int i; - int done; int letters_encoded = 0; + int i; if (current_mode == ULT_EIGHTBIT_MODE) { - cw[codeword_count] = 267; /* Latch ASCII Submode */ - codeword_count++; + cw[codeword_count++] = 267; /* Latch ASCII Submode */ } if (current_mode == ULT_C43_MODE) { - cw[codeword_count] = 282; /* Unlatch */ - codeword_count++; + cw[codeword_count++] = 282; /* Unlatch */ if (symbol_mode == ULT_EIGHTBIT_MODE) { - cw[codeword_count] = 267; /* Latch ASCII Submode */ - codeword_count++; + cw[codeword_count++] = 267; /* Latch ASCII Submode */ } } i = in_locn; do { /* Check for double digits */ - done = 0; + int done = 0; if (i + 1 < length) { const int first_digit = z_posn(ult_digit, source[i]); const int second_digit = z_posn(ult_digit, source[i + 1]); @@ -313,32 +301,27 @@ static float ult_look_ahead_ascii(unsigned char source[], const int length, cons /* Double digit can be encoded */ if (first_digit >= 0 && first_digit <= 9 && second_digit >= 0 && second_digit <= 9) { /* Double digit numerics */ - cw[codeword_count] = (10 * first_digit) + second_digit + 128; - codeword_count++; + cw[codeword_count++] = (10 * first_digit) + second_digit + 128; i += 2; done = 1; } else if (first_digit >= 0 && first_digit <= 9 && second_digit == 10) { /* Single digit followed by selected decimal point character */ - cw[codeword_count] = first_digit + 228; - codeword_count++; + cw[codeword_count++] = first_digit + 228; i += 2; done = 1; } else if (first_digit == 10 && second_digit >= 0 && second_digit <= 9) { /* Selected decimal point character followed by single digit */ - cw[codeword_count] = second_digit + 238; - codeword_count++; + cw[codeword_count++] = second_digit + 238; i += 2; done = 1; } else if (first_digit >= 0 && first_digit <= 9 && second_digit == 11) { /* Single digit or decimal point followed by field deliminator */ - cw[codeword_count] = first_digit + 248; - codeword_count++; + cw[codeword_count++] = first_digit + 248; i += 2; done = 1; } else if (first_digit == 11 && second_digit >= 0 && second_digit <= 9) { /* Field deliminator followed by single digit or decimal point */ - cw[codeword_count] = second_digit + 259; - codeword_count++; + cw[codeword_count++] = second_digit + 259; i += 2; done = 1; } @@ -346,12 +329,7 @@ static float ult_look_ahead_ascii(unsigned char source[], const int length, cons } if (!done && z_isascii(source[i])) { - if (gs1 && source[i] == '\x1D') { - cw[codeword_count] = 272; /* FNC1 */ - } else { - cw[codeword_count] = source[i]; - } - codeword_count++; + cw[codeword_count++] = gs1 && source[i] == '\x1D' ? 272 /*FNC1*/ : source[i]; i++; } } while (i < length && i < end_char && z_isascii(source[i])); @@ -467,53 +445,43 @@ static float ult_look_ahead_c43(const unsigned char source[], const int length, switch (fragno) { case 17: /* mailto: */ - cw[codeword_count] = 276; + cw[codeword_count++] = 276; sublocn += (int) strlen(ult_fragment[fragno]); - codeword_count++; break; case 18: /* tel: */ - cw[codeword_count] = 277; + cw[codeword_count++] = 277; sublocn += (int) strlen(ult_fragment[fragno]); - codeword_count++; break; case 26: /* file: */ - cw[codeword_count] = 278; + cw[codeword_count++] = 278; sublocn += (int) strlen(ult_fragment[fragno]); - codeword_count++; break; case 0: /* http:// */ - cw[codeword_count] = 279; + cw[codeword_count++] = 279; sublocn += (int) strlen(ult_fragment[fragno]); - codeword_count++; break; case 1: /* https:// */ - cw[codeword_count] = 280; + cw[codeword_count++] = 280; sublocn += (int) strlen(ult_fragment[fragno]); - codeword_count++; break; case 4: /* ftp:// */ - cw[codeword_count] = 281; + cw[codeword_count++] = 281; sublocn += (int) strlen(ult_fragment[fragno]); - codeword_count++; break; default: if (subset == 1) { - cw[codeword_count] = 260; /* C43 Compaction Submode C1 */ - codeword_count++; + cw[codeword_count++] = 260; /* C43 Compaction Submode C1 */ } else if (subset == 2 || subset == 3) { - cw[codeword_count] = 266; /* C43 Compaction Submode C2 */ - codeword_count++; + cw[codeword_count++] = 266; /* C43 Compaction Submode C2 */ } break; } } else if (current_mode == ULT_ASCII_MODE) { if (subset == 1) { - cw[codeword_count] = 278; /* C43 Compaction Submode C1 */ - codeword_count++; + cw[codeword_count++] = 278; /* C43 Compaction Submode C1 */ } else if (subset == 2 || subset == 3) { - cw[codeword_count] = 280; /* C43 Compaction Submode C2 */ - codeword_count++; + cw[codeword_count++] = 280; /* C43 Compaction Submode C2 */ } } unshift_set = subset; @@ -532,14 +500,11 @@ static float ult_look_ahead_c43(const unsigned char source[], const int length, if (new_subset != subset && (new_subset == 1 || new_subset == 2)) { if (ult_c43_should_latch_other(source, length, sublocn, subset)) { - subcw[subcodeword_count] = 42; /* Latch to other C43 set */ - subcodeword_count++; + subcw[subcodeword_count++] = 42; /* Latch to other C43 set */ unshift_set = new_subset; } else { - subcw[subcodeword_count] = 40; /* Shift to other C43 set for 1 char */ - subcodeword_count++; - subcw[subcodeword_count] = z_posn(new_subset == 1 ? ult_c43_set1 : ult_c43_set2, source[sublocn]); - subcodeword_count++; + subcw[subcodeword_count++] = 40; /* Shift to other C43 set for 1 char */ + subcw[subcodeword_count++] = z_posn(new_subset == 1 ? ult_c43_set1 : ult_c43_set2, source[sublocn]); sublocn++; continue; } @@ -548,32 +513,26 @@ static float ult_look_ahead_c43(const unsigned char source[], const int length, subset = new_subset; if (subset == 1) { - subcw[subcodeword_count] = z_posn(ult_c43_set1, source[sublocn]); - subcodeword_count++; + subcw[subcodeword_count++] = z_posn(ult_c43_set1, source[sublocn]); sublocn++; } else if (subset == 2) { - subcw[subcodeword_count] = z_posn(ult_c43_set2, source[sublocn]); - subcodeword_count++; + subcw[subcodeword_count++] = z_posn(ult_c43_set2, source[sublocn]); sublocn++; } else if (subset == 3) { - subcw[subcodeword_count] = 41; /* Shift to set 3 */ - subcodeword_count++; + subcw[subcodeword_count++] = 41; /* Shift to set 3 */ fragno = ult_find_fragment(source, length, sublocn); if (fragno != -1 && fragno != 26) { if (fragno <= 18) { - subcw[subcodeword_count] = fragno; /* C43 Set 3 codewords 0 to 18 */ - subcodeword_count++; + subcw[subcodeword_count++] = fragno; /* C43 Set 3 codewords 0 to 18 */ sublocn += (int) strlen(ult_fragment[fragno]); } else { - subcw[subcodeword_count] = fragno + 17; /* C43 Set 3 codewords 36 to 42 */ - subcodeword_count++; + subcw[subcodeword_count++] = fragno + 17; /* C43 Set 3 codewords 36 to 42 */ sublocn += (int) strlen(ult_fragment[fragno]); } } else { /* C43 Set 3 codewords 19 to 35 */ - subcw[subcodeword_count] = z_posn(ult_c43_set3, source[sublocn]) + 19; - subcodeword_count++; + subcw[subcodeword_count++] = z_posn(ult_c43_set3, source[sublocn]) + 19; sublocn++; } subset = unshift_set; @@ -586,8 +545,7 @@ static float ult_look_ahead_c43(const unsigned char source[], const int length, } for (i = 0; i < pad; i++) { - subcw[subcodeword_count] = 42; /* Latch to other C43 set used as pad */ - subcodeword_count++; + subcw[subcodeword_count++] = 42; /* Latch to other C43 set used as pad */ } if (debug_print) { @@ -603,10 +561,8 @@ static float ult_look_ahead_c43(const unsigned char source[], const int length, for (i = 0; i < subcodeword_count; i += 3) { base43_value = (43 * 43 * subcw[i]) + (43 * subcw[i + 1]) + subcw[i + 2]; - cw[codeword_count] = base43_value / 282; - codeword_count++; - cw[codeword_count] = base43_value % 282; - codeword_count++; + cw[codeword_count++] = base43_value / 282; + cw[codeword_count++] = base43_value % 282; } *cw_len = codeword_count; @@ -796,7 +752,7 @@ static int ult_generate_codewords(struct zint_symbol *symbol, const unsigned cha /* Call `ult_generate_codewords()` for each segment, dealing with symbol mode and start codeword beforehand */ static int ult_generate_codewords_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, - int codewords[], int *p_data_cw_count) { + int codewords[]) { int i; int codeword_count = 0; int symbol_mode; @@ -926,13 +882,11 @@ static int ult_generate_codewords_segs(struct zint_symbol *symbol, struct zint_s } } - *p_data_cw_count = codeword_count; - - return 0; + return codeword_count; } INTERNAL int zint_ultra(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { - int data_cw_count = 0; + int data_cw_count; int acc, qcc; int scr[3] = {0}, scr_cw_count = 0; /* Symbol Control Region (only if have Structured Append) */ int dr_count; @@ -1008,9 +962,7 @@ INTERNAL int zint_ultra(struct zint_symbol *symbol, struct zint_seg segs[], cons data_codewords = (int *) z_alloca(sizeof(int) * cw_alloc); - if (ult_generate_codewords_segs(symbol, segs, seg_count, data_codewords, &data_cw_count)) { - return ZINT_ERROR_MEMORY; /* `ult_generate_codewords_segs()` only returns non-zero if OOM */ - } + data_cw_count = ult_generate_codewords_segs(symbol, segs, seg_count, data_codewords); if (debug_print) { printf("Codewords (%d):", data_cw_count); diff --git a/backend/upcean.c b/backend/upcean.c index b0d6930f..ebf17efb 100644 --- a/backend/upcean.c +++ b/backend/upcean.c @@ -559,9 +559,7 @@ static int isbnx(struct zint_symbol *symbol, unsigned char source[], const int l char check_digit; z_to_upper(source, length); - if (z_not_sane(ISBNX_SANE_F, source, length)) { /* As source has been zero-padded, don't report position */ - return z_errtxt(ZINT_ERROR_INVALID_DATA, symbol, 277, "Invalid character in input (digits and \"X\" only)"); - } + assert(!z_not_sane(ISBNX_SANE_F, source, length)); /* Prior checks ensure this */ /* Input must be 9, 10 or 13 characters */ if (length != 9 && length != 10 && length != 13) { @@ -942,6 +940,9 @@ INTERNAL int zint_eanx_cc(struct zint_symbol *symbol, unsigned char source[], in case BARCODE_EANX: case BARCODE_EANX_CHK: case BARCODE_EAN13: + /* Checks in `zint_ean_leading_zeroes()` ensure following */ + assert(first_part_len == 2 || first_part_len == 5 || first_part_len == 7 || first_part_len == 8 + || first_part_len == 12 || first_part_len == 13); switch (first_part_len) { case 2: case 5: @@ -963,18 +964,15 @@ INTERNAL int zint_eanx_cc(struct zint_symbol *symbol, unsigned char source[], in case 13: error_number = ean13(symbol, first_part, first_part_len, dest); break; - default: - assert(symbol->symbology == BARCODE_EANX || symbol->symbology == BARCODE_EANX_CHK); - return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 286, - "Input length %d wrong (2, 5, 7, 8, 12 or 13 characters required)", - first_part_len); - break; } break; case BARCODE_EANX_CC: case BARCODE_EAN8_CC: case BARCODE_EAN13_CC: - switch (first_part_len) { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */ + /* Checks in `zint_ean_leading_zeroes()` ensure following */ + assert(first_part_len == 7 || first_part_len == 8 || first_part_len == 12 || first_part_len == 13); + switch (first_part_len) { + /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */ case 7: case 8: z_set_module(symbol, symbol->rows, 1); @@ -1003,11 +1001,6 @@ INTERNAL int zint_eanx_cc(struct zint_symbol *symbol, unsigned char source[], in symbol->rows += 3; error_number = ean13_cc(symbol, first_part, first_part_len, dest, cc_rows); break; - default: - assert(symbol->symbology == BARCODE_EANX_CC); - return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 287, - "Input length %d wrong (7, 12 or 13 characters required)", first_part_len); - break; } break; case BARCODE_UPCA: diff --git a/backend/vector.c b/backend/vector.c index 00e4623d..62388168 100644 --- a/backend/vector.c +++ b/backend/vector.c @@ -36,6 +36,43 @@ #include "output.h" #include "zfiletypes.h" +#ifdef ZINT_TEST +/* For testing `malloc()` failure */ + +static int vector_fail_id = 0; /* VECT_FAIL_ID_XXX below */ +static int vector_fail_at = 0; /* Number of times before failure */ + +INTERNAL void zint_test_vector_set_fail(const int id, const int at) { + vector_fail_id = id; + vector_fail_at = at; +} + +/* TODO: add new "vector.h" & put these in it */ +#define VECT_FAIL_ID_RECT 1 +#define VECT_FAIL_ID_HEXAGON 2 +#define VECT_FAIL_ID_CIRCLE 3 +#define VECT_FAIL_ID_STR 4 +#define VECT_FAIL_ID_SUBSTR 5 +#define VECT_FAIL_ID_HDR 6 + +#define vect_malloc(id, sz) (vector_fail_at > 0 && vector_fail_id == (id) && --vector_fail_at == 0 \ + ? NULL : malloc(sz)) + +#define vect_malloc_rect(sz) vect_malloc(VECT_FAIL_ID_RECT, sz) +#define vect_malloc_hexagon(sz) vect_malloc(VECT_FAIL_ID_HEXAGON, sz) +#define vect_malloc_circle(sz) vect_malloc(VECT_FAIL_ID_CIRCLE, sz) +#define vect_malloc_str(sz) vect_malloc(VECT_FAIL_ID_STR, sz) +#define vect_malloc_substr(sz) vect_malloc(VECT_FAIL_ID_SUBSTR, sz) +#define vect_malloc_hdr(sz) vect_malloc(VECT_FAIL_ID_HDR, sz) +#else +#define vect_malloc_rect(sz) malloc(sz) +#define vect_malloc_hexagon(sz) malloc(sz) +#define vect_malloc_circle(sz) malloc(sz) +#define vect_malloc_str(sz) malloc(sz) +#define vect_malloc_substr(sz) malloc(sz) +#define vect_malloc_hdr(sz) malloc(sz) +#endif + INTERNAL int zint_ps_plot(struct zint_symbol *symbol); INTERNAL int zint_svg_plot(struct zint_symbol *symbol); INTERNAL int zint_emf_plot(struct zint_symbol *symbol, int rotate_angle); @@ -49,7 +86,7 @@ static int vector_add_rect(struct zint_symbol *symbol, const float x, const floa assert(width >= 0.0f); assert(height >= 0.0f); - if (!(rect = (struct zint_vector_rect *) malloc(sizeof(struct zint_vector_rect)))) { + if (!(rect = (struct zint_vector_rect *) vect_malloc_rect(sizeof(struct zint_vector_rect)))) { /* NOTE: clang-tidy-20 gets confused about return value of function returning a function unfortunately, so put on 2 lines (see also "postal.c" `postnet_enc()` & `planet_enc()`, same issue) */ z_errtxt(0, symbol, 691, "Insufficient memory for vector rectangle"); @@ -84,7 +121,7 @@ static int vector_add_hexagon(struct zint_symbol *symbol, const float x, const f assert(y >= 0.0f); assert(diameter >= 0.0f); - if (!(hexagon = (struct zint_vector_hexagon *) malloc(sizeof(struct zint_vector_hexagon)))) { + if (!(hexagon = (struct zint_vector_hexagon *) vect_malloc_hexagon(sizeof(struct zint_vector_hexagon)))) { return z_errtxt(0, symbol, 692, "Insufficient memory for vector hexagon"); } #ifdef ZINT_SANITIZEM /* Suppress clang -fsanitize=memory false positive */ @@ -107,7 +144,7 @@ static int vector_add_hexagon(struct zint_symbol *symbol, const float x, const f } static int vector_add_circle(struct zint_symbol *symbol, const float x, const float y, const float diameter, - const float width, const int colour, struct zint_vector_circle **last_circle) { + const float width, struct zint_vector_circle **last_circle) { struct zint_vector_circle *circle; assert(x >= 0.0f); @@ -115,7 +152,7 @@ static int vector_add_circle(struct zint_symbol *symbol, const float x, const fl assert(diameter >= 0.0f); assert(width >= 0.0f); - if (!(circle = (struct zint_vector_circle *) malloc(sizeof(struct zint_vector_circle)))) { + if (!(circle = (struct zint_vector_circle *) vect_malloc_circle(sizeof(struct zint_vector_circle)))) { return z_errtxt(0, symbol, 693, "Insufficient memory for vector circle"); } #ifdef ZINT_SANITIZEM /* Suppress clang -fsanitize=memory false positive */ @@ -126,7 +163,7 @@ static int vector_add_circle(struct zint_symbol *symbol, const float x, const fl circle->y = y; circle->diameter = diameter; circle->width = width; - circle->colour = colour; + circle->colour = 0; /* Legacy (was zero for draw with foreground colour (else draw with background colour) */ if (*last_circle) (*last_circle)->next = circle; @@ -147,7 +184,7 @@ static int vector_add_string(struct zint_symbol *symbol, const unsigned char *te assert(y >= 0.0f); assert(width >= 0.0f); - if (!(string = (struct zint_vector_string *) malloc(sizeof(struct zint_vector_string)))) { + if (!(string = (struct zint_vector_string *) vect_malloc_str(sizeof(struct zint_vector_string)))) { return z_errtxt(0, symbol, 694, "Insufficient memory for vector string"); } #ifdef ZINT_SANITIZEM /* Suppress clang -fsanitize=memory false positive */ @@ -161,7 +198,7 @@ static int vector_add_string(struct zint_symbol *symbol, const unsigned char *te string->length = length == -1 ? (int) z_ustrlen(text) : length; string->rotation = 0; string->halign = halign; - if (!(string->text = (unsigned char *) malloc(string->length + 1))) { + if (!(string->text = (unsigned char *) vect_malloc_substr(string->length + 1))) { free(string); return z_errtxt(0, symbol, 695, "Insufficient memory for vector string text"); } @@ -478,7 +515,7 @@ INTERNAL int zint_plot_vector(struct zint_symbol *symbol, int rotate_angle, int } /* Allocate memory */ - if (!(vector = symbol->vector = (struct zint_vector *) malloc(sizeof(struct zint_vector)))) { + if (!(vector = symbol->vector = (struct zint_vector *) vect_malloc_hdr(sizeof(struct zint_vector)))) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 696, "Insufficient memory for vector header"); } #ifdef ZINT_SANITIZEM /* Suppress clang -fsanitize=memory false positive */ @@ -562,9 +599,7 @@ INTERNAL int zint_plot_vector(struct zint_symbol *symbol, int rotate_angle, int if (addon_len && large_bar_height + textoffset - (font_height + text_gap_antialias) < 1.0f) { addon_min_row_height = 1.0f - (large_bar_height + textoffset - (font_height + text_gap_antialias)); - if (addon_min_row_height > 1.0f) { - addon_min_row_height = 1.0f; - } + assert(addon_min_row_height <= 1.0f); /* Due to checks above */ } vector->height = symbol->height + textoffset + addon_min_row_height + dot_overspill + (yoffset + boffset); @@ -593,15 +628,15 @@ INTERNAL int zint_plot_vector(struct zint_symbol *symbol, int rotate_angle, int bull_d_incr = (hex_diameter * 9 - hex_ydiameter) / 5.0f; bull_width = bull_d_incr / 2.0f; - if (!vector_add_circle(symbol, bull_x, bull_y, hex_ydiameter + bull_d_incr * 5 - bull_width, bull_width, 0, + if (!vector_add_circle(symbol, bull_x, bull_y, hex_ydiameter + bull_d_incr * 5 - bull_width, bull_width, &last_circle)) { return ZINT_ERROR_MEMORY; } - if (!vector_add_circle(symbol, bull_x, bull_y, hex_ydiameter + bull_d_incr * 3 - bull_width, bull_width, 0, + if (!vector_add_circle(symbol, bull_x, bull_y, hex_ydiameter + bull_d_incr * 3 - bull_width, bull_width, &last_circle)) { return ZINT_ERROR_MEMORY; } - if (!vector_add_circle(symbol, bull_x, bull_y, hex_ydiameter + bull_d_incr - bull_width, bull_width, 0, + if (!vector_add_circle(symbol, bull_x, bull_y, hex_ydiameter + bull_d_incr - bull_width, bull_width, &last_circle)) { return ZINT_ERROR_MEMORY; } @@ -626,7 +661,7 @@ INTERNAL int zint_plot_vector(struct zint_symbol *symbol, int rotate_angle, int for (i = 0; i < symbol->width; i++) { if (z_module_is_set(symbol, r, i)) { if (!vector_add_circle(symbol, i + dot_offset + xoffset, r + dot_offset + yoffset, - symbol->dot_size, 0, 0, &last_circle)) { + symbol->dot_size, 0 /*diameter*/, &last_circle)) { return ZINT_ERROR_MEMORY; } } @@ -666,9 +701,7 @@ INTERNAL int zint_plot_vector(struct zint_symbol *symbol, int rotate_angle, int if (r == symbol->rows - 1 && i > main_width && addon_latch == 0) { addon_text_yposn = yposn + font_height - digit_ascender; - if (addon_text_yposn < 0.0f) { - addon_text_yposn = 0.0f; - } + assert(addon_text_yposn >= 0.0f); addon_row_yposn = yposn + font_height + text_gap_antialias; addon_row_height = row_height - (addon_row_yposn - yposn); /* Following ISO/IEC 15420:2009 Figure 5 — UPC-A bar code symbol with 2-digit add-on (contrary to diff --git a/backend/zint.h b/backend/zint.h index 27eef85f..bec95839 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -77,7 +77,7 @@ extern "C" { float x, y; /* Centre */ float diameter; /* Circle diameter. Does not include width (if any) */ float width; /* Width of circle perimeter (circumference). 0 for fill (disc) */ - int colour; /* Zero for draw with foreground colour (else draw with background colour (legacy)) */ + int colour; /* Legacy, no longer used (set to 0) */ struct zint_vector_circle *next; /* Pointer to next circle */ }; @@ -366,7 +366,6 @@ extern "C" { #define ZINT_CAP_HRT 0x0001 /* Prints Human Readable Text? */ #define ZINT_CAP_STACKABLE 0x0002 /* Is stackable? */ #define ZINT_CAP_EANUPC 0x0004 /* Is EAN/UPC? */ -#define ZINT_CAP_EXTENDABLE 0x0004 /* Legacy */ #define ZINT_CAP_COMPOSITE 0x0008 /* Can have composite data? */ #define ZINT_CAP_ECI 0x0010 /* Supports Extended Channel Interpretations? */ #define ZINT_CAP_GS1 0x0020 /* Supports GS1 data? */ @@ -380,6 +379,9 @@ extern "C" { #define ZINT_CAP_COMPLIANT_HEIGHT 0x2000 /* Has compliant height? */ #define ZINT_CAP_BINDABLE 0x4000 /* Can set row separators? */ +/* Legacy capability flag name */ +#define ZINT_CAP_EXTENDABLE ZINT_CAP_EANUPC + /* The largest amount of data that can be encoded is 4350 4-byte UTF-8 chars in Han Xin Code */ #define ZINT_MAX_DATA_LEN 17400 /* Maximum number of segments allowed for (`seg_count`) */ diff --git a/backend_qt/qzint.cpp b/backend_qt/qzint.cpp index 5361fa2e..0665553e 100644 --- a/backend_qt/qzint.cpp +++ b/backend_qt/qzint.cpp @@ -125,25 +125,6 @@ namespace Zint { return color; } - /* Helper to convert ECI combo index to ECI value */ - static int ECIIndexToECI(const int ECIIndex) { - int ret; - if (ECIIndex >= 1 && ECIIndex <= 11) { - ret = ECIIndex + 2; - } else if (ECIIndex >= 12 && ECIIndex <= 15) { - ret = ECIIndex + 3; - } else if (ECIIndex >= 16 && ECIIndex <= 31) { - ret = ECIIndex + 4; - } else if (ECIIndex == 32) { - ret = 170; /* ISO 646 Invariant */ - } else if (ECIIndex == 33) { - ret = 899; /* 8-bit binary data */ - } else { - ret = 0; - } - return ret; - } - /* Helper to calculate max right and bottom of elements for fudging `render()` */ static void getMaxRectsRightBottom(struct zint_vector *vector, int &maxRight, int &maxBottom) { struct zint_vector_rect *rect; @@ -184,7 +165,8 @@ namespace Zint { /* Segment constructors */ QZintSeg::QZintSeg() : m_eci(0) {} - QZintSeg::QZintSeg(const QString& text, const int ECIIndex) : m_text(text), m_eci(ECIIndexToECI(ECIIndex)) {} + QZintSeg::QZintSeg(const QString& text, const int ECIIndex) + : m_text(text), m_eci(QZint::ECIIndexToECIValue(ECIIndex)) {} QZint::QZint() : m_zintSymbol(nullptr), m_symbol(BARCODE_CODE128), m_input_mode(UNICODE_MODE), @@ -224,6 +206,7 @@ namespace Zint { ZBarcode_Delete(m_zintSymbol); } + /* private: Reset the symbol structure for encoding using member fields */ bool QZint::resetSymbol() { m_error = 0; m_lastError.clear(); @@ -302,6 +285,7 @@ namespace Zint { return true; } + /* private: `ZBarcode_Encode_and_Buffer_Vector()` or `ZBarcode_Encode_Segs_and_Buffer_Vector()` */ void QZint::encode() { if (resetSymbol()) { if (m_segs.empty()) { @@ -344,6 +328,49 @@ namespace Zint { } } + /* private: Helper to convert `m_segs` to `struct zint_seg[]` */ + int QZint::convertSegs(struct zint_seg segs[], std::vector& bstrs) { + bstrs.reserve(m_segs.size()); + int i; + for (i = 0; i < (int) m_segs.size() && i < maxSegs && !m_segs[i].m_text.isEmpty(); i++) { + segs[i].eci = m_segs[i].m_eci; + bstrs.push_back(m_segs[i].m_text.toUtf8()); + segs[i].source = (unsigned char *) bstrs.back().data(); + segs[i].length = (int) bstrs.back().length(); + } + return i; + } + + /* private: static: Convert `zint_vector_rect->colour` to Qt color */ + Qt::GlobalColor QZint::colourToQtColor(int colour) { + switch (colour) { + case 1: // Cyan + return Qt::cyan; + break; + case 2: // Blue + return Qt::blue; + break; + case 3: // Magenta + return Qt::magenta; + break; + case 4: // Red + return Qt::red; + break; + case 5: // Yellow + return Qt::yellow; + break; + case 6: // Green + return Qt::green; + break; + case 8: // White + return Qt::white; + break; + default: + return Qt::black; + break; + } + } + /* Symbology to use (see BARCODE_XXX) */ int QZint::symbol() const { return m_symbol; @@ -577,6 +604,13 @@ namespace Zint { } } + void QZint::setBorderTypeValue(int borderType) { // Sets literal value + if (borderType != BARCODE_BIND && borderType != BARCODE_BOX && borderType != BARCODE_BIND_TOP) { + borderType = 0; + } + m_borderType = borderType; + } + /* Size of border in X-dimensions */ int QZint::borderWidth() const { return m_borderWidth; @@ -721,7 +755,7 @@ namespace Zint { } void QZint::setECI(int ECIIndex) { // Sets from comboBox index - m_eci = ECIIndexToECI(ECIIndex); + m_eci = ECIIndexToECIValue(ECIIndex); } void QZint::setECIValue(int eci) { // Sets literal value @@ -849,6 +883,14 @@ namespace Zint { return m_encodedOption3; } + int QZint::encodedInputMode() const { // Read-only, `input_mode` + return m_input_mode; + } + + int QZint::encodedOutputOptions() const { // Read-only, `output_options` + return m_zintSymbol->output_options; + } + /* Legacy property getters/setters */ void QZint::setWidth(int width) { setOption2(width); } int QZint::width() const { return m_option_2; } @@ -941,7 +983,7 @@ namespace Zint { break; default: return (symbology >= BARCODE_EANX_CC && symbology <= BARCODE_DBAR_EXPSTK_CC) - || symbology == BARCODE_EAN8_CC || symbology == BARCODE_EAN13_CC; + || symbology == BARCODE_EAN8_CC || symbology == BARCODE_EAN13_CC; break; } } @@ -961,6 +1003,7 @@ namespace Zint { return m_lastError.length(); } + /* Encode and print barcode to file `filename`. Only sets `getError()` on error, not on warning */ bool QZint::save_to_file(const QString& filename) { if (resetSymbol()) { cpy_bytearray_left(m_zintSymbol->outfile, filename.toUtf8(), ARRAY_SIZE(m_zintSymbol->outfile) - 1); @@ -985,6 +1028,8 @@ namespace Zint { return true; } + /* Encode and print barcode to memory file `filename` (only the extension is used, to determine output format). + Only sets `getError()` on error, not on warning */ bool QZint::save_to_memfile(const QString& filename, QByteArray& data) { if (resetSymbol()) { m_zintSymbol->output_options |= BARCODE_MEMORY_FILE; @@ -1012,49 +1057,6 @@ namespace Zint { return true; } - /* Convert `zint_vector_rect->colour` to Qt color */ - Qt::GlobalColor QZint::colourToQtColor(int colour) { - switch (colour) { - case 1: // Cyan - return Qt::cyan; - break; - case 2: // Blue - return Qt::blue; - break; - case 3: // Magenta - return Qt::magenta; - break; - case 4: // Red - return Qt::red; - break; - case 5: // Yellow - return Qt::yellow; - break; - case 6: // Green - return Qt::green; - break; - case 8: // White - return Qt::white; - break; - default: - return Qt::black; - break; - } - } - - /* Helper to convert `m_segs` to `struct zint_seg[]` */ - int QZint::convertSegs(struct zint_seg segs[], std::vector& bstrs) { - bstrs.reserve(m_segs.size()); - int i; - for (i = 0; i < (int) m_segs.size() && i < maxSegs && !m_segs[i].m_text.isEmpty(); i++) { - segs[i].eci = m_segs[i].m_eci; - bstrs.push_back(m_segs[i].m_text.toUtf8()); - segs[i].source = (unsigned char *) bstrs.back().data(); - segs[i].length = (int) bstrs.back().length(); - } - return i; - } - /* Encode and display barcode in `paintRect` using `painter`. Note: legacy argument `mode` is not used */ void QZint::render(QPainter& painter, const QRectF& paintRect, AspectRatioMode /*mode*/) { @@ -1276,7 +1278,45 @@ namespace Zint { return true; } - /* Return the BARCODE_XXX name of `symbology` */ + /* static: Convert literal ECI to ECI combobox index */ + int QZint::ECIValueToECIIndex(const int eci) { + int ret; + if (eci >= 3 && eci <= 13) { + ret = eci - 2; + } else if (eci >= 15 && eci <= 18) { + ret = eci - 3; + } else if (eci >= 20 && eci <= 35) { + ret = eci - 4; + } else if (eci == 170) { + ret = 32; + } else if (eci == 899) { + ret = 33; + } else { + ret = 0; + } + return ret; + } + + /* static: Convert ECI combo index to literal ECI */ + int QZint::ECIIndexToECIValue(const int ECIIndex) { + int ret; + if (ECIIndex >= 1 && ECIIndex <= 11) { + ret = ECIIndex + 2; + } else if (ECIIndex >= 12 && ECIIndex <= 15) { + ret = ECIIndex + 3; + } else if (ECIIndex >= 16 && ECIIndex <= 31) { + ret = ECIIndex + 4; + } else if (ECIIndex == 32) { + ret = 170; /* ISO 646 Invariant */ + } else if (ECIIndex == 33) { + ret = 899; /* 8-bit binary data */ + } else { + ret = 0; + } + return ret; + } + + /* static: Return the BARCODE_XXX name of `symbology` */ QString QZint::barcodeName(const int symbology) { char buf[32]; if (ZBarcode_BarcodeName(symbology, buf) == 0) { @@ -1285,17 +1325,17 @@ namespace Zint { return QSEmpty; } - /* Whether Zint library "libzint" built with PNG support or not */ + /* static: Whether Zint library "libzint" built with PNG support or not */ bool QZint::noPng() { return ZBarcode_NoPng() == 1; } - /* Whether Zint library "libzint" built with PNG support or not */ + /* static: Whether Zint library "libzint" built with PNG support or not */ bool QZint::haveGS1SyntaxEngine() { return ZBarcode_HaveGS1SyntaxEngine() == 1; } - /* Version of Zint library "libzint" linked to */ + /* static: Version of Zint library "libzint" linked to */ int QZint::getVersion() { return ZBarcode_Version(); } @@ -1545,7 +1585,7 @@ namespace Zint { return cmd; } - /* `getAsCLI()` helpers */ + /* private: static: `getAsCLI()` helpers */ void QZint::arg_str(QString& cmd, const char *const opt, const QString& val) { if (!val.isEmpty()) { QByteArray bstr = val.toUtf8(); @@ -1553,18 +1593,21 @@ namespace Zint { } } + /* private: static: */ void QZint::arg_int(QString& cmd, const char *const opt, const int val, const bool allowZero) { if (val > 0 || (val == 0 && allowZero)) { cmd += QString::asprintf(" %s%d", opt, val); } } + /* private: static: */ void QZint::arg_bool(QString& cmd, const char *const opt, const bool val) { if (val) { cmd += QString::asprintf(" %s", opt); } } + /* private: static: */ void QZint::arg_data(QString& cmd, const char *const opt, const QString& val, const bool win) { if (!val.isEmpty()) { QString text(val); @@ -1572,12 +1615,14 @@ namespace Zint { } } + /* private: static: */ void QZint::arg_seg(QString& cmd, const int seg_no, const QZintSeg& val, const bool win) { QString text(val.m_text); QString opt = QString::asprintf("--seg%d=%d,", seg_no, val.m_eci); arg_data_esc(cmd, opt.toUtf8(), text, win); } + /* private: static: */ void QZint::arg_data_esc(QString& cmd, const char *const opt, QString& text, const bool win) { const char delim = win ? '"' : '\''; if (win) { @@ -1594,12 +1639,14 @@ namespace Zint { } } + /* private: static: */ void QZint::arg_float(QString& cmd, const char *const opt, const float val, const bool allowZero) { if (val > 0 || (val == 0 && allowZero)) { cmd += QString::asprintf(" %s%g", opt, val); } } + /* private: static: */ void QZint::arg_structapp(QString& cmd, const char *const opt, const int count, const int index, const QString& id, const bool win) { if (count >= 2 && index >= 1) { @@ -1613,6 +1660,7 @@ namespace Zint { } } + /* private: static: */ void QZint::arg_scalexdimdp(QString& cmd, const char *const opt, const float scale, const float dpmm, const int symbol, const QZintXdimDpVars *xdimdpVars) { if (dpmm) { @@ -1635,7 +1683,7 @@ namespace Zint { } } - /* Helper to return "GIF"/"SVG"(/"EMF") if `msg` false, "raster"/"vector"(/"EMF") otherwise + /* static: Helper to return "GIF"/"SVG"(/"EMF") if `msg` false, "raster"/"vector"(/"EMF") otherwise (EMF only if `symbol` is MaxiCode) */ const char *QZintXdimDpVars::getFileType(int symbol, const struct QZintXdimDpVars *vars, bool msg) { static const char *filetypes[3] = { "GIF", "SVG", "EMF" }; @@ -1643,8 +1691,9 @@ namespace Zint { if (!vars) return ""; - const int idx = std::max(std::min(symbol == BARCODE_MAXICODE ? vars->filetype_maxicode - : vars->filetype, 2), 0); + const int filetype = symbol == BARCODE_MAXICODE ? vars->filetype_maxicode : vars->filetype; + const int max = symbol == BARCODE_MAXICODE ? 2 : 1; + const int idx = std::max(std::min(filetype, max), 0); return msg ? msg_types[idx] : filetypes[idx]; } } /* namespace Zint */ diff --git a/backend_qt/qzint.h b/backend_qt/qzint.h index 294b0363..f4741a83 100644 --- a/backend_qt/qzint.h +++ b/backend_qt/qzint.h @@ -146,7 +146,8 @@ public: /* Type of border above/below/around barcode */ int borderType() const; // `symbol->output_options | BARCODE_BIND | BARCODE_BOX | BARCODE_BIND_TOP` - void setBorderType(int borderTypeIndex); + void setBorderType(int borderTypeIndex); // Sets from comboBox index + void setBorderTypeValue(int borderType); // Sets literal value /* Size of border in X-dimensions */ int borderWidth() const; // `symbol->border_width` @@ -246,6 +247,8 @@ public: int encodedOption1() const; // Read-only, encoded `option_1` int encodedOption2() const; // Read-only, encoded `option_2` int encodedOption3() const; // Read-only, encoded `option_3` + int encodedInputMode() const; // Read-only, `input_mode` + int encodedOutputOptions() const; // Read-only, `output_options` /* Legacy property getters/setters */ @@ -323,6 +326,12 @@ public: bool getWidthHeightXdim(float x_dim, float &width_x_dim, float &height_x_dim) const; + /* Convert literal ECI to ECI combobox index */ + static int ECIValueToECIIndex(const int eci); + + /* Convert ECI combo index to literal ECI */ + static int ECIIndexToECIValue(const int ECIIndex); + /* Return the BARCODE_XXX name of `symbology` */ static QString barcodeName(const int symbology); // `ZBarcode_BarcodeName()` diff --git a/backend_qt/tests/test_qzint.cpp b/backend_qt/tests/test_qzint.cpp index 9a8f5ef2..ea90c146 100644 --- a/backend_qt/tests/test_qzint.cpp +++ b/backend_qt/tests/test_qzint.cpp @@ -94,8 +94,7 @@ private slots: std::vector segs; for (int i = 0; i < (int) segTexts.size(); i++) { - segs.push_back(Zint::QZintSeg(segTexts[i])); - segs.back().m_eci = segECIs[i]; + segs.push_back({segTexts[i], Zint::QZint::ECIValueToECIIndex(segECIs[i])}); } bc.setSegs(segs); @@ -191,11 +190,16 @@ private slots: for (int i = 0; i < ARRAY_SIZE(borderTypes); i++) { bc.setBorderType(i); QCOMPARE(bc.borderType(), borderTypes[i]); + + bc.setBorderTypeValue(borderTypes[i]); + QCOMPARE(bc.borderType(), borderTypes[i]); } int borderWidth = 4; bc.setBorderWidth(borderWidth); QCOMPARE(bc.borderWidth(), borderWidth); + bc.setBorderWidth(-1); + QCOMPARE(bc.borderWidth(), 0); int whitespace = 5; bc.setWhitespace(whitespace); @@ -328,6 +332,26 @@ private slots: QCOMPARE(bc.takesGS1AIData(BARCODE_CODE128), false); QCOMPARE(bc.takesGS1AIData(BARCODE_GS1_128), true); + QCOMPARE(bc.takesGS1AIData(BARCODE_EAN8_CC), true); + QCOMPARE(bc.takesGS1AIData(0), false); + + QCOMPARE(symbology, BARCODE_CODE11); + + float defaultXdim = 0.495f; + QCOMPARE(bc.defaultXdim(), defaultXdim); + QCOMPARE(bc.defaultXdim(symbology), defaultXdim); + + scale = 3.0f; + QString fileType(Zint::QZint::noPng() ? "gif" : "png"); + float x_dim_mm = 0.5f; + dpmm = 12.0f; + QCOMPARE(bc.getScaleFromXdimDp(x_dim_mm, dpmm, fileType, symbology), scale); + + QCOMPARE(bc.getXdimDpFromScale(scale, x_dim_mm, fileType), dpmm); + QCOMPARE(bc.getXdimDpFromScale(scale, dpmm, fileType), x_dim_mm); + + float width_x_dim, height_x_dim; + QCOMPARE(bc.getWidthHeightXdim(x_dim_mm, width_x_dim, height_x_dim), false); } void setGetECIValueTest_data() @@ -452,10 +476,21 @@ private slots: void renderTest_data() { QTest::addColumn("symbology"); + QTest::addColumn("inputMode"); QTest::addColumn("text"); QTest::addColumn("scale"); + QTest::addColumn("fgStr"); + QTest::addColumn("bgStr"); + QTest::addColumn("borderType"); + QTest::addColumn("borderWidth"); + QTest::addColumn("quietZones"); + QTest::addColumn("rotateAngle"); + QTest::addColumn("getError"); QTest::addColumn("error_message"); + + QTest::addColumn("encodedInputMode"); + QTest::addColumn("encodedOutputOptions"); QTest::addColumn("encodedWidth"); QTest::addColumn("encodedRows"); QTest::addColumn("encodedHeight"); @@ -465,21 +500,54 @@ private slots: QTest::addColumn("vectorWidth"); QTest::addColumn("vectorHeight"); - QTest::newRow("BARCODE_CODE128") << BARCODE_CODE128 << "1234" << 0.0f << 0 << "" << 57 << 1 << 50.0f << -1 << 0 << 0 << 114.0f << 100.0f; - QTest::newRow("BARCODE_CODE128 Scale 2") << BARCODE_CODE128 << "1234" << 2.0f << 0 << "" << 57 << 1 << 50.0f << -1 << 0 << 0 << 228.0f << 200.0f; - QTest::newRow("BARCODE_QRCODE") << BARCODE_QRCODE << "1234" << 0.0f << 0 << "" << 21 << 21 << 21.0f << 4 << 1 << (7 << 8) << 42.0f << 42.0f; - QTest::newRow("BARCODE_QRCODE Scale 1.5") << BARCODE_QRCODE << "1234" << 1.5f << 0 << "" << 21 << 21 << 21.0f << 4 << 1 << (7 << 8) << 63.0f << 63.0f; + QTest::addColumn("getWidthHeightXdim"); + QTest::addColumn("xdimWidth"); + QTest::addColumn("xdimHeight"); + + QTest::newRow("BARCODE_CODE128") << BARCODE_CODE128 << UNICODE_MODE << "1234" << 0.0f + << "" << "" << 0 << 0 << false << 0 << 0 << "" + << UNICODE_MODE << 0 << 57 << 1 << 50.0f << -1 << 0 << 0 << 114.0f << 100.0f + << true << 28.215f << 24.75f; + QTest::newRow("BARCODE_CODE128 Scale 2") << BARCODE_CODE128 << UNICODE_MODE << "1234" << 2.0f + << "" << "" << 0 << 0 << false << 0 << 0 << "" + << UNICODE_MODE << 0 << 57 << 1 << 50.0f << -1 << 0 << 0 << 228.0f << 200.0f + << true << 28.215f << 24.75f; + QTest::newRow("BARCODE_QRCODE") << BARCODE_QRCODE << UNICODE_MODE << "1234" << 0.0f + << "" << "" << 0 << 0 << false << 0 << 0 << "" + << UNICODE_MODE << 0 << 21 << 21 << 21.0f << 4 << 1 << (7 << 8) << 42.0f << 42.0f + << true << 13.125f << 13.125f; + QTest::newRow("BARCODE_QRCODE Scale 1.5") << BARCODE_QRCODE << UNICODE_MODE << "1234" << 1.5f + << "" << "" << 0 << 0 << false << 0 << 0 << "" + << UNICODE_MODE << 0 << 21 << 21 << 21.0f << 4 << 1 << (7 << 8) << 63.0f << 63.0f + << true << 13.125f << 13.125f; if (!m_skipIfFontUsed) { - QTest::newRow("BARCODE_QRCODE no text") << BARCODE_QRCODE << "" << 0.0f << ZINT_ERROR_INVALID_DATA << "Error 228: No input data (segment 0 empty)" << 0 << 0 << 0.0f << -1 << 0 << 0 << 0.0f << 0.0f; + QTest::newRow("BARCODE_QRCODE no text") << BARCODE_QRCODE << UNICODE_MODE << "" << 0.0f + << "" << "" << 0 << 0 << false << 0 << ZINT_ERROR_INVALID_DATA + << "Error 228: No input data (segment 0 empty)" + << UNICODE_MODE << 0 << 0 << 0 << 0.0f << -1 << 0 << 0 << 0.0f << 0.0f + << false << 0.0f << 0.0f; } - QTest::newRow("BARCODE_MAXICODE") << BARCODE_MAXICODE << "1234" << 0.0f << 0 << "" << 30 << 33 << 28.578f << 4 << 0 << 0 << 60.0f << 57.7334f; - QTest::newRow("BARCODE_MAXICODE Scale 2") << BARCODE_MAXICODE << "1234" << 2.0f << 0 << "" << 30 << 33 << 28.578f << 4 << 0 << 0 << 120.0f << 115.467f; + QTest::newRow("BARCODE_MAXICODE") << BARCODE_MAXICODE << UNICODE_MODE << "1234" << 0.0f + << "808080" << "" << BARCODE_BOX << 1 << true << 0 << 0 << "" + << UNICODE_MODE << (BARCODE_BOX | BARCODE_QUIET_ZONES) << 30 << 33 << 28.578f + << 4 << 0 << 0 << 68.0f << 65.7334f + << true << 29.92f << 28.9227f; + QTest::newRow("BARCODE_MAXICODE Scale 2") << BARCODE_MAXICODE << UNICODE_MODE << "1234" << 2.0f + << "" << "808080" << 0 << 0 << false << 90 << 0 << "" + << UNICODE_MODE << 0 << 30 << 33 << 28.578f << 4 << 0 << 0 << 120.0f << 115.467f + << true << 25.4027f << 26.4f; + QTest::newRow("BARCODE_ULTRA") << BARCODE_ULTRA << UNICODE_MODE << "1234" << 0.0f + << "808080" << "" << BARCODE_BIND << 2 << true << 0 << 0 << "" + << UNICODE_MODE << (BARCODE_BIND | BARCODE_QUIET_ZONES) << 15 << 13 << 13.0f + << 3 << 0 << 0 << 34.0f << 38.0f + << true << 10.625f << 11.875f; } void renderTest() { #ifdef TESTQZINT_GUILESS - QSKIP("disabled on Linux for Qt5 > 5.15.13 & Qt6 > 6.4.2 due to memory leaks (ZINT_SANITIZE)", "" /*Dummy arg to suppress -Wc++20-extensions*/); + QSKIP("disabled on Linux for Qt5 > 5.15.13 & Qt6 > 6.4.2 due to memory leaks (ZINT_SANITIZE)", + "" /*Dummy arg to suppress -Wc++20-extensions*/); #endif Zint::QZint bc; @@ -495,10 +563,19 @@ private slots: mode = Zint::QZint::AspectRatioMode::KeepAspectRatio; // Legacy - ignored QFETCH(int, symbology); + QFETCH(int, inputMode); QFETCH(QString, text); QFETCH(float, scale); + QFETCH(QString, fgStr); + QFETCH(QString, bgStr); + QFETCH(int, borderType); + QFETCH(int, borderWidth); + QFETCH(bool, quietZones); + QFETCH(int, rotateAngle); QFETCH(int, getError); QFETCH(QString, error_message); + QFETCH(int, encodedInputMode); + QFETCH(int, encodedOutputOptions); QFETCH(int, encodedWidth); QFETCH(int, encodedRows); QFETCH(float, encodedHeight); @@ -507,13 +584,23 @@ private slots: QFETCH(int, encodedOption3); QFETCH(float, vectorWidth); QFETCH(float, vectorHeight); + QFETCH(bool, getWidthHeightXdim); + QFETCH(float, xdimWidth); + QFETCH(float, xdimHeight); bc.setSymbol(symbology); + bc.setInputMode(inputMode); bc.setText(text); bc.setShowText(false); if (scale) { bc.setScale(scale); } + bc.setFgStr(fgStr); + bc.setBgStr(bgStr); + bc.setBorderTypeValue(borderType); + bc.setBorderWidth(borderWidth); + bc.setQuietZones(quietZones); + bc.setRotateAngleValue(rotateAngle); bRet = painter.begin(&paintDevice); QCOMPARE(bRet, true); @@ -527,6 +614,8 @@ private slots: QCOMPARE(bc.error_message(), error_message); QCOMPARE(bc.lastError(), error_message); QCOMPARE(bc.hasErrors(), getError != 0); + QCOMPARE(bc.encodedInputMode(), encodedInputMode); + QCOMPARE(bc.encodedOutputOptions(), encodedOutputOptions); QCOMPARE(bc.encodedWidth(), encodedWidth); QCOMPARE(bc.encodedRows(), encodedRows); QCOMPARE(bc.encodedHeight(), encodedHeight); @@ -543,22 +632,36 @@ private slots: QCOMPARE(spyEncoded.count(), 1); QCOMPARE(spyErrored.count(), 0); } + + float x_dim = bc.defaultXdim(); + float width_x_dim, height_x_dim; + QCOMPARE(bc.getWidthHeightXdim(x_dim, width_x_dim, height_x_dim), getWidthHeightXdim); + QCOMPARE(width_x_dim, xdimWidth); + QCOMPARE(height_x_dim, xdimHeight); } void saveToFileTest_data() { QTest::addColumn("symbology"); QTest::addColumn("text"); + QTest::addColumn("eci"); + QTest::addColumn("seg1"); + QTest::addColumn("seg1_eci"); QTest::addColumn("fileName"); QTest::addColumn("expected_bRet"); - QTest::newRow("BARCODE_DATAMATRIX gif") << BARCODE_DATAMATRIX << "1234" << "test_save_to_file.gif" << true; - QTest::newRow("BARCODE_DATAMATRIX unknown format") << BARCODE_DATAMATRIX << "1234" << "test_save_to_file.ext" << false; - QTest::newRow("BARCODE_DATAMATRIX UTF8 gif") << BARCODE_DATAMATRIX << "1234" << "test_save_to_file_τ.gif" << true; - QTest::newRow("BARCODE_DATAMATRIX too long (unknown format)") << BARCODE_DATAMATRIX << "1234" + QTest::newRow("BARCODE_DATAMATRIX gif") << BARCODE_DATAMATRIX << "1234" << 0 << "" << 0 + << "test_save_to_file.gif" << true; + QTest::newRow("BARCODE_DATAMATRIX segs gif") << BARCODE_DATAMATRIX << "1234" << 26 << "5678" << 3 + << "test_save_to_file_segs.gif" << true; + QTest::newRow("BARCODE_DATAMATRIX unknown format") << BARCODE_DATAMATRIX << "1234" << 0 << "" << 0 + << "test_save_to_file.ext" << false; + QTest::newRow("BARCODE_DATAMATRIX UTF8 gif") << BARCODE_DATAMATRIX << "1234" << 0 << "" << 0 + << "test_save_to_file_τ.gif" << true; + QTest::newRow("BARCODE_DATAMATRIX too long (unknown format)") << BARCODE_DATAMATRIX << "1234" << 0 << "" << 0 << "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" - "1234567890123456789012345678901234567890123456789012.gif" // 256 long so should be truncated to end in ".gi" + "1234567890123456789012345678901234567890123456789012.gif" // 256 long so truncates to end in ".gi" << false; } @@ -570,11 +673,22 @@ private slots: QFETCH(int, symbology); QFETCH(QString, text); + QFETCH(int, eci); + QFETCH(QString, seg1); + QFETCH(int, seg1_eci); QFETCH(QString, fileName); QFETCH(bool, expected_bRet); bc.setSymbol(symbology); - bc.setText(text); + if (!seg1.isEmpty()) { + std::vector segs; + segs.push_back({text, Zint::QZint::ECIValueToECIIndex(eci)}); + segs.push_back({seg1, Zint::QZint::ECIValueToECIIndex(seg1_eci)}); + bc.setSegs(segs); + } else { + bc.setText(text); + bc.setECIValue(eci); + } bRet = bc.save_to_file(fileName); QCOMPARE(bRet, expected_bRet); @@ -589,18 +703,24 @@ private slots: { QTest::addColumn("symbology"); QTest::addColumn("text"); + QTest::addColumn("eci"); + QTest::addColumn("seg1"); + QTest::addColumn("seg1_eci"); QTest::addColumn("fileName"); QTest::addColumn("expected_bRet"); QTest::addColumn("expected_strData"); - QTest::newRow("BARCODE_DATAMATRIX gif") << BARCODE_DATAMATRIX << "1234" << "test_memfile.gif" << true + QTest::newRow("BARCODE_DATAMATRIX gif") << BARCODE_DATAMATRIX << "1234" << 0 << "" << 0 + << "test_memfile.gif" << true << "47494638376114001400f00000ffffff0000002c00000000140014000002" "3c4c00869ad7eb988c942168b2cef7eecf794e37594f776a285a862b8485" "ea49caf66a4ef10ca7204e010a69a24f6ff7231a5f351db3580149a7d44c" "01003b"; - QTest::newRow("BARCODE_DATAMATRIX svg") << BARCODE_DATAMATRIX << "1234" << "test_memfile.svg" << true + QTest::newRow("BARCODE_DATAMATRIX svg") << BARCODE_DATAMATRIX << "1234" << 0 << "" << 0 + << "test_memfile.svg" << true << "\n" - "\n" + "\n" "\n" " Zint Generated Symbol\n" " \n" @@ -611,6 +731,16 @@ private slots: " 14h2v2h-2ZM16 14h4v2h-4ZM0 16h2v2h-2ZM14 16h4v2h-4ZM0 18h20v2h-20Z\"/>\n" " \n" "\n"; + QTest::newRow("BARCODE_AZTEC gif") << BARCODE_AZTEC << "1234" << 3 << "5678" << 4 + << "test_memfile.gif" << true + << "47494638376126002600f00000ffffff0000002c00000000260026000002" + "b58411a97918b65a636e2e652196bacbfb3814a58d217980e519ae9ea972" + "622ba36b546f72b57fa09ecbf47e400eca96da1c81b85ed26459225d33a2" + "9565545eb79e1dd499a47ab1e0179346bda6b559d86ffdbd91854d9e94ed" + "13dbf1df3ed96d16b82788e3972528478836c803f7678538b3265738d718" + "76e9b4d4853915d4f948b905082a3a3a8969baa82ac49a4394985acae8b6" + "9947bb88747728cbc959f79b2b4cc7524ba37bfc681c5356e9c90ce6bc0a" + "5000003b"; } void saveToMemfileTest() @@ -621,24 +751,38 @@ private slots: QFETCH(int, symbology); QFETCH(QString, text); + QFETCH(int, eci); + QFETCH(QString, seg1); + QFETCH(int, seg1_eci); QFETCH(QString, fileName); QFETCH(bool, expected_bRet); QFETCH(QString, expected_strData); bc.setSymbol(symbology); - bc.setText(text); + if (!seg1.isEmpty()) { + std::vector segs; + segs.push_back({text, Zint::QZint::ECIValueToECIIndex(eci)}); + segs.push_back({seg1, Zint::QZint::ECIValueToECIIndex(seg1_eci)}); + bc.setSegs(segs); + } else { + bc.setText(text); + bc.setECIValue(eci); + } QByteArray data; bRet = bc.save_to_memfile(fileName, data); QCOMPARE(bRet, expected_bRet); if (bRet) { - QCOMPARE(bRet, true); if (fileName.endsWith(".eps") || fileName.endsWith(".svg") || fileName.endsWith(".txt")) { QCOMPARE(data, expected_strData); + QCOMPARE(bc.save_to_memfile(fileName, data), true); + QCOMPARE(data, expected_strData); } else { QByteArray expected_data = QByteArray::fromHex(expected_strData.toUtf8()); QCOMPARE(data, expected_data); + QCOMPARE(bc.save_to_memfile(fileName, data), true); + QCOMPARE(data, expected_data); } } } @@ -765,10 +909,10 @@ private slots: << 7 << false << false << false << false // eci-gs1SyntaxEngine << false << false << false << WARN_DEFAULT << false // readerInit-debug << 0.0 << 0 << 0 << 0 << 0 << 0 // xdimdp - << "zint -b 92 --bg=0,0,0,0 --cmyk --eci=7 -d '12345678Ж0%var%' --dotsize=0.9 --dotty --fg=71,0,40,44 --scale=4" - " --secure=1 --structapp='1,2,as\"dfa'\\''sdf' --vwhitesp=3 -w 2" - << "zint.exe -b 92 --bg=0,0,0,0 --cmyk --eci=7 -d \"12345678Ж0%var%\" --dotsize=0.9 --dotty --fg=71,0,40,44 --scale=4" - " --secure=1 --structapp=\"1,2,as\\\"dfa'sdf\" --vwhitesp=3 -w 2" + << "zint -b 92 --bg=0,0,0,0 --cmyk --eci=7 -d '12345678Ж0%var%' --dotsize=0.9 --dotty" + " --fg=71,0,40,44 --scale=4 --secure=1 --structapp='1,2,as\"dfa'\\''sdf' --vwhitesp=3 -w 2" + << "zint.exe -b 92 --bg=0,0,0,0 --cmyk --eci=7 -d \"12345678Ж0%var%\" --dotsize=0.9 --dotty" + " --fg=71,0,40,44 --scale=4 --secure=1 --structapp=\"1,2,as\\\"dfa'sdf\" --vwhitesp=3 -w 2" << "" << "" << "" << ""; QTest::newRow("BARCODE_C25INTER") << true << 0.0f << "" @@ -921,10 +1065,10 @@ private slots: << 0 << false << false << false << false // eci-gs1SyntaxEngine << true << false << false << WARN_DEFAULT << false // readerInit-debug << 0.0 << 0 << 0 << 0 << 0 << 0 // xdimdp - << "zint -b 74 --binary --border=4 --box --cols=5 --compliantheight -d 'T\\n\\xA0t\\\"' --esc --init" - " --rows=2 --scale=3 --separator=3" - << "zint.exe -b 74 --binary --border=4 --box --cols=5 --compliantheight -d \"T\\n\\xA0t\\\\\"\" --esc --init" - " --rows=2 --scale=3 --separator=3" + << "zint -b 74 --binary --border=4 --box --cols=5 --compliantheight -d 'T\\n\\xA0t\\\"' --esc" + " --init --rows=2 --scale=3 --separator=3" + << "zint.exe -b 74 --binary --border=4 --box --cols=5 --compliantheight -d \"T\\n\\xA0t\\\\\"\" --esc" + " --init --rows=2 --scale=3 --separator=3" << "" << "" << "" << ""; QTest::newRow("BARCODE_DAFT") << false << 0.0f << "" @@ -1019,8 +1163,10 @@ private slots: << 0 << false << false << true << true // eci-gs1SyntaxEngine << false << false << false << WARN_DEFAULT << false // readerInit-debug << 0.0 << 0 << 0 << 0 << 0 << 0 // xdimdp - << "zint -b 71 -d '010952012345678810BATCH4\\G2107' --dmb256=2 --esc --gs1raw --gs1strict --gssep --square" - << "zint.exe -b 71 -d \"010952012345678810BATCH4\\G2107\" --dmb256=2 --esc --gs1raw --gs1strict --gssep --square" + << "zint -b 71 -d '010952012345678810BATCH4\\G2107' --dmb256=2 --esc --gs1raw --gs1strict --gssep" + " --square" + << "zint.exe -b 71 -d \"010952012345678810BATCH4\\G2107\" --dmb256=2 --esc --gs1raw --gs1strict --gssep" + " --square" << "" << "" << "" << ""; QTest::newRow("BARCODE_DATAMATRIX") << false << 0.0f << "" @@ -1040,7 +1186,7 @@ private slots: << "" << "" << "" << ""; QTest::newRow("BARCODE_MAILMARK_2D") << false << 0.0f << "" - << BARCODE_DATAMATRIX << UNICODE_MODE // symbology-inputMode + << BARCODE_MAILMARK_2D << UNICODE_MODE // symbology-inputMode << "JGB 012100123412345678AB19XY1A 0 www.xyz.com" << "" // text-primary << 0.0f << 0 << 0 << DM_C40_START << 1.0f // height-scale << 0.0f << false << 0.7f << 1.0f // dpmm-textGap @@ -1051,8 +1197,8 @@ private slots: << 0 << false << false << false << false // eci-gs1SyntaxEngine << false << false << false << WARN_DEFAULT << false // readerInit-debug << 0.0 << 0 << 0 << 0 << 0 << 0 // xdimdp - << "zint -b 71 -d 'JGB 012100123412345678AB19XY1A 0 www.xyz.com' --dmc40=0 --rotate=90" - << "zint.exe -b 71 -d \"JGB 012100123412345678AB19XY1A 0 www.xyz.com\" --dmc40=0 --rotate=90" + << "zint -b 119 -d 'JGB 012100123412345678AB19XY1A 0 www.xyz.com' --dmc40=0 --rotate=90" + << "zint.exe -b 119 -d \"JGB 012100123412345678AB19XY1A 0 www.xyz.com\" --dmc40=0 --rotate=90" << "" << "" << "" << ""; QTest::newRow("BARCODE_DBAR_EXPSTK_CC") << false << 40.8f << "" @@ -1122,6 +1268,23 @@ private slots: << "" << "" << "" << "zint -b 96 --compliantheight -d '1234567890123456789012345678' --scalexdimdp=0.375mm,600dpi"; + QTest::newRow("BARCODE_DPD") << true << 0.0f << "" + << BARCODE_DPD << UNICODE_MODE // symbology-inputMode + << "1234567890123456789012345678" << "" // text-primary + << 0.0f << -1 << 0 << 0 << 4.5f // height-scale + << 24.0f << true << 0.8f << 1.0f // dpmm-textGap + << 0.0f << 0 << 0 << "" // guardDescent-structAppID + << "" << "" << QColor(Qt::black) << QColor(Qt::white) << false // fgStr-cmyk + << 3 << 3 << 0 << 0 << 0 // borderTypeIndex-fontSetting + << true << false << false << false << true << 0 // showText-rotateAngle + << 0 << false << false << false << false // eci-gs1SyntaxEngine + << false << false << false << WARN_DEFAULT << false // readerInit-debug + << 0.375 << 0 << 600 << 1 << 0 << 0 // xdimdp + << "zint -b 96 --compliantheight -d '1234567890123456789012345678' --scalexdimdp=0.375,24" + << "zint.exe -b 96 --compliantheight -d \"1234567890123456789012345678\" --scalexdimdp=0.375,24" + << "" << "" << "" + << "zint -b 96 --compliantheight -d '1234567890123456789012345678' --scalexdimdp=0.375mm,600dpi"; + QTest::newRow("BARCODE_EAN13") << true << 0.0f << "" << BARCODE_EAN13 << UNICODE_MODE // symbology-inputMode << "123456789012+12" << "" // text-primary @@ -1166,8 +1329,10 @@ private slots: << 0 << false << false << false << false // eci-gs1SyntaxEngine << false << true << true << WARN_DEFAULT << false // readerInit-debug << 0.0 << 0 << 0 << 0 << 0 << 0 // xdimdp - << "zint -b 15 --addongap=8 --compliantheight -d '123456789012+12' --embedfont --guarddescent=0 --guardwhitespace" - << "zint.exe -b 15 --addongap=8 --compliantheight -d \"123456789012+12\" --embedfont --guarddescent=0 --guardwhitespace" + << "zint -b 15 --addongap=8 --compliantheight -d '123456789012+12' --embedfont --guarddescent=0" + " --guardwhitespace" + << "zint.exe -b 15 --addongap=8 --compliantheight -d \"123456789012+12\" --embedfont --guarddescent=0" + " --guardwhitespace" << "" << "" << "" << ""; QTest::newRow("BARCODE_EANX (guardWhitespace/embedVectorFont") << true << 0.0f << "" @@ -1182,8 +1347,10 @@ private slots: << 0 << false << false << false << false // eci-gs1SyntaxEngine << false << true << true << WARN_DEFAULT << false // readerInit-debug << 0.0 << 0 << 0 << 0 << 0 << 0 // xdimdp - << "zint -b 13 --addongap=8 --compliantheight -d '123456789012+12' --embedfont --guarddescent=0 --guardwhitespace" - << "zint.exe -b 13 --addongap=8 --compliantheight -d \"123456789012+12\" --embedfont --guarddescent=0 --guardwhitespace" + << "zint -b 13 --addongap=8 --compliantheight -d '123456789012+12' --embedfont --guarddescent=0" + " --guardwhitespace" + << "zint.exe -b 13 --addongap=8 --compliantheight -d \"123456789012+12\" --embedfont --guarddescent=0" + " --guardwhitespace" << "" << "" << "" << ""; QTest::newRow("BARCODE_GRIDMATRIX") << false << 0.0f << "" @@ -1284,6 +1451,22 @@ private slots: << "zint.exe -b 89 --border=1 --compliantheight -d \"9212320967145\"" << "" << "" << "" << ""; + QTest::newRow("BARCODE_ITF14 (border)") << true << 0.0f << "" + << BARCODE_ITF14 << UNICODE_MODE // symbology-inputMode + << "9212320967145" << "" // text-primary + << 30.0f << -1 << 0 << 0 << 1.0f // height-scale + << 0.0f << false << 0.8f << 1.0f // dpmm-textGap + << 5.0f << 0 << 0 << "" // guardDescent-structAppID + << "" << "" << QColor(Qt::black) << QColor(Qt::white) << false // fgStr-cmyk + << 2 << 5 << 0 << 0 << 0 // borderTypeIndex-fontSetting + << true << false << false << false << true << 0 // showText-rotateAngle + << 0 << false << false << false << false // eci-gs1SyntaxEngine + << false << false << false << WARN_DEFAULT << false // readerInit-debug + << 0.0 << 0 << 0 << 0 << 0 << 0 // xdimdp + << "zint -b 89 --compliantheight -d '9212320967145'" + << "zint.exe -b 89 --compliantheight -d \"9212320967145\"" + << "" << "" << "" << ""; + QTest::newRow("BARCODE_MAXICODE") << true << 0.0f << "" << BARCODE_MAXICODE << (UNICODE_MODE | ESCAPE_MODE) // symbology-inputMode << "152382802840001" @@ -1297,10 +1480,10 @@ private slots: << 0 << false << false << false << false // eci-gs1SyntaxEngine << false << false << false << WARN_DEFAULT << false // readerInit-debug << 0.0 << 0 << 0 << 0 << 0 << 0 // xdimdp - << "zint -b 57 -d '1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G1 MAIN ST\\GTOWN\\GNY\\R\\E'" - " --esc --primary='152382802840001' --quietzones --scale=2.5 --scmvv=96" - << "zint.exe -b 57 -d \"1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G1 MAIN ST\\GTOWN\\GNY\\R\\E\"" - " --esc --primary=\"152382802840001\" --quietzones --scale=2.5 --scmvv=96" + << "zint -b 57 -d '1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G1 MAIN ST\\GTOWN\\GNY" + "\\R\\E' --esc --primary='152382802840001' --quietzones --scale=2.5 --scmvv=96" + << "zint.exe -b 57 -d \"1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G1 MAIN ST\\GTOWN\\GNY" + "\\R\\E\" --esc --primary=\"152382802840001\" --quietzones --scale=2.5 --scmvv=96" << "" << "" << "" << ""; QTest::newRow("BARCODE_MICROQR") << false << 0.0f << "" @@ -1421,10 +1604,12 @@ private slots: << 0 << false << true << true << true // eci-gs1SyntaxEngine << false << false << false << WARN_FAIL_ALL << false // readerInit-debug << 0.0 << 0 << 0 << 0 << 0 << 0 // xdimdp - << "zint -b 136 --compliantheight -d '1190122299ABCDE' --fg=EF2929 --gs1nocheck --gs1raw --gs1strict --guarddescent=6.5" - " --noquietzones -o 'out.svg' --primary='12345670+1234' --small --werror" - << "zint.exe -b 136 --compliantheight -d \"1190122299ABCDE\" --fg=EF2929 --gs1nocheck --gs1raw --gs1strict --guarddescent=6.5" - " --noquietzones -o \"out.svg\" --primary=\"12345670+1234\" --small --werror" + << "zint -b 136 --compliantheight -d '1190122299ABCDE' --fg=EF2929 --gs1nocheck --gs1raw" + " --gs1strict --guarddescent=6.5 --noquietzones -o 'out.svg' --primary='12345670+1234' --small" + " --werror" + << "zint.exe -b 136 --compliantheight -d \"1190122299ABCDE\" --fg=EF2929 --gs1nocheck --gs1raw" + " --gs1strict --guarddescent=6.5 --noquietzones -o \"out.svg\" --primary=\"12345670+1234\" --small" + " --werror" << "" << "" << "" << ""; QTest::newRow("BARCODE_VIN") << false << 2.0f << "" @@ -1643,19 +1828,20 @@ private slots: std::vector segs; for (int i = 0; i < (int) segTexts.size(); i++) { - segs.push_back(Zint::QZintSeg(segTexts[i])); - segs.back().m_eci = segECIs[i]; + segs.push_back({segTexts[i], Zint::QZint::ECIValueToECIIndex(segECIs[i])}); } bc.setSymbol(BARCODE_QRCODE); bc.setSegs(segs); bc.setDotty(true); - expected_cmd = "zint -b 58 --eci=9 -d 'Τεχτ' --seg1=3,'Téxt' --seg2=13,'กขฯ' --seg3=20,'貫やぐ禁' --dotty"; + expected_cmd = "zint -b 58 --eci=9 -d 'Τεχτ' --seg1=3,'Téxt' --seg2=13,'กขฯ' --seg3=20,'貫やぐ禁'" + " --dotty"; cmd = bc.getAsCLI(false /*win*/); QCOMPARE(cmd, expected_cmd); - expected_win = "zint.exe -b 58 --eci=9 -d \"Τεχτ\" --seg1=3,\"Téxt\" --seg2=13,\"กขฯ\" --seg3=20,\"貫やぐ禁\" --dotty"; + expected_win = "zint.exe -b 58 --eci=9 -d \"Τεχτ\" --seg1=3,\"Téxt\" --seg2=13,\"กขฯ\" --seg3=20,\"貫やぐ禁\"" + " --dotty"; cmd = bc.getAsCLI(true /*win*/); QCOMPARE(cmd, expected_win); } @@ -1666,11 +1852,16 @@ private slots: QTest::addColumn("rotateAngles"); QTest::addColumn("text"); - QTest::newRow("symbology=BARCODE_DATAMATRIX rotateAngles=0 text=1234") << BARCODE_DATAMATRIX << 0 << "1234"; - QTest::newRow("symbology=BARCODE_QRCODE rotateAngles=0 text=Hello%20World") << BARCODE_QRCODE << 0 << "Hello%20World"; - QTest::newRow("symbology=BARCODE_QRCODE rotateAngles=90 text=Hello%20World") << BARCODE_QRCODE << 90 << "Hello%20World"; - QTest::newRow("symbology=BARCODE_QRCODE rotateAngles=180 text=Hello%20World") << BARCODE_QRCODE << 180 << "Hello%20World"; - QTest::newRow("symbology=BARCODE_QRCODE rotateAngles=270 text=Hello%20World") << BARCODE_QRCODE << 270 << "Hello%20World"; + QTest::newRow("symbology=BARCODE_DATAMATRIX rotateAngles=0 text=1234") << BARCODE_DATAMATRIX + << 0 << "1234"; + QTest::newRow("symbology=BARCODE_QRCODE rotateAngles=0 text=Hello%20World") << BARCODE_QRCODE + << 0 << "Hello%20World"; + QTest::newRow("symbology=BARCODE_QRCODE rotateAngles=90 text=Hello%20World") << BARCODE_QRCODE + << 90 << "Hello%20World"; + QTest::newRow("symbology=BARCODE_QRCODE rotateAngles=180 text=Hello%20World") << BARCODE_QRCODE + << 180 << "Hello%20World"; + QTest::newRow("symbology=BARCODE_QRCODE rotateAngles=270 text=Hello%20World") << BARCODE_QRCODE + << 270 << "Hello%20World"; } void qZintAndLibZintEqualTest() @@ -1694,7 +1885,8 @@ private slots: qstrcpy(symbol->outfile, qUtf8Printable(fileNameForLibZint)); bc.save_to_file(fileNameForQZint); - ZBarcode_Encode_and_Print(symbol.data(), reinterpret_cast(qUtf8Printable(text)), 0, rotateAngles); + ZBarcode_Encode_and_Print(symbol.data(), reinterpret_cast(qUtf8Printable(text)), 0, + rotateAngles); QImage imageWrittenByVanilla(fileNameForLibZint); QImage imageWrittenByQZint(fileNameForQZint); @@ -1716,6 +1908,7 @@ private slots: QTest::newRow("BARCODE_MAXICODE") << BARCODE_MAXICODE << "BARCODE_MAXICODE"; QTest::newRow("BARCODE_CODE128AB") << BARCODE_CODE128AB << "BARCODE_CODE128AB"; QTest::newRow("BARCODE_CODE128B") << BARCODE_CODE128B << "BARCODE_CODE128AB"; + QTest::newRow("BARCODE_LAST") << 0 << ""; } void barcodeNameTest() @@ -1726,6 +1919,67 @@ private slots: QString name = Zint::QZint::barcodeName(symbology); QCOMPARE(name, expected_name); } + + void ECIIndexTest() + { + for (int i = 0; i < 900; i++) { + int eciIndex = Zint::QZint::ECIValueToECIIndex(i); + int eci = Zint::QZint::ECIIndexToECIValue(eciIndex); + QCOMPARE(eciIndex, Zint::QZint::ECIValueToECIIndex(eci)); + QCOMPARE(eci, Zint::QZint::ECIIndexToECIValue(eciIndex)); + if (i < 3 || (i > 35 && i != 170 && i != 899) || i == 14 || i == 19) { + QCOMPARE(eci, 0); + } else { + QCOMPARE(eci, i); + } + if (i == 40) { + i = 170 - 1; + } else if (i == 170) { + i = 899 - 1; + } + } + } + + void XdimDpVarsTest() + { + struct Zint::QZintXdimDpVars vars; + + int symbol = BARCODE_CODE128; + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, false /*msg*/), "GIF"); + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, true /*msg*/), "raster"); + + vars.filetype = 1; + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, false /*msg*/), "SVG"); + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, true /*msg*/), "vector"); + + vars.filetype = 2; + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, false /*msg*/), "SVG"); + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, true /*msg*/), "vector"); + + vars.filetype = -1; + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, false /*msg*/), "GIF"); + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, true /*msg*/), "raster"); + + symbol = BARCODE_MAXICODE; + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, false /*msg*/), "GIF"); + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, true /*msg*/), "raster"); + + vars.filetype_maxicode = 1; + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, false /*msg*/), "SVG"); + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, true /*msg*/), "vector"); + + vars.filetype_maxicode = 2; + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, false /*msg*/), "EMF"); + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, true /*msg*/), "EMF"); + + vars.filetype_maxicode = 3; + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, false /*msg*/), "EMF"); + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, true /*msg*/), "EMF"); + + vars.filetype_maxicode = -1; + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, false /*msg*/), "GIF"); + QCOMPARE(Zint::QZintXdimDpVars::getFileType(symbol, &vars, true /*msg*/), "raster"); + } }; #ifdef TESTQZINT_GUILESS diff --git a/docs/Makefile b/docs/Makefile index 73d13dc5..da8c1666 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -184,14 +184,14 @@ $(OUT_TXT) : $(SOURCE) $(SOURCE_MAN_PAGE) $(INCLUDES_TXT) $(INFRASTRUCTURE) -V $(MAIN_FONT) -V $(MONO_FONT) -V $(CJK_FONT) \ $(TXT_OPTS) \ -o $(OUT_TXT) - # Indent Man Page sections in TOC, remove trailing spaces, echoed image tags, tbl: hashes - # & clean up Table captions + # Indent Man Page sections in TOC, remove trailing spaces, tbl: hashes, + # clean up Table captions & prefix Figure nos. (https://stackoverflow.com/a/60073027) sed -i \ -e 's/^\(- [A-Z][A-Z ]*\)$$/ \1/' \ -e 's/ *$$//' \ - -e '/^\[.*\]$$/{N;N;s/\[\(.*\)\]\n\n\1/[\1]/;p;d}' \ -e 's/ *{#tbl:[^}]*}//' \ -e 's/^ : Table/ Table/' \ + -e '/^\[[^1-9].*$$/{x;s/.*/expr & + 1/e;x;G;s/^\[\(.*\)\n\(.*\)/[Figure \2: \1/}' \ $(OUT_TXT) # Wrap sed -i '/.\{81\}/{s/.\{80\}/&\n/}' $(OUT_TXT) diff --git a/docs/images/datamatrix_big5.svg b/docs/images/datamatrix_big5.svg index d24f457c..4457d37a 100644 --- a/docs/images/datamatrix_big5.svg +++ b/docs/images/datamatrix_big5.svg @@ -4,6 +4,6 @@ Zint Generated Symbol - + diff --git a/docs/images/gui_aztec.png b/docs/images/gui_aztec.png index 63523ac31c44f1d789e21db30c6ff17221b11958..ddb7704200a496be6d0c00ed42031cdc275eeb2e 100644 GIT binary patch delta 96916 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�oDXSjHE37|$rWo$J1{U|h?GxPg>A-W$f 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 delta 83425 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

  • Note that unless the --binary switch is -used, 8-bit binary data for ECI 899 must be given as UTF-8, e.g. a byte +used, 8-bit binary data for ECI 899 must be given as UTF-8, e.g. byte "\x80" must be represented as the 2 bytes "\xC2\x80"; similarly "\xC0" as "\xC3\x80", etc.FNC1 (except when the last AI).↩︎

  • -
  • BARCODE_MEMORY_FILE textual formats EPS and SVG will -have Unix newlines (LF) on both Windows and Unix, i.e. not CR+LF on -Windows.

    The --mirror option will replace control +characters (including DEL) and slash (/) with +an underscore (_). Additionally on Windows the characters +!, ", *, :, +<, >, ?, \ and +| will also be replaced with underscores, as they are +prohibited in filenames.↩︎

  • -
  • The height value is ignored for Aztec +

  • BARCODE_MEMORY_FILE textual formats EPS and SVG will +have Unix newlines (LF) on both Windows and Unix, i.e. not CR+LF on +Windows.↩︎

  • +
  • The height value is ignored for Aztec (including HIBC and Aztec Rune), Code One, Data Matrix (including HIBC), DotCode, Grid Matrix, Han Xin, MaxiCode, QR Code (including HIBC, Micro QR, rMQR and UPNQR), and Ultracode - all of which have a fixed width-to-height ratio (or, in the case of Code One, a fixed height).↩︎

  • -
  • For Windows, outfile is assumed to be -UTF-8 encoded.↩︎

  • +
  • For Windows, outfile is assumed to be +UTF-8 encoded.↩︎

  • -
  • The BARCODE_BIND_TOP flag is set by +

  • The BARCODE_BIND_TOP flag is set by default for DPD - see 6.1.10.7 DPD Code.↩︎

  • -
  • The BARCODE_BIND flag is always set for +href="#fnref16" class="footnote-back" role="doc-backlink">↩︎

  • +
  • The BARCODE_BIND flag is always set for Codablock F, Code 16K and Code 49. Special considerations apply to -ITF-14 - see 6.1.2.6 ITF-14.6.1.2.6 ITF-14.↩︎

  • -
  • Codablock F, Code 16K, Code 49, EAN-13, EAN-8, EAN/UPC +

  • Codablock F, Code 16K, Code 49, EAN-13, EAN-8, EAN/UPC add-ons, ISBN, ITF-14, UPC-A and UPC-E have compliant quiet zones added -by default.↩︎

  • -
  • ZINT_CAP_EANUPC was previously named +

  • ZINT_CAP_EANUPC was previously named ZINT_CAP_EXTENDABLE, which is still recognised.↩︎

  • -
  • DotCode, Han Xin, Micro QR Code, QR Code and UPNQR have -variable masks. Rectangular Micro QR Code has a fixed mask (4).↩︎

  • -
  • Except for Japanese Postal Code, whose check character -is not truly representable in the encoded data.

    DotCode, Han Xin, Micro QR Code, QR Code and UPNQR have +variable masks. Rectangular Micro QR Code has a fixed mask (4).↩︎

  • +
  • Except for Japanese Postal Code, whose check character +is not truly representable in the encoded data.↩︎

  • -
  • The library libzueci, which can convert +

  • The library libzueci, which can convert both to and from UTF-8 and ECI, is available at https://sourceforge.net/projects/libzueci/.↩︎

  • -
  • BARCODE_CODE128AB previously used the name -BARCODE_CODE128B, which is still recognised.↩︎

  • -
  • The DX number may be looked up in The (Modified) Big +

  • BARCODE_CODE128AB previously used the name +BARCODE_CODE128B, which is still recognised.↩︎

  • +
  • The DX number may be looked up in The (Modified) Big Film Database at https://thebigfilmdatabase.merinorus.com.↩︎

  • -
  • ASCII-compatible ECIs are ECIs 3 to 18 and 21 to 27 +href="#fnref24" class="footnote-back" role="doc-backlink">↩︎

  • +
  • ASCII-compatible ECIs are ECIs 3 to 18 and 21 to 27 (see Table 9: ECI Codes). Note in particular that ECI 899, 8-bit binary, is not considered ASCII-compatible.↩︎

  • +href="#fnref25" class="footnote-back" role="doc-backlink">↩︎

    diff --git a/docs/manual.pmd b/docs/manual.pmd index 41e77d35..49034d0a 100644 --- a/docs/manual.pmd +++ b/docs/manual.pmd @@ -444,9 +444,9 @@ meanings as given below: | Character | Effect | |:-------------------|:------------------------| -|`$` | Insert leading zeroes | -|`#` | Insert leading spaces | -|`*` | Insert leading asterisks| +|`$` (dollar) | Insert leading zeroes | +|`#` (hash) | Insert leading spaces | +|`*` (asterisk) | Insert leading asterisks| |Any other character | Interpreted literally | Table: Sequence Format Characters {#tbl:sequence_format_characters} @@ -488,9 +488,9 @@ zint.exe -d "This Text" For compatibility with Windows the examples use double quotes to delimit data, though on Unix single quotes are generally preferable as they stop the shell -from processing any characters such as backslash or dollar. A single quote -itself is dealt with by terminating the single-quoted text, backslashing the -single quote, and then continuing: +from processing characters such as backslash. A single quote itself is dealt +with by terminating the single-quoted text, backslashing the single quote, and +then continuing: ```bash zint -d 'Text containing a single quote '\'' in the middle' @@ -514,6 +514,10 @@ zint --data "This Text" The examples use a space separator for short option names, and an equals sign for long option names. +Long options may be abbreviated up to nonambiguity. For instance +`--compliantheight` may be shortened to `--compliant`, or even `--com`, but note +that future additions may necessitate longer abbreviations. + ## 4.1 Inputting Data The data to encode can be entered at the command line using the `-d` or `--data` @@ -525,11 +529,11 @@ zint -d "This Text" This will encode the text `"This Text"`. Zint will use the default symbology, Code 128, and output to the default file `"out.png"` in the current directory. -Alternatively, if `libpng` was not present when Zint was built, the default -output file will be `"out.gif"`. +Alternatively, if Zint was not built with `libpng`, the default output file will +be `"out.gif"`. The data input to the Zint CLI is assumed to be encoded in UTF-8 (Unicode) -format (Zint will correctly handle UTF-8 data on Windows). If you are encoding +(Zint will correctly handle UTF-8 data on Windows). If you are encoding characters beyond the 7-bit ASCII set using a scheme other than UTF-8 then you will need to set the appropriate input options as shown in [4.11 Input Modes] below. @@ -633,8 +637,8 @@ See [6.1.10.1 Standard Code 128 (ISO 15417)] for the details on manually switching Code Sets. Input data can be read directly from file using the `-i` or `--input` switch as -shown below. The input file is assumed to be UTF-8 formatted unless an -alternative mode is selected. This option replaces the use of the `-d` switch. +shown below. The input file is assumed to be in UTF-8 unless `--binary` is +selected. This option replaces the use of the `-d` switch. ```bash zint -i somefile.txt @@ -688,6 +692,9 @@ zint -o "dir/subdir/filename.eps" -d "This Text" Note that on Windows, filenames are assumed to be UTF-8 encoded. +For another way to name output files, using the `--mirror` option, see [4.14 +Automatic Filenames]. + ## 4.3 Selecting Barcode Type Selecting which type of barcode you wish to produce (i.e. which symbology to @@ -1139,9 +1146,8 @@ applied to the X-dimension. For MaxiCode, it is multiplied by 10 for raster output, by 40 for EMF vector output, and by 2 otherwise (non-EMF vector output). For non-MaxiCode raster output, the default scale of 1 results in an X-dimension -of 2 pixels. For example for non-MaxiCode PNG images a scale of 5 will increase -the X-dimension to 10 pixels. For MaxiCode, see [4.9.3 MaxiCode Raster Scaling] -below. +of 2 pixels, e.g. for PNG images a scale of 5 will increase the X-dimension to +10 pixels. For MaxiCode, see [4.9.3 MaxiCode Raster Scaling] below. Scales for non-MaxiCode raster output should be given in increments of 0.5, i.e. 0.5, 1, 1.5, 2, 2.5, 3, 3.5, etc., to avoid the X-dimension varying across the @@ -1211,14 +1217,14 @@ nominal size" gives an example of an EAN-13 barcode using the X-dimension of pixels, or 4 pixels rounding to the nearest pixel: ```bash -zint -b EAN13 -d "501234567890" --compliantheight --scale=2 +zint -b EAN13 -d "501234567890" --compliant --scale=2 ``` This will result in output of 37.29mm x 25.56mm (WxH) at 12 dpmm. The same result can be achieved using the `--scalexdimdp` option with ```bash -zint -b EAN13 -d "501234567890" --compliantheight --scalexdimdp +zint -b EAN13 -d "501234567890" --compliant --scalexdimdp ``` as 0.33mm is the default X-dimension for EAN, and 12 dpmm the default @@ -1280,12 +1286,12 @@ matrix barcodes. ### 4.11.1 Unicode, Data, and GS1 Modes -By default all CLI input data is assumed to be encoded in UTF-8 format. Many -barcode symbologies encode data using the Latin-1 (ISO/IEC 8859-1 plus ASCII) -character set, so input is converted from UTF-8 to Latin-1 before being put in -the symbol. In addition QR Code and its variants and Han Xin Code can by default -encode Japanese (Kanji) or Chinese (Hanzi) characters which are also converted -from UTF-8. +By default all CLI input data is assumed to be encoded in UTF-8. Many barcode +symbologies encode data using the Latin-1 (ISO/IEC 8859-1 plus ASCII) character +set, so input is converted from UTF-8 to Latin-1 before being put in the symbol. +In addition QR Code and its variants and Han Xin Code can by default encode +Japanese (Kanji) or Chinese (Hanzi) characters which are also converted from +UTF-8. There are two exceptions to the Latin-1 default: Grid Matrix, whose default character set is GB 2312 (Chinese); and UPNQR, whose default character set is @@ -1412,7 +1418,7 @@ Table: ECI Codes {#tbl:eci_codes} `#`, `$`, `@`, `[`, `\`, `]`, `^`, `` ` ``, `{`, `|`, `}`, `~` (tilde). [^9]: Note that unless the `--binary` switch is used, 8-bit binary data for ECI -899 must be given as UTF-8, e.g. a byte `"\x80"` must be represented as the 2 +899 must be given as UTF-8, e.g. byte `"\x80"` must be represented as the 2 bytes `"\xC2\x80"`; similarly `"\xC0"` as `"\xC3\x80"`, etc. An ECI value of 0 does not encode any ECI information in the code symbol (unless @@ -1436,60 +1442,64 @@ information. #### 4.11.2.1 Input Modes and ECI Example 1 -The Euro sign U+20AC can be encoded in ISO/IEC 8859-15. The Euro sign has the -ISO/IEC 8859-15 codepoint hex `"A4"`. It is encoded in UTF-8 as the hex -sequence: `"E2 82 AC"`. Those 3 bytes are contained in the file -`"utf8euro.txt"`. This command will generate the corresponding code: +The Euro sign `"€"` (U+20AC) can be encoded in ISO/IEC 8859-15 (ECI 17) as the +hex byte `"A4"`. It is encoded in UTF-8 as the hex sequence: `"E2 82 AC"`. Those +3 bytes are contained in the file `"utf8euro.txt"`, e.g. on Unix ```bash -zint -b DATAMATRIX --scale=10 --eci=17 -i utf8euro.txt +echo -ne '\xE2\x82\xAC' > utf8euro.txt +``` + +This command will generate the corresponding code: + +```bash +zint -b DATAMATRIX --eci=17 -i utf8euro.txt ``` This is equivalent to the commands (using the `--esc` switch): ```bash -zint -b DATAMATRIX --scale=10 --eci=17 --esc -d "\xE2\x82\xAC" +zint -b DATAMATRIX --eci=17 --esc -d "\xE2\x82\xAC" -zint -b DATAMATRIX --scale=10 --eci=17 --esc -d "\u20AC" +zint -b DATAMATRIX --eci=17 --esc -d "\u20AC" ``` and to the command: ```bash -zint -b DATAMATRIX --scale=10 --eci=17 -d "€" +zint -b DATAMATRIX --eci=17 -d "€" ``` ![`zint -b DATAMATRIX --eci=17 -d "€"`](images/datamatrix_euro.svg){.i2d} #### 4.11.2.2 Input Modes and ECI Example 2 -The Chinese character with the Unicode codepoint U+5E38 can be encoded in Big5 -encoding. The Big5 representation of this character is the two hex bytes: -`"B1 60"` (contained in the file `"big5char.txt"`). The generation command for -Data Matrix is: +The Chinese character `"碼"` (U+78BC) can be encoded in Big5 encoding (ECI 28) +as the hex sequence: `"BD 58"`. Those 2 bytes are contained in the file +`"big5char.txt"`. The generation command is: ```bash -zint -b DATAMATRIX --scale=10 --eci=28 --binary -i big5char.txt +zint -b DATAMATRIX --eci=28 --binary -i big5char.txt ``` This is equivalent to the command (using the `--esc` switch): ```bash -zint -b DATAMATRIX --scale=10 --eci=28 --binary --esc -d "\xB1\x60" +zint -b DATAMATRIX --eci=28 --binary --esc -d "\xBD\x58" ``` and to the commands (no `--binary` switch so conversion occurs): ```bash -zint -b DATAMATRIX --scale=10 --eci=28 --esc -d "\xE5\xB8\xB8" +zint -b DATAMATRIX --eci=28 --esc -d "\xE7\xA2\xBC" -zint -b DATAMATRIX --scale=10 --eci=28 --esc -d "\u5E38" +zint -b DATAMATRIX --eci=28 --esc -d "\u78BC" -zint -b DATAMATRIX --scale=10 --eci=28 -d "常" +zint -b DATAMATRIX --eci=28 -d "碼" ``` -![`zint -b DATAMATRIX --eci=28 -d "\u5E38" ---esc`](images/datamatrix_big5.svg){.i2d} +![`zint -b DATAMATRIX --eci=28 --binary --esc -d +"\xBD\x58"`](images/datamatrix_big5.svg){.i2d} #### 4.11.2.3 Input Modes and ECI Example 3 @@ -1498,53 +1508,53 @@ by default and do not support ECI. In this case supply UTF-8 data and use the `--binary` switch so that the data will be encoded as UTF-8 without conversion: ```bash -zint -b QRCODE --binary -d "UTF-8 data" +zint -b QRCODE --binary -d "€" ``` -![`zint -b QRCODE --binary -d "\xE2\x82\xAC\xE5\xB8\xB8" ---esc`](images/qrcode_binary_utf8.svg){.i2d} +![`zint -b QRCODE --binary -d "€"`](images/qrcode_binary_utf8.svg){.i2d} ### 4.11.3 GS1 Data Entry and Options The following symbologies accept GS1 data: ----------------------------------------------------------- -Symbology Implicit GS1 Data Supports GS1 - AI? Assumed? Composite? -------------- -------- -------- ------------ -Aztec Code No No No +------------------------------------------------------------ +Symbology Implicit GS1 Data Supports GS1 + AI? Assumed? Composite? +------------------------ --------- --------- ------------ +Aztec Code No No No -Code 16K No No No +Code 16K No No No -Code 49 No No No +Code 49 No No No -Code One No No No +Code One No No No -Data Matrix No No No +Data Matrix No No No -DotCode No No No +DotCode No No No -EAN-13, EAN-8 Yes (01) Yes Yes +EAN-13, EAN-8 Yes (01) Yes Yes -EAN-14 Yes (01) Yes No +EAN-14 Yes (01) Yes No -GS1-128 No Yes Yes +GS1-128 No Yes Yes -GS1 DataBar Expanded No Yes Yes -(including Stacked) +GS1 DataBar Expanded No Yes Yes +(including Expanded +Stacked) -GS1 DataBar (all others) Yes (01) Yes Yes +GS1 DataBar (all others) Yes (01) Yes Yes -NVE-18 Yes (00) Yes No +NVE-18 Yes (00) Yes No -QR Code No No No +QR Code No No No -rMQR No No No +rMQR No No No -Ultracode No No No +Ultracode No No No -UPC-A, UPC-E Yes (01) Yes Yes ----------------------------------------------------------- +UPC-A, UPC-E Yes (01) Yes Yes +------------------------------------------------------------ Table: GS1-Enabled Symbologies @@ -1623,9 +1633,9 @@ other GS1 options. - `--gs1strict`, which enables the use the GS1 Syntax Engine to strictly validate GS1 data, including GS1 Digital Link URIs (by default Zint -does not validate Digital Links at all). It requires that the `gs1encoders` -library was present when Zint was built, otherwise the default built-in -validation will be used. +does not validate Digital Links at all). It requires that Zint was built with +the `gs1encoders` library, otherwise the default built-in validation will be +used. - `--gs1nocheck`, for use with legacy systems that have data that does not conform to the current GS1 standard. Printable ASCII input is still checked for, @@ -1665,9 +1675,9 @@ characters in the output filename as shown in the table below: Input Character Interpretation --------------- ------------------------------------------ -`~` Insert a number or 0 -`#` Insert a number or space -`@` Insert a number or `*` (or `+` on Windows) +`~` (tilde) Insert a number or 0 +`#` (hash) Insert a number or space +`@` (ampersand) Insert a number or `*` (or `+` on Windows) Any other Insert literally Table: Batch Filename Formatting {#tbl:batch_filename_formatting} @@ -1707,9 +1717,9 @@ For an alternative method of naming output files see the `--mirror` option in The finished image files can be output directly to stdout for use as part of a pipe by using the `--direct` option. By default `--direct` will output data as a -PNG image (or GIF image if `libpng` is not present), but this can be altered by -supplementing the `--direct` option with a `--filetype` option followed by the -suffix of the file type required. For example: +PNG image (or GIF image if Zint not built with `libpng`), but this can be +altered by supplementing the `--direct` option with a `--filetype` option +followed by the suffix of the file type required. For example: ```bash zint -b MICROPDF417 --direct --filetype=pcx -d "Data to encode" @@ -1733,13 +1743,34 @@ file named `"1234567.png"`. There are restrictions, however, on what characters can be stored in a filename, so the filename may vary from the data if the data includes non-printable -characters, for example, and may be shortened if the data input is long. +characters, for example,[^12] and may be shortened if the data input is long. So +in batch mode your data must be unique given these restrictions otherwise files +will overwrite each other. To set the output file format use the `--filetype` option as detailed above in -[4.13 Direct Output to stdout]. To output to a specific directory use the `-o` -option giving the name of the directory (any filename will be ignored, unless -`--filetype` is not specified, in which case the filename's extension will be -used). +[4.13 Direct Output to stdout]. For instance + +```bash +zint -d "1234567" --mirror --filetype=eps +``` + +will output to the file `"1234567.eps"`: + +To output to a specific directory use the `-o` option giving the name of the +directory, indicated by a terminating slash `/` (backslash `\` may be used on +Windows). Any filename after the last slash will be ignored, unless `--filetype` +is not specified, in which case the filename's extension will be used - e.g. + +```bash +zint -d "1234567" --mirror -o "dir/subdir/mir.eps" +``` + +will output to the file `"1234567.eps"` in the `"dir/subdir"` directory. + +[^12]: The `--mirror` option will replace control characters (including `DEL`) +and slash (`/`) with an underscore (`_`). Additionally on Windows the characters +`!`, `"`, `*`, `:`, `<`, `>`, `?`, `\` and `|` will also be replaced with +underscores, as they are prohibited in filenames. ## 4.15 Working with Dots @@ -1880,8 +1911,8 @@ gcc -o simple simple.c -lzint To encode data in a barcode use the `ZBarcode_Encode()` function. To write the symbol to a file use the `ZBarcode_Print()` function. For example the following code takes a string from the command line and outputs a Code 128 symbol to a PNG -file named `"out.png"` (or a GIF file `"out.gif"` if `libpng` is not present) in -the current working directory: +file named `"out.png"` (or a GIF file `"out.gif"` if Zint not built with +`libpng`) in the current working directory: ```c #include @@ -2108,10 +2139,10 @@ int main(int argc, char **argv) ``` will print the SVG output to `stdout` (the file `"mem.svg"` is not created). -This is particularly useful for the textual formats EPS and SVG,[^12] allowing +This is particularly useful for the textual formats EPS and SVG,[^13] allowing the output to be manipulated and processed by the client. -[^12]: BARCODE_MEMORY_FILE textual formats EPS and SVG will have Unix newlines +[^13]: BARCODE_MEMORY_FILE textual formats EPS and SVG will have Unix newlines (LF) on both Windows and Unix, i.e. not CR+LF on Windows. ## 5.7 Setting Options @@ -2132,7 +2163,7 @@ Member Name Type Meaning Default Value `height` float Symbol height in Symbol dependent X-dimensions, excluding fixed width-to-height - symbols.[^13] + symbols.[^14] `scale` float Scale factor for 1.0 adjusting size of image @@ -2182,7 +2213,7 @@ Member Name Type Meaning Default Value `.eps`, `.pcx`, `.svg`, `.tif` or `.txt` followed by a terminating - `NUL`.[^14] + `NUL`.[^15] `primary` character Primary message data for `""` (empty) string more complex symbols, @@ -2310,13 +2341,13 @@ Member Name Type Meaning Default Value Table: API Structure `zint_symbol` {#tbl:api_structure_zint_symbol} -[^13]: The `height` value is ignored for Aztec (including HIBC and Aztec Rune), +[^14]: The `height` value is ignored for Aztec (including HIBC and Aztec Rune), Code One, Data Matrix (including HIBC), DotCode, Grid Matrix, Han Xin, MaxiCode, QR Code (including HIBC, Micro QR, rMQR and UPNQR), and Ultracode - all of which have a fixed width-to-height ratio (or, in the case of Code One, a fixed height). -[^14]: For Windows, `outfile` is assumed to be UTF-8 encoded. +[^15]: For Windows, `outfile` is assumed to be UTF-8 encoded. To alter these values use the syntax shown in the example below. This code has the same result as the previous example except the output is now taller and @@ -2482,10 +2513,10 @@ Value Effect ------------------------- --------------------------------------------------- 0 No options selected. -`BARCODE_BIND_TOP` Boundary bar above the symbol only.[^15] +`BARCODE_BIND_TOP` Boundary bar above the symbol only.[^16] `BARCODE_BIND` Boundary bars above and below the symbol and - between rows if stacking multiple symbols.[^16] + between rows if stacking multiple symbols.[^17] `BARCODE_BOX` Add a box surrounding the symbol and whitespace. @@ -2512,7 +2543,7 @@ Value Effect Symbols in Memory (raster)]. `BARCODE_QUIET_ZONES` Add compliant quiet zones (additional to any - specified whitespace).[^17] + specified whitespace).[^18] `BARCODE_NO_QUIET_ZONES` Disable quiet zones, notably those with defaults. @@ -2534,13 +2565,13 @@ Value Effect Table: API `output_options` Values {#tbl:api_output_options} -[^15]: The `BARCODE_BIND_TOP` flag is set by default for DPD - see [6.1.10.7 DPD +[^16]: The `BARCODE_BIND_TOP` flag is set by default for DPD - see [6.1.10.7 DPD Code]. -[^16]: The `BARCODE_BIND` flag is always set for Codablock F, Code 16K and Code +[^17]: The `BARCODE_BIND` flag is always set for Codablock F, Code 16K and Code 49. Special considerations apply to ITF-14 - see [6.1.2.6 ITF-14]. -[^17]: Codablock F, Code 16K, Code 49, EAN-13, EAN-8, EAN/UPC add-ons, ISBN, +[^18]: Codablock F, Code 16K, Code 49, EAN-13, EAN-8, EAN/UPC add-ons, ISBN, ITF-14, UPC-A and UPC-E have compliant quiet zones added by default. ## 5.11 Setting the Input Mode @@ -2568,7 +2599,7 @@ Value Effect `GS1NOCHECK_MODE` Do not check GS1 data for validity, i.e. suppress checks for valid AIs and data lengths. Invalid - characters (e.g. control characters, extended ASCII + characters (e.g. control characters, extended ASCII characters) are still checked for. `HEIGHTPERROW_MODE` Interpret the `height` member as per-row rather than @@ -2799,7 +2830,7 @@ Value Meaning `ZINT_CAP_STACKABLE` Is the symbology stackable? Note that stacked symbologies are not stackable. -`ZINT_CAP_EANUPC`[^18] Is the symbology EAN/UPC? +`ZINT_CAP_EANUPC`[^19] Is the symbology EAN/UPC? `ZINT_CAP_COMPOSITE` Does the symbology support composite data? (see [6.3 GS1 Composite Symbols (ISO 24723)] below) @@ -2835,7 +2866,7 @@ Value Meaning Table: API Capability Flags {#tbl:api_cap} -[^18]: `ZINT_CAP_EANUPC` was previously named `ZINT_CAP_EXTENDABLE`, which is +[^19]: `ZINT_CAP_EANUPC` was previously named `ZINT_CAP_EXTENDABLE`, which is still recognised. For example: @@ -2862,7 +2893,7 @@ On successful encodation (after using `ZBarcode_Encode()` etc.) the `option_1`, create the barcode. This is useful for feedback if the values were left as defaults or were overridden by Zint. -In particular for symbologies that have masks,[^19] `option_3` will contain the +In particular for symbologies that have masks,[^20] `option_3` will contain the mask used as `(N + 1) << 8`, N being the mask. Also Aztec Code will return the actual ECC percentage used in `option_1` as `P << 8`, where P is the integer percentage, the low byte containing the values given in [#tbl:aztec_eccs] (with @@ -2880,7 +2911,7 @@ least one. The `source`, `length` and `eci` members of `zint_seg` will be set accordingly - the unconverted data in `source`, the data length in `length`, and the character set the data was converted to in `eci`. Any check characters encoded will be -included,[^20] and for GS1 data any `FNC1` separators will be represented as +included,[^21] and for GS1 data any `FNC1` separators will be represented as `GS` (ASCII 29) characters. UPC-A and UPC-E data will be expanded to EAN-13, as will EAN-8 but only if it has an add-on (otherwise it will remain at 8 digits), and any add-ons will follow the 13 digits directly (no separator). GS1 Composite @@ -2892,16 +2923,16 @@ is `DATA_MODE`, it remains in binary; otherwise it will be in UTF-8. The UTF-8 source may be converted to the character set of the corresponding `eci` member using the two helper functions discussed next. -[^19]: DotCode, Han Xin, Micro QR Code, QR Code and UPNQR have variable masks. +[^20]: DotCode, Han Xin, Micro QR Code, QR Code and UPNQR have variable masks. Rectangular Micro QR Code has a fixed mask (4). -[^20]: Except for Japanese Postal Code, whose check character is not truly +[^21]: Except for Japanese Postal Code, whose check character is not truly representable in the encoded data. ## 5.17 UTF-8 to ECI convenience functions As a convenience the conversion done by Zint from UTF-8 to ECIs is exposed in -two helper functions (compatible with the `libzueci`[^21] functions +two helper functions (compatible with the `libzueci`[^22] functions `zueci_utf8_to_eci()` and `zueci_dest_len_eci()`): @@ -2921,7 +2952,7 @@ returned in `p_dest_length`, may be smaller than the estimate given by NUL-terminated. The destination buffer is not NUL-terminated. The obsolete ECIs 0, 1 and 2 are supported. -[^21]: The library `libzueci`, which can convert both to and from UTF-8 and ECI, +[^22]: The library `libzueci`, which can convert both to and from UTF-8 and ECI, is available at [https://sourceforge.net/projects/libzueci/]( https://sourceforge.net/projects/libzueci/). @@ -3026,8 +3057,7 @@ A high-density barcode that encodes pairs of numbers, and so can only encode an even number of digits (0-9). If an odd number of digits is entered a leading zero is added by Zint. A maximum of 62 pairs (124 digits) can be encoded. -![`zint -b C25INTER --compliantheight -d -"9212320967"`](images/c25inter.svg){.lin} +![`zint -b C25INTER --compliant -d "9212320967"`](images/c25inter.svg){.lin} No check digit is added by default, but can be set the same as for [6.1.2.1 Standard Code 2 of 5]. @@ -3051,7 +3081,7 @@ entered, or a 14-digit input if the standard GS1 check digit is given, in which case the check digit will be verified. A standard GS1 check digit is added by Zint unless already given. -![`zint -b ITF14 --compliantheight -d "9212320967145"`](images/itf14.svg){.lin} +![`zint -b ITF14 --compliant -d "9212320967145"`](images/itf14.svg){.lin} If no border option is specified Zint defaults to adding a bounding box with a border width of 5. This behaviour can be overridden by using the `--bind` option @@ -3060,7 +3090,7 @@ overridden using `--border` (API `border_width`). If a symbol with no border is required this can be achieved by explicitly setting the border type to box (or bind or bindtop) and leaving the border width 0. -![`zint -b ITF14 --box --compliantheight -d +![`zint -b ITF14 --box --compliant -d "9212320967145"`](images/itf14_border0.svg){.lin} #### 6.1.2.7 Deutsche Post Leitcode @@ -3089,7 +3119,7 @@ UPC-A is used in the United States for retail applications, and encodes a GTIN-12, a 12-digit Global Trade Item Number that includes a standard GS1 check digit. -![`zint -b UPCA --compliantheight -d "01234500005"`](images/upca.svg){.upcean} +![`zint -b UPCA --compliant -d "01234500005"`](images/upca.svg){.upcean} Input up to 11 digits may be given, to which a check digit will be added by Zint. A 12-digit input including the check digit may also be supplied, in which @@ -3116,8 +3146,7 @@ error = ZBarcode_Encode_and_Print(symbol, "01234500005+12345", 0, 0); error = ZBarcode_Encode_and_Print(symbol, "01234500005 12345", 0, 0); ``` -![`zint -b UPCA --compliantheight -d -"01234500005+12345"`](images/upca_5.svg){.upcean} +![`zint -b UPCA --compliant -d "01234500005+12345"`](images/upca_5.svg){.upcean} A quiet zone indicator can be added to the HRT by setting `--guardwhitespace` (API `output_options |= EANUPC_GUARD_WHITESPACE`). For UPC, this is only @@ -3135,7 +3164,7 @@ symbol->output_options |= EANUPC_GUARD_WHITESPACE; error = ZBarcode_Encode_and_Print(symbol, "01234500005+12345", 0, 0); ``` -![`zint -b UPCA --compliantheight -d "01234500005+12345" +![`zint -b UPCA --compliant -d "01234500005+12345" --guardwhitespace`](images/upca_5_gws.svg){.upcean} You can adjust the gap between the main symbol and an add-on in integral @@ -3152,7 +3181,7 @@ Zint. If 7 digits are given then the first must be '0' or '1' (the latter is known as number system 1 and is non-standard). Input less than 7 digits will be zero-filled. -![`zint -b UPCE --compliantheight -d "123455"`](images/upce.svg){.upcean} +![`zint -b UPCE --compliant -d "123455"`](images/upce.svg){.upcean} An 8-digit input including the check digit may also be supplied, in which case Zint will verify the check digit, or the symbology `BARCODE_UPCE_CHK` (38) may @@ -3167,7 +3196,7 @@ EANUPC_GUARD_WHITESPACE`): zint -b UPCE -d "123455+12" --guardwhitespace ``` -![`zint -b UPCE --compliantheight -d "123455+12" +![`zint -b UPCE --compliant -d "123455+12" --guardwhitespace`](images/upce_2_gws.svg){.upcean} You can adjust the gap between the main symbol and an add-on in integral @@ -3188,8 +3217,7 @@ EAN-8 and ISBN (a subset of EAN-13). EAN-13 encodes a GTIN-13, a 13-digit Global Trade Item Number that includes a standard GS1 check digit. -![`zint -b EAN13 --compliantheight -d -"952012345678"`](images/ean13.svg){.upcean} +![`zint -b EAN13 --compliant -d "952012345678"`](images/ean13.svg){.upcean} Input up to 12 digits may be given, to which a check digit will be added by Zint, or a 13-digit input can be supplied in which case Zint will validate the @@ -3210,8 +3238,7 @@ symbol->symbology = BARCODE_EAN13; error = ZBarcode_Encode_and_Print(symbol, "952012345678+21", 0, 0); ``` -![`zint -b EAN13 --compliantheight -d -"952012345678+21"`](images/ean13_2.svg){.upcean} +![`zint -b EAN13 --compliant -d "952012345678+21"`](images/ean13_2.svg){.upcean} Options to add quiet zone indicators and to adjust the add-on gap and the guard bar descent height are the same as for [6.1.3.2 UPC Version E]. For instance: @@ -3220,15 +3247,15 @@ bar descent height are the same as for [6.1.3.2 UPC Version E]. For instance: zint -b EAN13 -d "9520123456788" --guarddescent=2.5 --guardwhitespace ``` -![`zint -b EAN13 --compliantheight -d "9520123456788"` ---guarddescent=2.5 --guardwhitespace](images/ean13_gd_gws.svg){.upcean} +![`zint -b EAN13 --compliant -d "9520123456788" --guarddescent=2.5 +--guardwhitespace`](images/ean13_gd_gws.svg){.upcean} #### 6.1.4.2 EAN-8 EAN-8 is a shortened version of EAN-13, encoding a GTIN-8 (a GTIN-13 with 5 leading zeroes implied), for use with small packages. -![`zint -b EAN8 --compliantheight -d "9520000"`](images/ean8.svg){.upcean} +![`zint -b EAN8 --compliant -d "9520000"`](images/ean8.svg){.upcean} Input up to 7 digits may be supplied, to which Zint will add a standard GS1 check digit. An 8-digit input including the check digit may also be given, in @@ -3250,7 +3277,7 @@ symbol->output_options |= EANUPC_GUARD_WHITESPACE; error = ZBarcode_Encode_and_Print(symbol, "9520000", 0, 0); ``` -![`zint -b EAN8 --compliantheight -d "9520000"` +![`zint -b EAN8 --compliant -d "9520000"` --guardwhitespace](images/ean8_gws.svg){.upcean} 2-digit and 5-digit add-ons may also be added, and the gap adjusted, as with @@ -3263,12 +3290,11 @@ SBN, 10-digit ISBN or 13-digit ISBN-13 data. The relevant check digit needs to be present in the input data and will be verified before the symbol is generated. -![`zint -b ISBNX --compliantheight -d -"9789295055124"`](images/isbnx.svg){.upcean} +![`zint -b ISBNX --compliant -d "9789295055124"`](images/isbnx.svg){.upcean} As with EAN-13, a quiet zone indicator can be added using `--guardwhitespace`: -![`zint -b ISBNX --compliantheight -d "9789295055124" +![`zint -b ISBNX --compliant -d "9789295055124" --guardwhitespace`](images/isbnx_gws.svg){.upcean} 2-digit and 5-digit add-on symbols can be added using a `+` or space character, @@ -3281,8 +3307,7 @@ As a convenience, 2-digit and 5-digit add-ons may be generated as standalone symbols using the symbologies `BARCODE_EAN_2ADDON` (11) and `BARCODE_EAN_5ADDON` (12). -![`zint -b EAN_2ADDON --compliantheight --d "12"`](images/ean_2addon.svg){.upcean} +![`zint -b EAN_2ADDON --compliant -d "12"`](images/ean_2addon.svg){.upcean} As with the main EAN/UPC symbols a quiet zone indicator can be added using `---guardwhitespace`. For instance @@ -3300,7 +3325,7 @@ symbol->output_options |= EANUPC_GUARD_WHITESPACE; error = ZBarcode_Encode_and_Print(symbol, "54321", 0, 0); ``` -![`zint -b EAN_5ADDON --compliantheight -d "54321"` +![`zint -b EAN_5ADDON --compliant -d "54321"` --guardwhitespace](images/ean_5addon_gws.svg){.upcean} ### 6.1.5 Plessey @@ -3350,7 +3375,7 @@ Telepen Alpha was developed in 1972 by SB Electronic Systems Limited and can encode ASCII text input, up to a maximum of 69 characters. Telepen includes a hidden modulo-127 check digit, added by Zint. -![`zint -b TELEPEN --compliantheight -d "Z8000"`](images/telepen.svg){.lin} +![`zint -b TELEPEN --compliant -d "Z8000"`](images/telepen.svg){.lin} AIM-defined Start/Stop characters may be enabled by setting `--vers=1` (API `option_2 = 1`). In this mode control character `DLE` (ASCII 16, escape sequence @@ -3358,7 +3383,7 @@ AIM-defined Start/Stop characters may be enabled by setting `--vers=1` (API symbol character encodes a digit pair (or a "digit X" pair - see Telepen Numeric below): -![`zint -b TELEPEN --compliantheight -d +![`zint -b TELEPEN --compliant -d "Z\L8000" -esc --vers=1`](images/telepen_aim.svg){.lin} However not all barcode readers recognise this mode so check before using. @@ -3372,19 +3397,18 @@ character. For example: `"466333"` and `"466X33"` are valid codes whereas supplied, Zint will add a leading zero. Up to 138 digits can be encoded. A hidden modulo-127 check digit is added by Zint. -![`zint -b TELEPEN_NUM --compliantheight -d -"466X33"`](images/telepen_num.svg){.lin} +![`zint -b TELEPEN_NUM --compliant -d "466X33"`](images/telepen_num.svg){.lin} Additionally trailing ASCII characters may be encoded by prefixing them with a `DLE` control character (ASCII 16, escape sequence `\L`) and appending them to the numeric data: -![`zint -b TELEPEN_NUM --compliantheight -d +![`zint -b TELEPEN_NUM --compliant -d "12\LAB" --esc`](images/telepen_num_asc.svg){.lin} This method allows odd numbers to be encoded without a leading zero: -![`zint -b TELEPEN_NUM --compliantheight -d +![`zint -b TELEPEN_NUM --compliant -d "123\L4" --esc`](images/telepen_num_odd.svg){.lin} AIM-defined Start/Stop characters may be enabled by setting `--vers=1` (API @@ -3402,7 +3426,7 @@ characters in length and can include the characters 0-9, A-Z, dash (`-`), full stop (`.`), space, asterisk (`*`), dollar (`$`), slash (`/`), plus (`+`) and percent (`%`). -![`zint -b CODE39 --compliantheight -d "1A" --vers=1`](images/code39.svg){.lin} +![`zint -b CODE39 --compliant -d "1A" --vers=1`](images/code39.svg){.lin} The standard does not require a check digit but a modulo-43 check digit can be added if desired by setting `--vers=1` (API `option_2 = 1`). To add a check @@ -3414,8 +3438,7 @@ digit but not show it in the Human Readable Text, set `--vers=2` (API Also known as Code 39e and Code39+, this symbology expands on Standard Code 39 to provide support for the full 7-bit ASCII character set. -![`zint -b EXCODE39 --compliantheight -d -"123.45#@fd"`](images/excode39.svg){.lin} +![`zint -b EXCODE39 --compliant -d "123.45#@fd"`](images/excode39.svg){.lin} The check digit options are the same as for [6.1.7.1 Standard Code 39 (ISO 16388)]. @@ -3427,7 +3450,7 @@ accepting up to 123 characters. Two check characters are added by Zint. By default these check characters are not shown in the Human Readable Text, but may be shown by setting `--vers=1` (API `option_2 = 1`). -![`zint -b CODE93 --compliantheight -d "C93"`](images/code93.svg){.lin} +![`zint -b CODE93 --compliant -d "C93"`](images/code93.svg){.lin} #### 6.1.7.4 PZN (Pharmazentralnummer) @@ -3436,7 +3459,7 @@ PZN encodes a 7-digit number to which Zint will add a modulo-11 check digit (PZN8). Input less than 7 digits will be zero-filled. An 8-digit input can be supplied in which case Zint will validate the check digit. -![`zint -b PZN --compliantheight -d "2758089"`](images/pzn.svg){.lin} +![`zint -b PZN --compliant -d "2758089"`](images/pzn.svg){.lin} To encode a PZN7 (obsolete since 2013) instead set `--vers=1` (API `option_2 = 1`) and supply up to 7 digits. As with PZN8, a modulo-11 check digit @@ -3450,7 +3473,7 @@ LOGMARS encodes the same character set as [6.1.7.1 Standard Code 39 (ISO 16388)], and the check digit options are also the same. Input is restricted to a maximum of 30 characters. -![`zint -b LOGMARS --compliantheight -d "12345/ABCDE" +![`zint -b LOGMARS --compliant -d "12345/ABCDE" --vers=1`](images/logmars.svg){.lin} #### 6.1.7.6 Code 32 @@ -3460,7 +3483,7 @@ Sanità") for encoding identifiers on pharmaceutical products. This symbology requires a numeric input up to 8 digits in length. A check digit is added by Zint. -![`zint -b CODE32 --compliantheight -d "14352312"`](images/code32.svg){.lin} +![`zint -b CODE32 --compliant -d "14352312"`](images/code32.svg){.lin} #### 6.1.7.7 HIBC Code 39 @@ -3468,7 +3491,7 @@ This variant adds a leading `'+'` character and a trailing modulo-49 check digit to a standard Code 39 symbol as required by the Health Industry Barcode standards. -![`zint -b HIBC_39 --compliantheight -d "14352312"`](images/hibc_39.svg){.lin} +![`zint -b HIBC_39 --compliant -d "14352312"`](images/hibc_39.svg){.lin} #### 6.1.7.8 Vehicle Identification Number (VIN) @@ -3489,7 +3512,7 @@ and Monarch, this symbology was developed in 1972 from earlier versions by Pitney Bowes-Alpex for retail price marking. The American Blood Commission adopted Codabar in 1979 as the standard barcode for blood products. -![`zint -b CODABAR --compliantheight -d "A37859B"`](images/codabar.svg){.lin} +![`zint -b CODABAR --compliant -d "A37859B"`](images/codabar.svg){.lin} Codabar can encode up to 103 characters starting and ending with the letters A-D and containing between these letters the numbers 0-9, dash (`-`), dollar (`$`), @@ -3505,7 +3528,7 @@ Developed by Laetus, Pharmacode One-Track is used for the identification of pharmaceuticals. The symbology is able to encode whole numbers between 3 and 131070. -![`zint -b PHARMA --compliantheight -d "130170"`](images/pharma.svg){.lin} +![`zint -b PHARMA --compliant -d "130170"`](images/pharma.svg){.lin} ### 6.1.10 Code 128 @@ -3565,7 +3588,7 @@ alphanumerics) are not recommended. #### 6.1.10.2 Code 128 Suppress Code Set C (Code Sets A and B only) It is sometimes advantageous to stop Code 128 from using Code Set C which -compresses numerical data. The `BARCODE_CODE128AB`[^22] variant (symbology 60) +compresses numerical data. The `BARCODE_CODE128AB`[^23] variant (symbology 60) suppresses Code Set C in favour of Code Sets A and B. ![`zint -b CODE128AB -d "130170X178"`](images/code128ab.svg){.lin} @@ -3573,7 +3596,7 @@ suppresses Code Set C in favour of Code Sets A and B. Note that the special extra escapes mentioned above are not available for this variant (nor for any other). -[^22]: `BARCODE_CODE128AB` previously used the name `BARCODE_CODE128B`, which is +[^23]: `BARCODE_CODE128AB` previously used the name `BARCODE_CODE128B`, which is still recognised. #### 6.1.10.3 GS1-128 @@ -3583,7 +3606,7 @@ defined by the GS1 General Specifications. Data should be in one of the formats described in [4.11.3.1 GS1 Data Entry]. Here we will use the square bracket format. -![`zint -b GS1_128 --compliantheight -d +![`zint -b GS1_128 --compliant -d "[01]98898765432106[3202]012345[15]991231"`](images/gs1_128.svg){.lin} Fixed length data should be entered at the appropriate length for correct @@ -3603,7 +3626,7 @@ digits entered, or a 14-digit number if the standard GS1 check digit is given, in which case the check digit will be verified. The GS1 check digit (if not given) and HRT-only AI `"(01)"` are added by Zint. -![`zint -b EAN14 --compliantheight -d "9889876543210"`](images/ean14.svg){.lin} +![`zint -b EAN14 --compliant -d "9889876543210"`](images/ean14.svg){.lin} #### 6.1.10.5 NVE-18 (SSCC-18) @@ -3614,8 +3637,7 @@ which will be prefixed with leading zeros if less than 17 digits given, or an 18-digit input if the GS1 check digit is included, in which case the check digit will be verified. Check digit(s) and HRT-only AI `"(00)"` are added by Zint. -![`zint -b NVE18 --compliantheight -d -"37612345000001003"`](images/nve18.svg){.lin} +![`zint -b NVE18 --compliant -d "37612345000001003"`](images/nve18.svg){.lin} #### 6.1.10.6 HIBC Code 128 @@ -3629,7 +3651,7 @@ standards. Another variation of Code 128 as used by DPD (Deutscher Paketdienst). -![`zint -b DPD --compliantheight -d +![`zint -b DPD --compliant -d "000393206219912345678101040"`](images/dpd.svg){.lin} DPD Code requires a 27 or 28 character input. For 28 character input, the first @@ -3673,8 +3695,7 @@ format `"SSNNNNNNNNXCC"`, where `"SS"` is a two-character alphabetic service indicator, `"NNNNNNNN"` is an 8-digit serial number, `"X"` is a modulo-11 check digit, and `"CC"` is a two-character ISO 3166-1 country code. -![`zint -b UPU_S10 --compliantheight -d -"EE876543216CA"`](images/upu_s10.svg){.lin} +![`zint -b UPU_S10 --compliant -d "EE876543216CA"`](images/upu_s10.svg){.lin} The check digit may be omitted in which case Zint will add it. Warnings will be generated if the service indicator is non-standard or the country code is not @@ -3698,8 +3719,7 @@ digit and HRT-only Application Identifier of `"(01)"` are added by Zint. (A case the check digit will be verified.) Input less than 13 digits will be zero-filled. -![`zint -b DBAR_OMN --compliantheight -d -"0950110153001"`](images/dbar_omn.svg){.lin} +![`zint -b DBAR_OMN --compliant -d "0950110153001"`](images/dbar_omn.svg){.lin} GS1 DataBar Omnidirectional symbols should have a height of 33 or greater. To produce a GS1 DataBar Truncated symbol set the symbol height to a value between @@ -3718,8 +3738,7 @@ digit and HRT-only Application Identifier of `"(01)"` are added by Zint, and a 14-digit code may be given in which case the check digit will be verified. Input less than 13 digits will be zero-filled. -![`zint -b DBAR_LTD --compliantheight -d -"0950110153001"`](images/dbar_ltd.svg){.lin} +![`zint -b DBAR_LTD --compliant -d "0950110153001"`](images/dbar_ltd.svg){.lin} #### 6.1.11.3 GS1 DataBar Expanded @@ -3728,7 +3747,7 @@ encoding multiple AIs in a single symbol. Data should be in one of the formats described in [4.11.3.1 GS1 Data Entry], and will be displayed using parentheses (round brackets) in the Human Readable Text. -![`zint -b DBAR_EXP --compliantheight -d +![`zint -b DBAR_EXP --compliant -d "[01]98898765432106[3202]012345[15]991231"`](images/dbar_exp.svg){.lin} The GTIN-14 data for AI (01) must include the standard GS1 check digit as this @@ -3756,7 +3775,7 @@ the `--vers` option (API `option_2`). It can also be determined by the length of the input data: e.g. a three character input string generates a 4 channel code by default. -![`zint -b CHANNEL -d "453678" --compliantheight`](images/channel.svg){.lin} +![`zint -b CHANNEL -d "453678" --compliant`](images/channel.svg){.lin} The maximum values permitted depend on the number of channels used as shown in the table below: @@ -3781,7 +3800,7 @@ input must be alphanumeric, excluding the letter `O`, and must be from 7 to 18 characters in length. A single check character is added by Zint, appearing in the 2nd character position. Lowercase input is automatically made uppercase. -![`zint -b BC412 -d "AQ45670" --compliantheight`](images/bc412.svg){.lin} +![`zint -b BC412 -d "AQ45670" --compliant`](images/bc412.svg){.lin} \clearpage @@ -3859,8 +3878,7 @@ character encoding in the same manner as Code 128. GS1 data encoding is also supported. The minimum number of rows to use can be set using the `--rows` option (API `option_1`), with values from 2 to 16. -![`zint -b CODE16K --compliantheight -d -"ab0123456789"`](images/code16k.svg){.lin} +![`zint -b CODE16K --compliant -d "ab0123456789"`](images/code16k.svg){.lin} ### 6.2.4 PDF417 (ISO 15438) @@ -3939,8 +3957,7 @@ except that its height is reduced and its central separator is a single row, making it suitable for small items when omnidirectional scanning is not required. -![`zint -b DBAR_STK --compliantheight -d -"9889876543210"`](images/dbar_stk.svg){.lin} +![`zint -b DBAR_STK --compliant -d "9889876543210"`](images/dbar_stk.svg){.lin} #### 6.2.7.2 GS1 DataBar Stacked Omnidirectional @@ -3948,7 +3965,7 @@ A stacked variation of the GS1 DataBar Omnidirectional symbol requiring the same input (see [6.1.11.1 GS1 DataBar Omnidirectional and GS1 DataBar Truncated]). The data is encoded in two rows of bars with a central 3-row separator. -![`zint -b DBAR_OMNSTK --compliantheight -d +![`zint -b DBAR_OMNSTK --compliant -d "9889876543210"`](images/dbar_omnstk.svg){.lin} #### 6.2.7.3 GS1 DataBar Expanded Stacked @@ -3957,7 +3974,7 @@ A stacked variation of the GS1 DataBar Expanded symbol for smaller packages. Input is the same as for GS1 DataBar Expanded (see [6.1.11.3 GS1 DataBar Expanded]), with the same maximum capacity. -![`zint -b DBAR_EXPSTK --compliantheight -d +![`zint -b DBAR_EXPSTK --compliant -d "[01]98898765432106[3202]012345[15]991231"`](images/dbar_expstk.svg){.lin} The width of the symbol can be altered using the `--cols` switch (API @@ -3978,7 +3995,7 @@ or 81 numeric digits. GS1 data encoding is also supported. The minimum number of fixed-width rows to use can be set using the `--rows` option (API `option_1`), with values from 2 to 8. -![`zint -b CODE49 --compliantheight -d +![`zint -b CODE49 --compliant -d "MULTIPLE ROWS IN CODE 49"`](images/code49.svg){.lin} \clearpage @@ -4073,7 +4090,7 @@ which is being used. CC-A can encode up to 56 numeric digits (including AIs) or an alphanumeric string of shorter length (e.g. if all capitals, at most 30, excluding AI). To select CC-A use `--mode=1` (API `option_1 = 1`). -![`zint -b EAN13_CC --compliantheight -d "[99]1234-abcd" --mode=1 +![`zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=1 --primary=331234567890`](images/ean13_cc_a.svg){.upcean} ### 6.3.2 CC-B @@ -4084,7 +4101,7 @@ to be encoded and the type of linear component which is being used. CC-B can encode up to 338 numeric digits or an alphanumeric string of shorter length. To select CC-B use `--mode=2` (API `option_1 = 2`). -![`zint -b EAN13_CC --compliantheight -d "[99]1234-abcd" --mode=2 +![`zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=2 --primary=331234567890`](images/ean13_cc_b.svg){.upcean} ### 6.3.3 CC-C @@ -4093,7 +4110,7 @@ This system uses PDF417 and can only be used in conjunction with a GS1-128 linear component. CC-C can encode up to 2361 numeric digits or an alphanumeric string of shorter length. To select CC-C use `--mode=3` (API `option_1 = 3`). -![`zint -b GS1_128_CC --compliantheight -d "[99]1234-abcd" --mode=3 +![`zint -b GS1_128_CC --compliant -d "[99]1234-abcd" --mode=3 --primary="[01]03312345678903"`](images/gs1_128_cc_c.svg){.upcean} \clearpage @@ -4107,8 +4124,7 @@ One-Track (see [6.1.9 Pharmacode One-Track]) used for the identification of pharmaceuticals. The symbology is able to encode whole numbers between 4 and 64570080. -![`zint -b PHARMA_TWO --compliantheight -d -"29876543"`](images/pharma_two.svg){.trk} +![`zint -b PHARMA_TWO --compliant -d "29876543"`](images/pharma_two.svg){.trk} ### 6.4.2 POSTNET @@ -4120,8 +4136,7 @@ to 38 digits in length, standard lengths as used by USPS were `PostNet6` `PostNet12` (5-digit ZIP + 6-digit user data), and a warning will be issued if the input length is not one of these. -![`zint -b POSTNET --compliantheight -d -"12345678901"`](images/postnet.svg){.trk} +![`zint -b POSTNET --compliant -d "12345678901"`](images/postnet.svg){.trk} ### 6.4.3 PLANET @@ -4133,8 +4148,7 @@ lengths used by USPS were `Planet12` (11-digit input) and `Planet14` (13-digit input), and as with POSTNET a warning will be issued if the length is not one of these. -![`zint -b PLANET --compliantheight -d -"4012345235636"`](images/planet.svg){.trk} +![`zint -b PLANET --compliant -d "4012345235636"`](images/planet.svg){.trk} ### 6.4.4 Brazilian CEPNet @@ -4143,7 +4157,7 @@ service, to encode CEP (Código de Endereçamento Postal) numbers on mail items. Input should consist of eight digits with the check digit being automatically added by Zint. -![`zint -b CEPNET --compliantheight -d "12345678"`](images/cepnet.svg){.trk} +![`zint -b CEPNET --compliant -d "12345678"`](images/cepnet.svg){.trk} ### 6.4.5 DX Film Edge Barcode @@ -4151,8 +4165,7 @@ Introduced by Kodak in the 1980s, the DX (Digital Index) barcode is printed on the bottom edge of 35mm film to aid in the reordering and post-processing of prints. -![`zint -b DXFILMEDGE --compliantheight -d -"112-1/10A"`](images/dxfilmedge.svg){.trk} +![`zint -b DXFILMEDGE --compliant -d "112-1/10A"`](images/dxfilmedge.svg){.trk} The data can be in two parts. The first part (required) is the "DX number", identifying the manufacturer and film type - the National Association of @@ -4166,7 +4179,7 @@ first and last digit are ignored, leaving a 4-digit DX Extract number in any case, which must be in the range 16 to 2047. The second format `"NNN-NN"` represents the DX Extract as two numbers separated by a dash (`-`), the first number being 1 to 3 digits (range 1 to 127) and the second 1 to 2 digits (range -0 to 15).[^23] +0 to 15).[^24] The optional frame number is a number in the range 0 to 63, and may have a half frame indicator `"A"` appended. Special character sequences (with or without a @@ -4176,7 +4189,7 @@ number 62, `"K"` or `"00"` means frame number 63, and `"F"` means frame number A parity bit is automatically added by Zint. -[^23]: The DX number may be looked up in The (Modified) Big Film Database at +[^24]: The DX number may be looked up in The (Modified) Big Film Database at [https://thebigfilmdatabase.merinorus.com]( https://thebigfilmdatabase.merinorus.com). @@ -4193,7 +4206,7 @@ Barcode 3 are 37-bar, 52-bar and 67-bar specifications respectively, developed by Australia Post for printing Delivery Point ID (DPID) and customer information on mail items. -![`zint -b AUSPOST --compliantheight -d "96184209"`](images/auspost.svg){.trk} +![`zint -b AUSPOST --compliant -d "96184209"`](images/auspost.svg){.trk} Valid data characters are 0-9, A-Z, a-z, space and hash (#). A Format Control Code (FCC) is added by Zint and should not be included in the input data. @@ -4226,22 +4239,21 @@ lengths) if the DPID is all zeroes. A Reply Paid version of the Australia Post 4-State Barcode (FCC 45) which requires an 8-digit DPID input. -![`zint -b AUSREPLY --compliantheight -d "12345678"`](images/ausreply.svg){.trk} +![`zint -b AUSREPLY --compliant -d "12345678"`](images/ausreply.svg){.trk} #### 6.5.1.3 Routing Barcode A Routing version of the Australia Post 4-State Barcode (FCC 87) which requires an 8-digit DPID input. -![`zint -b AUSROUTE --compliantheight -d "34567890"`](images/ausroute.svg){.trk} +![`zint -b AUSROUTE --compliant -d "34567890"`](images/ausroute.svg){.trk} #### 6.5.1.4 Redirect Barcode A Redirection version of the Australia Post 4-State Barcode (FCC 92) which requires an 8-digit DPID input. -![`zint -b AUSREDIRECT --compliantheight -d -"98765432"`](images/ausredirect.svg){.trk} +![`zint -b AUSREDIRECT --compliant -d "98765432"`](images/ausredirect.svg){.trk} ### 6.5.2 Dutch Post KIX Code @@ -4249,7 +4261,7 @@ This symbology is used by Royal Dutch TPG Post (Netherlands) for Postal code and automatic mail sorting. Data input can consist of numbers 0-9 and letters A-Z and needs to be 11 characters in length. No check digit is included. -![`zint -b KIX --compliantheight -d "2500GG30250"`](images/kix.svg){.trk} +![`zint -b KIX --compliant -d "2500GG30250"`](images/kix.svg){.trk} ### 6.5.3 Royal Mail 4-State Customer Code (RM4SCC) @@ -4259,14 +4271,14 @@ A-Z and usually includes delivery postcode followed by house number. For example `"W1J0TR01"` for 1 Piccadilly Circus in London. Check digit data is generated by Zint. -![`zint -b RM4SCC --compliantheight -d "W1J0TR01"`](images/rm4scc.svg){.trk} +![`zint -b RM4SCC --compliant -d "W1J0TR01"`](images/rm4scc.svg){.trk} ### 6.5.4 Royal Mail 4-State Mailmark Developed in 2014 as a replacement for RM4SCC this 4-state symbol includes Reed- Solomon error correction. -![`zint -b MAILMARK_4S --compliantheight -d +![`zint -b MAILMARK_4S --compliant -d "21B2254800659JW5O9QA6Y"`](images/mailmark_4s.svg){.trk} Input is a pre-formatted alphanumeric string of 22 (for Barcode C) or 26 (for @@ -4310,7 +4322,7 @@ Also known as the OneCode barcode and used in the U.S. by the United States Postal Service (USPS), the Intelligent Mail system replaced the POSTNET and PLANET symbologies in 2009. -![`zint -b USPS_IMAIL --compliantheight -d +![`zint -b USPS_IMAIL --compliant -d "01234567094987654321-01234"`](images/usps_imail.svg){.trk} Intelligent Mail is a fixed length 65-bar symbol which combines routing and @@ -4329,7 +4341,7 @@ inputs are valid data entries: Used for address data on mail items for Japan Post. Accepted values are 0-9, A-Z and dash (`-`). A modulo 19 check digit is added by Zint. -![`zint -b JAPANPOST --compliantheight -d +![`zint -b JAPANPOST --compliant -d "15400233-16-4-205"`](images/japanpost.svg){.trk} ### 6.5.7 DAFT Code @@ -4357,7 +4369,7 @@ produces the same barcode (see [6.5.3 Royal Mail 4-State Customer Code (RM4SCC)]) as ```bash -zint -b RM4SCC --compliantheight -d "W1J0TR01" +zint -b RM4SCC --compliant -d "W1J0TR01" ``` \clearpage @@ -4439,7 +4451,7 @@ zint -b DATAMATRIX -d "A\^1BC\^1DEF" --extraesc encodes the data `"ABCDEF"`, where `` represents the `FNC1` character. If the data contains an extra escape sequence, it can be escaped by doubling the caret (`^`), i.e. `"\^^"` encodes `"\^"`. Note that if using ECIs -with manual FNC1s then the ECIs must be ASCII compatible.[^24] +with manual FNC1s then the ECIs must be ASCII compatible.[^25] By default Zint uses a "de facto" codeword placement for symbols of size 144 x 144 (version 24). To override this and use the now clarified ISO/IEC standard @@ -4463,7 +4475,7 @@ be given as `"123234"`. Note that both `ID1` and `ID2` must be non-zero, so e.g. `"123000"` or `"000123"` would be invalid IDs. If an ID is not given it defaults to `"001001"`. -[^24]: ASCII-compatible ECIs are ECIs 3 to 18 and 21 to 27 (see +[^25]: ASCII-compatible ECIs are ECIs 3 to 18 and 21 to 27 (see [#tbl:eci_codes]). Note in particular that ECI 899, 8-bit binary, is not considered ASCII-compatible. @@ -4768,7 +4780,7 @@ already Latin-2 formatted use the `--binary` switch (API The following example creates a symbol from data saved as a Latin-2 file: ```bash -zint -o upnqr.png -b UPNQR --scale=3 --binary -i upn.txt +zint -o upnqr.png -b UPNQR --binary -i upn.txt ``` A mask may be manually specified and the `--fast` option used as with [6.6.3 QR @@ -5217,7 +5229,7 @@ is not given, no ID is encoded. Used by the United States Postal Service (USPS), the FIM symbology is used to assist automated mail processing. -![`zint -b FIM --compliantheight -d "C"`](images/fim.svg){.trk} +![`zint -b FIM --compliant -d "C"`](images/fim.svg){.trk} There are only 5 valid symbols which can be generated using the characters A-E as shown in the table below. @@ -5514,7 +5526,7 @@ For full details, see `"backend_qt/qzint.h"`. # Annex C. Tcl Backend Binding -A Tcl binding is available in the `"backend_tcl`" sub-directory. To make on +A Tcl binding is available in the `"backend_tcl"` sub-directory. To make on Unix: ```bash diff --git a/docs/manual.txt b/docs/manual.txt index 0bcb7027..98f08945 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -450,7 +450,7 @@ Below is a brief guide to Zint Barcode Studio. 3.1 Main Window and Data Tab -[Zint Barcode Studio on startup - main window with Data tab] +[Figure 1: Zint Barcode Studio on startup - main window with Data tab] This is the main window of Zint Barcode Studio. The top of the window shows a preview of the barcode that the current settings would create. These settings @@ -483,11 +483,11 @@ available by clicking the "Menu" button, along with "CLI Equivalent...", options. Most of the options are also available in a context menu by right-clicking the preview. -[Main menu (left) and context menu (right)] +[Figure 2: Main menu (left) and context menu (right)] 3.2 GS1 Composite Groupbox -[Encoding GS1 Composite data] +[Figure 3: Encoding GS1 Composite data] In the middle of the Data tab is an area for creating composite symbologies which appears when the currently selected symbology supports the GS1 Composite @@ -503,7 +503,7 @@ discussed. 3.3 Additional ECI/Data Segments Groupbox -[Encoding multiple segments] +[Figure 4: Encoding multiple segments] For symbologies that support ECIs (Extended Channel Interpretations) the middle of the Data tab is an area for entering additional data segments with their own @@ -512,7 +512,7 @@ specified. See 4.16 Multiple Segments for details. 3.4 Symbology-specific Groupbox -[Code 2 of 5 Interleaved Groupbox] +[Figure 5: Code 2 of 5 Interleaved Groupbox] Many symbologies have extra options to change the content, format and appearance of the symbol generated. For those with few additional options (and no support @@ -527,7 +527,7 @@ a second Symbology-specific tab, shown next. 3.5 Symbology-specific Tab -[Aztec Code Tab] +[Figure 6: Aztec Code Tab] A second tab appears for those symbologies with more than a few extra options. @@ -539,7 +539,7 @@ as part of a Structured Append sequence of symbols (see 4.17 Structured Append). 3.6 Appearance Tab -[Appearance Tab] +[Figure 7: Appearance Tab] The Appearance tab can be used to adjust the dimensions and other properties of the symbol. @@ -559,14 +559,14 @@ The size of the saved image can be specified with "Printing Scale", and also by clicking the [scaling] icon to invoke the Set Printing Scale Dialog - see 4.9 Adjusting Image Size (X-dimension) for further details. -[Adjusting the Print Size] +[Figure 8: Adjusting the Print Size] The foreground and background colours can be set either using the text boxes which accept "RRGGBBAA" hexadecimal values and "C,M,Y,K" decimal percentage values, or by clicking the foreground eye [eye] and background eye [eye] buttons which invoke a colour picker. -[The colour picker tool] +[Figure 9: The colour picker tool] (Note that to change the colours visually, the luminance slider, the long narrow column on the right, must be adjusted.) The color picker only deals in RGB(A), @@ -578,7 +578,7 @@ the swap [swap] button next to it. 3.7 Data Dialog -[Entering longer text input] +[Figure 10: Entering longer text input] Clicking on the ellipsis "..." button next to the "Data to Encode" text box in the Data tab opens a larger window which can be used to enter longer strings of @@ -597,7 +597,7 @@ escape sequences, see 4.1 Inputting Data.) 3.8 Sequence Dialog -[Creating a sequence of barcode symbols] +[Figure 11: Creating a sequence of barcode symbols] Clicking on the sequence button (labelled "1234..") in the Data tab opens the Sequence Dialog. This allows you to create multiple barcode images by entering a @@ -610,9 +610,9 @@ meanings as given below: Character Effect --------------------- -------------------------- - $ Insert leading zeroes - # Insert leading spaces - * Insert leading asterisks + $ (dollar) Insert leading zeroes + # (hash) Insert leading spaces + * (asterisk) Insert leading asterisks Any other character Interpreted literally Table 1: Sequence Format Characters @@ -622,7 +622,7 @@ up the Export Dialog, discussed next. 3.9 Export Dialog -[Setting filenames for an exported sequence of barcode symbols] +[Figure 12: Setting filenames for an exported sequence of barcode symbols] The Export Dialog invoked by pressing the "Export..." button in the Sequence Dialog sets the parameters for exporting the sequence of barcode images. Here @@ -632,7 +632,7 @@ information are taken from the main window. 3.10 CLI Equivalent Dialog -[Replicating via the command line] +[Figure 13: Replicating via the command line] The CLI Equivalent Dialog can be invoked from the main menu or the context menu (Figure 2: Main menu (left) and context menu (right)) and displays the CLI @@ -651,9 +651,9 @@ if ".EXE" is not in your PATHEXT environment variable, i.e.: For compatibility with Windows the examples use double quotes to delimit data, though on Unix single quotes are generally preferable as they stop the shell -from processing any characters such as backslash or dollar. A single quote -itself is dealt with by terminating the single-quoted text, backslashing the -single quote, and then continuing: +from processing characters such as backslash. A single quote itself is dealt +with by terminating the single-quoted text, backslashing the single quote, and +then continuing: zint -d 'Text containing a single quote '\'' in the middle' @@ -672,6 +672,10 @@ ambiguity. For long names a space or an equals sign may be used. For instance: The examples use a space separator for short option names, and an equals sign for long option names. +Long options may be abbreviated up to nonambiguity. For instance +--compliantheight may be shortened to --compliant, or even --com, but note that +future additions may necessitate longer abbreviations. + 4.1 Inputting Data The data to encode can be entered at the command line using the -d or --data @@ -681,14 +685,13 @@ option, for example This will encode the text "This Text". Zint will use the default symbology, Code 128, and output to the default file "out.png" in the current directory. -Alternatively, if libpng was not present when Zint was built, the default output -file will be "out.gif". +Alternatively, if Zint was not built with libpng, the default output file will +be "out.gif". -The data input to the Zint CLI is assumed to be encoded in UTF-8 (Unicode) -format (Zint will correctly handle UTF-8 data on Windows). If you are encoding -characters beyond the 7-bit ASCII set using a scheme other than UTF-8 then you -will need to set the appropriate input options as shown in 4.11 Input Modes -below. +The data input to the Zint CLI is assumed to be encoded in UTF-8 (Unicode) (Zint +will correctly handle UTF-8 data on Windows). If you are encoding characters +beyond the 7-bit ASCII set using a scheme other than UTF-8 then you will need to +set the appropriate input options as shown in 4.11 Input Modes below. Non-printing characters can be entered on the command line using backslash (\) as an escape character in combination with the --esc switch. Permissible @@ -785,8 +788,8 @@ See 6.1.10.1 Standard Code 128 (ISO 15417) for the details on manually switching Code Sets. Input data can be read directly from file using the -i or --input switch as -shown below. The input file is assumed to be UTF-8 formatted unless an -alternative mode is selected. This option replaces the use of the -d switch. +shown below. The input file is assumed to be in UTF-8 unless --binary is +selected. This option replaces the use of the -d switch. zint -i somefile.txt @@ -832,6 +835,9 @@ created if they don’t already exist: Note that on Windows, filenames are assumed to be UTF-8 encoded. +For another way to name output files, using the --mirror option, see 4.14 +Automatic Filenames. + 4.3 Selecting Barcode Type Selecting which type of barcode you wish to produce (i.e. which symbology to @@ -1106,7 +1112,7 @@ are. For instance zint -b PDF417 -d "This Text" --height=4 --heightperrow -[zint -b PDF417 -d "This Text" --height=4 --heightperrow] +[Figure 14: zint -b PDF417 -d "This Text" --height=4 --heightperrow] will produce a barcode of height 32X, with each of the 8 rows 4X high. @@ -1154,7 +1160,7 @@ X-dimension, must be specified using the --border switch. For example: zint --box --border=10 -w 10 -d "This Text" -[zint --border=10 --box -d "This Text" -w 10] +[Figure 15: zint --border=10 --box -d "This Text" -w 10] gives a box with a width 10 times the X-dimension of the symbol. Note that when specifying a box, horizontal whitespace is usually required in order to create a @@ -1166,7 +1172,7 @@ inside any vertical whitespace (or text). For matrix symbols, however, where they are decorative rather than functional, boundary bars appear outside any whitespace. -[zint -b QRCODE --border=1 --box -d "This Text" --quietzones] +[Figure 16: zint -b QRCODE --border=1 --box -d "This Text" --quietzones] Codablock F, Code 16K and Code 49 always have boundary bars, and default to particular horizontal whitespace values. Special considerations apply to ITF-14 @@ -1195,7 +1201,7 @@ below). For example the command alters the symbol to a bright green. -[zint -d "This Text" --fg=00FF00] +[Figure 17: zint -d "This Text" --fg=00FF00] Zint also supports RGBA colour information for those output file formats which support alpha channels (currently only GIF, PCX, PNG, SVG and TIF, with GIF @@ -1204,7 +1210,7 @@ format. For example: zint --fg=00ff0055 -d "This Text" -[zint -d "This Text" --fg=00FF0055] +[Figure 18: zint -d "This Text" --fg=00FF0055] will produce a semi-transparent green foreground with a standard (white) background. Note that transparency is treated differently by raster and vector @@ -1230,7 +1236,7 @@ The symbol can be rotated through four orientations using the --rotate option followed by the angle of rotation, valid values being 0 (the default), 90, 180 and 270. -[zint -d "This Text" --rotate=90] +[Figure 19: zint -d "This Text" --rotate=90] 4.9 Adjusting Image Size (X-dimension) @@ -1242,9 +1248,8 @@ applied to the X-dimension. For MaxiCode, it is multiplied by 10 for raster output, by 40 for EMF vector output, and by 2 otherwise (non-EMF vector output). For non-MaxiCode raster output, the default scale of 1 results in an X-dimension -of 2 pixels. For example for non-MaxiCode PNG images a scale of 5 will increase -the X-dimension to 10 pixels. For MaxiCode, see 4.9.3 MaxiCode Raster Scaling -below. +of 2 pixels, e.g. for PNG images a scale of 5 will increase the X-dimension to +10 pixels. For MaxiCode, see 4.9.3 MaxiCode Raster Scaling below. Scales for non-MaxiCode raster output should be given in increments of 0.5, i.e. 0.5, 1, 1.5, 2, 2.5, 3, 3.5, etc., to avoid the X-dimension varying across the @@ -1307,12 +1312,12 @@ nominal size” gives an example of an EAN-13 barcode using the X-dimension of 300 dpi (dpi = dpmm * 25.4), specify a scale of 2, since 0.33 * 12 = 3.96 pixels, or 4 pixels rounding to the nearest pixel: - zint -b EAN13 -d "501234567890" --compliantheight --scale=2 + zint -b EAN13 -d "501234567890" --compliant --scale=2 This will result in output of 37.29mm x 25.56mm (WxH) at 12 dpmm. The same result can be achieved using the --scalexdimdp option with - zint -b EAN13 -d "501234567890" --compliantheight --scalexdimdp + zint -b EAN13 -d "501234567890" --compliant --scalexdimdp as 0.33mm is the default X-dimension for EAN, and 12 dpmm the default resolution. @@ -1343,32 +1348,32 @@ Text can be set to bold using the --bold option, or a smaller font can be substituted using the --small option. The --bold and --small options can be used together if required, but only for vector output. -[zint --bold -d "This Text" --small] +[Figure 20: zint --bold -d "This Text" --small] The gap between the barcode and the text can be adjusted using the --textgap option, where the gap is given in X-dimensions, and may be negative (minimum -5.0X, maximum 10.0X). The default gap is 1X. Note that a very small gap may cause accented texts to overlap with the barcode: -[zint -d "Áccent" --textgap=0.1] +[Figure 21: zint -d "Áccent" --textgap=0.1] For SVG output, the font preferred by Zint (monospaced “OCR-B” for EAN/UPC, “Arimo” - a proportional sans-serif font metrically compatible with “Arial” - for all others) can be embedded in the file for portability using the --embedfont option: -[zint -d "Áccent" --embedfont] +[Figure 22: zint -d "Áccent" --embedfont] 4.11 Input Modes 4.11.1 Unicode, Data, and GS1 Modes -By default all CLI input data is assumed to be encoded in UTF-8 format. Many -barcode symbologies encode data using the Latin-1 (ISO/IEC 8859-1 plus ASCII) -character set, so input is converted from UTF-8 to Latin-1 before being put in -the symbol. In addition QR Code and its variants and Han Xin Code can by default -encode Japanese (Kanji) or Chinese (Hanzi) characters which are also converted -from UTF-8. +By default all CLI input data is assumed to be encoded in UTF-8. Many barcode +symbologies encode data using the Latin-1 (ISO/IEC 8859-1 plus ASCII) character +set, so input is converted from UTF-8 to Latin-1 before being put in the symbol. +In addition QR Code and its variants and Han Xin Code can by default encode +Japanese (Kanji) or Chinese (Hanzi) characters which are also converted from +UTF-8. There are two exceptions to the Latin-1 default: Grid Matrix, whose default character set is GB 2312 (Chinese); and UPNQR, whose default character set is @@ -1509,47 +1514,49 @@ information. 4.11.2.1 Input Modes and ECI Example 1 -The Euro sign U+20AC can be encoded in ISO/IEC 8859-15. The Euro sign has the -ISO/IEC 8859-15 codepoint hex "A4". It is encoded in UTF-8 as the hex sequence: -"E2 82 AC". Those 3 bytes are contained in the file "utf8euro.txt". This command -will generate the corresponding code: +The Euro sign "€" (U+20AC) can be encoded in ISO/IEC 8859-15 (ECI 17) as the hex +byte "A4". It is encoded in UTF-8 as the hex sequence: "E2 82 AC". Those 3 bytes +are contained in the file "utf8euro.txt", e.g. on Unix - zint -b DATAMATRIX --scale=10 --eci=17 -i utf8euro.txt + echo -ne '\xE2\x82\xAC' > utf8euro.txt + +This command will generate the corresponding code: + + zint -b DATAMATRIX --eci=17 -i utf8euro.txt This is equivalent to the commands (using the --esc switch): - zint -b DATAMATRIX --scale=10 --eci=17 --esc -d "\xE2\x82\xAC" + zint -b DATAMATRIX --eci=17 --esc -d "\xE2\x82\xAC" - zint -b DATAMATRIX --scale=10 --eci=17 --esc -d "\u20AC" + zint -b DATAMATRIX --eci=17 --esc -d "\u20AC" and to the command: - zint -b DATAMATRIX --scale=10 --eci=17 -d "€" + zint -b DATAMATRIX --eci=17 -d "€" -[zint -b DATAMATRIX --eci=17 -d "€"] +[Figure 23: zint -b DATAMATRIX --eci=17 -d "€"] 4.11.2.2 Input Modes and ECI Example 2 -The Chinese character with the Unicode codepoint U+5E38 can be encoded in Big5 -encoding. The Big5 representation of this character is the two hex bytes: -"B1 60" (contained in the file "big5char.txt"). The generation command for Data -Matrix is: +The Chinese character "碼" (U+78BC) can be encoded in Big5 encoding (ECI 28) as +the hex sequence: "BD 58". Those 2 bytes are contained in the file +"big5char.txt". The generation command is: - zint -b DATAMATRIX --scale=10 --eci=28 --binary -i big5char.txt + zint -b DATAMATRIX --eci=28 --binary -i big5char.txt This is equivalent to the command (using the --esc switch): - zint -b DATAMATRIX --scale=10 --eci=28 --binary --esc -d "\xB1\x60" + zint -b DATAMATRIX --eci=28 --binary --esc -d "\xBD\x58" and to the commands (no --binary switch so conversion occurs): - zint -b DATAMATRIX --scale=10 --eci=28 --esc -d "\xE5\xB8\xB8" + zint -b DATAMATRIX --eci=28 --esc -d "\xE7\xA2\xBC" - zint -b DATAMATRIX --scale=10 --eci=28 --esc -d "\u5E38" + zint -b DATAMATRIX --eci=28 --esc -d "\u78BC" - zint -b DATAMATRIX --scale=10 --eci=28 -d "常" + zint -b DATAMATRIX --eci=28 -d "碼" -[zint -b DATAMATRIX --eci=28 -d "\u5E38" --esc] +[Figure 24: zint -b DATAMATRIX --eci=28 --binary --esc -d "\xBD\x58"] 4.11.2.3 Input Modes and ECI Example 3 @@ -1557,9 +1564,9 @@ Some decoders (in particular mobile app ones) for QR Code assume UTF-8 encoding by default and do not support ECI. In this case supply UTF-8 data and use the --binary switch so that the data will be encoded as UTF-8 without conversion: - zint -b QRCODE --binary -d "UTF-8 data" + zint -b QRCODE --binary -d "€" -[zint -b QRCODE --binary -d "\xE2\x82\xAC\xE5\xB8\xB8" --esc] +[Figure 25: zint -b QRCODE --binary -d "€"] 4.11.3 GS1 Data Entry and Options @@ -1588,7 +1595,8 @@ The following symbologies accept GS1 data: GS1-128 No Yes Yes GS1 DataBar Expanded No Yes Yes - (including Stacked) + (including Expanded + Stacked) GS1 DataBar (all others) Yes (01) Yes Yes @@ -1656,9 +1664,8 @@ GS1 options. - --gs1strict, which enables the use the GS1 Syntax Engine to strictly validate GS1 data, including GS1 Digital Link URIs (by default Zint does not - validate Digital Links at all). It requires that the gs1encoders library was - present when Zint was built, otherwise the default built-in validation will - be used. + validate Digital Links at all). It requires that Zint was built with the + gs1encoders library, otherwise the default built-in validation will be used. - --gs1nocheck, for use with legacy systems that have data that does not conform to the current GS1 standard. Printable ASCII input is still checked @@ -1695,9 +1702,9 @@ characters in the output filename as shown in the table below: Input Character Interpretation ----------------- ---------------------------------------- - ~ Insert a number or 0 - # Insert a number or space - @ Insert a number or * (or + on Windows) + ~ (tilde) Insert a number or 0 + # (hash) Insert a number or space + @ (ampersand) Insert a number or * (or + on Windows) Any other Insert literally Table 11: Batch Filename Formatting @@ -1735,7 +1742,7 @@ Automatic Filenames below. The finished image files can be output directly to stdout for use as part of a pipe by using the --direct option. By default --direct will output data as a PNG -image (or GIF image if libpng is not present), but this can be altered by +image (or GIF image if Zint not built with libpng), but this can be altered by supplementing the --direct option with a --filetype option followed by the suffix of the file type required. For example: @@ -1760,13 +1767,25 @@ batch data. For example the input data "1234567" will result in a file named There are restrictions, however, on what characters can be stored in a filename, so the filename may vary from the data if the data includes non-printable -characters, for example, and may be shortened if the data input is long. +characters, for example,[12] and may be shortened if the data input is long. So +in batch mode your data must be unique given these restrictions otherwise files +will overwrite each other. To set the output file format use the --filetype option as detailed above in -4.13 Direct Output to stdout. To output to a specific directory use the -o -option giving the name of the directory (any filename will be ignored, unless ---filetype is not specified, in which case the filename’s extension will be -used). +4.13 Direct Output to stdout. For instance + + zint -d "1234567" --mirror --filetype=eps + +will output to the file "1234567.eps": + +To output to a specific directory use the -o option giving the name of the +directory, indicated by a terminating slash / (backslash \ may be used on +Windows). Any filename after the last slash will be ignored, unless --filetype +is not specified, in which case the filename’s extension will be used - e.g. + + zint -d "1234567" --mirror -o "dir/subdir/mir.eps" + +will output to the file "1234567.eps" in the "dir/subdir" directory. 4.15 Working with Dots @@ -1779,7 +1798,7 @@ maximum is 20. The default size is 0.8. The default and minimum scale for raster output in dotty mode is 1. -[zint -b CODEONE -d "123456789012345678" --dotty --vers=9] +[Figure 26: zint -b CODEONE -d "123456789012345678" --dotty --vers=9] 4.16 Multiple Segments @@ -1797,7 +1816,7 @@ specifies 3 segments: segment 0 with ECI 9 (Greek), segment 1 with ECI 7 Naturally the symbology must be ECI-aware (see Table 8: ECI-Aware Symbologies). -[zint -b AZTEC --eci=9 -d "Κείμενο" --seg1=7,"Текст" --seg2=20,"文章"] +[Figure 27: zint -b AZTEC --eci=9 -d "Κείμενο" --seg1=7,"Текст" --seg2=20,"文章"] ECIs of zero may be given, in which case Zint will automatically determine an ECI if necessary, as described in section 4.11.2 Input Modes and ECI. @@ -1816,7 +1835,7 @@ and has the format --structapp=I,C[,ID] -[zint -b DATAMATRIX -d "2nd of 3" --structapp="2,3,5006"] +[Figure 28: zint -b DATAMATRIX -d "2nd of 3" --structapp="2,3,5006"] where I is the index (position) of the symbol in the Structured Append sequence, C is the count or total number of symbols in the sequence, and ID is an optional @@ -1894,8 +1913,8 @@ using the -lzint option: To encode data in a barcode use the ZBarcode_Encode() function. To write the symbol to a file use the ZBarcode_Print() function. For example the following code takes a string from the command line and outputs a Code 128 symbol to a PNG -file named "out.png" (or a GIF file "out.gif" if libpng is not present) in the -current working directory: +file named "out.png" (or a GIF file "out.gif" if Zint not built with libpng) in +the current working directory: #include int main(int argc, char **argv) @@ -2103,7 +2122,7 @@ the buffer is given in memfile_size. For instance: } will print the SVG output to stdout (the file "mem.svg" is not created). This is -particularly useful for the textual formats EPS and SVG,[12] allowing the output +particularly useful for the textual formats EPS and SVG,[13] allowing the output to be manipulated and processed by the client. 5.7 Setting Options @@ -2124,7 +2143,7 @@ the following members: height float Symbol height in Symbol dependent X-dimensions, excluding fixed width-to-height - symbols.[13] + symbols.[14] scale float Scale factor for adjusting 1.0 size of image (sets @@ -2171,7 +2190,7 @@ the following members: end in .png, .gif, .bmp, .emf, .eps, .pcx, .svg, .tif or .txt followed by a - terminating NUL.[14] + terminating NUL.[15] primary character Primary message data for "" (empty) string more complex symbols, with @@ -2447,10 +2466,10 @@ together when adjusting this value: -------------------------- --------------------------------------------------- 0 No options selected. - BARCODE_BIND_TOP Boundary bar above the symbol only.[15] + BARCODE_BIND_TOP Boundary bar above the symbol only.[16] BARCODE_BIND Boundary bars above and below the symbol and - between rows if stacking multiple symbols.[16] + between rows if stacking multiple symbols.[17] BARCODE_BOX Add a box surrounding the symbol and whitespace. @@ -2477,7 +2496,7 @@ together when adjusting this value: Symbols in Memory (raster). BARCODE_QUIET_ZONES Add compliant quiet zones (additional to any - specified whitespace).[17] + specified whitespace).[18] BARCODE_NO_QUIET_ZONES Disable quiet zones, notably those with defaults. @@ -2728,7 +2747,7 @@ see which are set. ZINT_CAP_STACKABLE Is the symbology stackable? Note that stacked symbologies are not stackable. - ZINT_CAP_EANUPC[18] Is the symbology EAN/UPC? + ZINT_CAP_EANUPC[19] Is the symbology EAN/UPC? ZINT_CAP_COMPOSITE Does the symbology support composite data? (see 6.3 GS1 Composite Symbols (ISO 24723) below) @@ -2786,7 +2805,7 @@ option_2 and option_3 members will be set to the values used by Zint to create the barcode. This is useful for feedback if the values were left as defaults or were overridden by Zint. -In particular for symbologies that have masks,[19] option_3 will contain the +In particular for symbologies that have masks,[20] option_3 will contain the mask used as (N + 1) << 8, N being the mask. Also Aztec Code will return the actual ECC percentage used in option_1 as P << 8, where P is the integer percentage, the low byte containing the values given in Table 41: Aztec Code @@ -2802,7 +2821,7 @@ being set in content_seg_count - which will always be at least one. The source, length and eci members of zint_seg will be set accordingly - the unconverted data in source, the data length in length, and the character set the -data was converted to in eci. Any check characters encoded will be included,[20] +data was converted to in eci. Any check characters encoded will be included,[21] and for GS1 data any FNC1 separators will be represented as GS (ASCII 29) characters. UPC-A and UPC-E data will be expanded to EAN-13, as will EAN-8 but only if it has an add-on (otherwise it will remain at 8 digits), and any add-ons @@ -2818,7 +2837,7 @@ two helper functions discussed next. 5.17 UTF-8 to ECI convenience functions As a convenience the conversion done by Zint from UTF-8 to ECIs is exposed in -two helper functions (compatible with the libzueci[21] functions +two helper functions (compatible with the libzueci[22] functions zueci_utf8_to_eci() and zueci_dest_len_eci()): int ZBarcode_UTF8_To_ECI(int eci, const unsigned char *source, int length, @@ -2877,7 +2896,7 @@ Developed by Intermec in 1977 for Bell Labs as a high-density barcode to track small telephone components, Code 11 can encode data consisting of the digits 0-9 and the dash character (-) up to a maximum of 140 characters. -[zint -b CODE11 -d "9212320967"] +[Figure 29: zint -b CODE11 -d "9212320967"] Two modulo-11 check digits are added by default. To add just one check digit, set --vers=1 (API option_2 = 1). To add no check digits, set --vers=2 (API @@ -2896,7 +2915,7 @@ Also known as Code 2 of 5 Matrix, and used in industrial applications and photo development, Standard Code 2 of 5 will encode numeric input (digits 0-9) up to a maximum of 112 digits. -[zint -b C25STANDARD -d "9212320967"] +[Figure 30: zint -b C25STANDARD -d "9212320967"] No check digit is added by default. To add a check digit, set --vers=1 (API option_2 = 1). To add a check digit but not show it in the Human Readable Text, @@ -2907,7 +2926,7 @@ set --vers=2 (API option_2 = 2). Used by the International Air Transport Agency (IATA) for baggage handling, this barcode will encode numeric input (digits 0-9) up to a maximum of 80 digits. -[zint -b C25IATA -d "9212320967"] +[Figure 31: zint -b C25IATA -d "9212320967"] No check digit is added by default, but can be set the same as for 6.1.2.1 Standard Code 2 of 5. @@ -2917,7 +2936,7 @@ Standard Code 2 of 5. Industrial Code 2 of 5 can encode numeric input (digits 0-9) up to a maximum of 79 digits. -[zint -b C25IND -d "9212320967"] +[Figure 32: zint -b C25IND -d "9212320967"] No check digit is added by default, but can be set the same as for 6.1.2.1 Standard Code 2 of 5. @@ -2928,7 +2947,7 @@ A high-density barcode that encodes pairs of numbers, and so can only encode an even number of digits (0-9). If an odd number of digits is entered a leading zero is added by Zint. A maximum of 62 pairs (124 digits) can be encoded. -[zint -b C25INTER --compliantheight -d "9212320967"] +[Figure 33: zint -b C25INTER --compliant -d "9212320967"] No check digit is added by default, but can be set the same as for 6.1.2.1 Standard Code 2 of 5. @@ -2938,7 +2957,7 @@ Standard Code 2 of 5. Data Logic, also known as China Post or Hong Kong 2 of 5, can encode numeric input (digits 0-9) up to a maximum of 113 digits. -[zint -b C25LOGIC -d "9212320967"] +[Figure 34: zint -b C25LOGIC -d "9212320967"] No check digit is added by default, but can be set the same as for 6.1.2.1 Standard Code 2 of 5. @@ -2952,7 +2971,7 @@ entered, or a 14-digit input if the standard GS1 check digit is given, in which case the check digit will be verified. A standard GS1 check digit is added by Zint unless already given. -[zint -b ITF14 --compliantheight -d "9212320967145"] +[Figure 35: zint -b ITF14 --compliant -d "9212320967145"] If no border option is specified Zint defaults to adding a bounding box with a border width of 5. This behaviour can be overridden by using the --bind option @@ -2961,7 +2980,7 @@ overridden using --border (API border_width). If a symbol with no border is required this can be achieved by explicitly setting the border type to box (or bind or bindtop) and leaving the border width 0. -[zint -b ITF14 --box --compliantheight -d "9212320967145"] +[Figure 36: zint -b ITF14 --box --compliant -d "9212320967145"] 6.1.2.7 Deutsche Post Leitcode @@ -2969,7 +2988,7 @@ Leitcode is based on Interleaved Code 2 of 5 and is used by Deutsche Post for routing purposes. Leitcode requires a 13-digit numerical input to which Zint adds a check digit. -[zint -b DPLEIT -d "9212320967145"] +[Figure 37: zint -b DPLEIT -d "9212320967145"] 6.1.2.8 Deutsche Post Identcode @@ -2977,7 +2996,7 @@ Identcode is based on Interleaved Code 2 of 5 and is used by Deutsche Post for identification purposes. Identcode requires an 11-digit numerical input to which Zint adds a check digit. -[zint -b DPIDENT -d "91232096712"] +[Figure 38: zint -b DPIDENT -d "91232096712"] 6.1.3 UPC (Universal Product Code) (ISO 15420) @@ -2987,7 +3006,7 @@ UPC-A is used in the United States for retail applications, and encodes a GTIN-12, a 12-digit Global Trade Item Number that includes a standard GS1 check digit. -[zint -b UPCA --compliantheight -d "01234500005"] +[Figure 39: zint -b UPCA --compliant -d "01234500005"] Input up to 11 digits may be given, to which a check digit will be added by Zint. A 12-digit input including the check digit may also be supplied, in which @@ -3010,7 +3029,7 @@ or using the API: /* Or a space */ error = ZBarcode_Encode_and_Print(symbol, "01234500005 12345", 0, 0); -[zint -b UPCA --compliantheight -d "01234500005+12345"] +[Figure 40: zint -b UPCA --compliant -d "01234500005+12345"] A quiet zone indicator can be added to the HRT by setting --guardwhitespace (API output_options |= EANUPC_GUARD_WHITESPACE). For UPC, this is only relevant when @@ -3024,7 +3043,7 @@ or using the API: symbol->output_options |= EANUPC_GUARD_WHITESPACE; error = ZBarcode_Encode_and_Print(symbol, "01234500005+12345", 0, 0); -[zint -b UPCA --compliantheight -d "01234500005+12345" --guardwhitespace] +[Figure 41: zint -b UPCA --compliant -d "01234500005+12345" --guardwhitespace] You can adjust the gap between the main symbol and an add-on in integral multiples of the X-dimension by setting --addongap (API option_2) to a value @@ -3040,7 +3059,7 @@ Zint. If 7 digits are given then the first must be ‘0’ or ‘1’ (the latte known as number system 1 and is non-standard). Input less than 7 digits will be zero-filled. -[zint -b UPCE --compliantheight -d "123455"] +[Figure 42: zint -b UPCE --compliant -d "123455"] An 8-digit input including the check digit may also be supplied, in which case Zint will verify the check digit, or the symbology BARCODE_UPCE_CHK (38) may be @@ -3053,7 +3072,7 @@ output_options |= EANUPC_GUARD_WHITESPACE): zint -b UPCE -d "123455+12" --guardwhitespace -[zint -b UPCE --compliantheight -d "123455+12" --guardwhitespace] +[Figure 43: zint -b UPCE --compliant -d "123455+12" --guardwhitespace] You can adjust the gap between the main symbol and an add-on in integral multiples of the X-dimension by setting --addongap (API option_2) to a value @@ -3073,7 +3092,7 @@ EAN-8 and ISBN (a subset of EAN-13). EAN-13 encodes a GTIN-13, a 13-digit Global Trade Item Number that includes a standard GS1 check digit. -[zint -b EAN13 --compliantheight -d "952012345678"] +[Figure 44: zint -b EAN13 --compliant -d "952012345678"] Input up to 12 digits may be given, to which a check digit will be added by Zint, or a 13-digit input can be supplied in which case Zint will validate the @@ -3090,22 +3109,22 @@ be achieved using the API: symbol->symbology = BARCODE_EAN13; error = ZBarcode_Encode_and_Print(symbol, "952012345678+21", 0, 0); -[zint -b EAN13 --compliantheight -d "952012345678+21"] +[Figure 45: zint -b EAN13 --compliant -d "952012345678+21"] Options to add quiet zone indicators and to adjust the add-on gap and the guard bar descent height are the same as for 6.1.3.2 UPC Version E. For instance: zint -b EAN13 -d "9520123456788" --guarddescent=2.5 --guardwhitespace -[zint -b EAN13 --compliantheight -d "9520123456788" –guarddescent=2.5 -–guardwhitespace] +[Figure 46: zint -b EAN13 --compliant -d "9520123456788" --guarddescent=2.5 --gu +ardwhitespace] 6.1.4.2 EAN-8 EAN-8 is a shortened version of EAN-13, encoding a GTIN-8 (a GTIN-13 with 5 leading zeroes implied), for use with small packages. -[zint -b EAN8 --compliantheight -d "9520000"] +[Figure 47: zint -b EAN8 --compliant -d "9520000"] Input up to 7 digits may be supplied, to which Zint will add a standard GS1 check digit. An 8-digit input including the check digit may also be given, in @@ -3123,7 +3142,7 @@ or using the API: symbol->output_options |= EANUPC_GUARD_WHITESPACE; error = ZBarcode_Encode_and_Print(symbol, "9520000", 0, 0); -[zint -b EAN8 --compliantheight -d "9520000" –guardwhitespace] +[Figure 48: zint -b EAN8 --compliant -d "9520000" –guardwhitespace] 2-digit and 5-digit add-ons may also be added, and the gap adjusted, as with EAN-13, but this usage is non-standard and Zint will issue a warning on use. @@ -3135,11 +3154,11 @@ SBN, 10-digit ISBN or 13-digit ISBN-13 data. The relevant check digit needs to be present in the input data and will be verified before the symbol is generated. -[zint -b ISBNX --compliantheight -d "9789295055124"] +[Figure 49: zint -b ISBNX --compliant -d "9789295055124"] As with EAN-13, a quiet zone indicator can be added using --guardwhitespace: -[zint -b ISBNX --compliantheight -d "9789295055124" --guardwhitespace] +[Figure 50: zint -b ISBNX --compliant -d "9789295055124" --guardwhitespace] 2-digit and 5-digit add-on symbols can be added using a + or space character, and there are options to adjust the add-on gap and the guard bar descent @@ -3151,7 +3170,7 @@ As a convenience, 2-digit and 5-digit add-ons may be generated as standalone symbols using the symbologies BARCODE_EAN_2ADDON (11) and BARCODE_EAN_5ADDON (12). -[zint -b EAN_2ADDON --compliantheight -d "12"] +[Figure 51: zint -b EAN_2ADDON --compliant -d "12"] As with the main EAN/UPC symbols a quiet zone indicator can be added using ---guardwhitespace. For instance @@ -3165,7 +3184,7 @@ API: symbol->output_options |= EANUPC_GUARD_WHITESPACE; error = ZBarcode_Encode_and_Print(symbol, "54321", 0, 0); -[zint -b EAN_5ADDON --compliantheight -d "54321" –guardwhitespace] +[Figure 52: zint -b EAN_5ADDON --compliant -d "54321" –guardwhitespace] 6.1.5 Plessey @@ -3175,7 +3194,7 @@ Also known as Plessey Code, this symbology was developed by the Plessey Company Ltd. in the UK. The symbol can encode data consisting of digits (0-9) or letters A-F (i.e. hexadecimal digits) up to a maximum of 67 characters. -[zint -b PLESSEY -d "C64"] +[Figure 53: zint -b PLESSEY -d "C64"] The symbol includes two hidden CRC check digits, which may be shown in the Human Readable Text by setting --vers=1 (API option_2 = 1). @@ -3185,7 +3204,7 @@ Readable Text by setting --vers=1 (API option_2 = 1). Based on UK Plessey and developed by MSI Data Corporation, MSI Plessey can encode numeric (digits 0-9) input of up to 92 digits. -[zint -b MSI_PLESSEY -d "6502" --vers=2] +[Figure 54: zint -b MSI_PLESSEY -d "6502" --vers=2] MSI Plessey has a range of check digit options that are selectable by setting --vers (API option_2), shown in the table below: @@ -3214,7 +3233,7 @@ Telepen Alpha was developed in 1972 by SB Electronic Systems Limited and can encode ASCII text input, up to a maximum of 69 characters. Telepen includes a hidden modulo-127 check digit, added by Zint. -[zint -b TELEPEN --compliantheight -d "Z8000"] +[Figure 55: zint -b TELEPEN --compliant -d "Z8000"] AIM-defined Start/Stop characters may be enabled by setting --vers=1 (API option_2 = 1). In this mode control character DLE (ASCII 16, escape sequence \L) @@ -3222,7 +3241,7 @@ indicates a switch from Full ASCII to Compressed Numeric, where each symbol character encodes a digit pair (or a “digit X” pair - see Telepen Numeric below): -[zint -b TELEPEN --compliantheight -d "Z\L8000" -esc --vers=1] +[Figure 56: zint -b TELEPEN --compliant -d "Z\L8000" -esc --vers=1] However not all barcode readers recognise this mode so check before using. @@ -3235,17 +3254,17 @@ is not (the pair "X3" is not valid). If an odd number of digits is supplied, Zint will add a leading zero. Up to 138 digits can be encoded. A hidden modulo-127 check digit is added by Zint. -[zint -b TELEPEN_NUM --compliantheight -d "466X33"] +[Figure 57: zint -b TELEPEN_NUM --compliant -d "466X33"] Additionally trailing ASCII characters may be encoded by prefixing them with a DLE control character (ASCII 16, escape sequence \L) and appending them to the numeric data: -[zint -b TELEPEN_NUM --compliantheight -d "12\LAB" --esc] +[Figure 58: zint -b TELEPEN_NUM --compliant -d "12\LAB" --esc] This method allows odd numbers to be encoded without a leading zero: -[zint -b TELEPEN_NUM --compliantheight -d "123\L4" --esc] +[Figure 59: zint -b TELEPEN_NUM --compliant -d "123\L4" --esc] AIM-defined Start/Stop characters may be enabled by setting --vers=1 (API option_2 = 1). This allows barcode readers to detect Compressed Numeric data @@ -3261,7 +3280,7 @@ Standard Code 39 was introduced in 1975 by Intermec. Input data can be up to 86 characters in length and can include the characters 0-9, A-Z, dash (-), full stop (.), space, asterisk (*), dollar ($), slash (/), plus (+) and percent (%). -[zint -b CODE39 --compliantheight -d "1A" --vers=1] +[Figure 60: zint -b CODE39 --compliant -d "1A" --vers=1] The standard does not require a check digit but a modulo-43 check digit can be added if desired by setting --vers=1 (API option_2 = 1). To add a check digit @@ -3272,7 +3291,7 @@ but not show it in the Human Readable Text, set --vers=2 (API option_2 = 2). Also known as Code 39e and Code39+, this symbology expands on Standard Code 39 to provide support for the full 7-bit ASCII character set. -[zint -b EXCODE39 --compliantheight -d "123.45#@fd"] +[Figure 61: zint -b EXCODE39 --compliant -d "123.45#@fd"] The check digit options are the same as for 6.1.7.1 Standard Code 39 (ISO 16388). @@ -3284,7 +3303,7 @@ accepting up to 123 characters. Two check characters are added by Zint. By default these check characters are not shown in the Human Readable Text, but may be shown by setting --vers=1 (API option_2 = 1). -[zint -b CODE93 --compliantheight -d "C93"] +[Figure 62: zint -b CODE93 --compliant -d "C93"] 6.1.7.4 PZN (Pharmazentralnummer) @@ -3293,7 +3312,7 @@ PZN encodes a 7-digit number to which Zint will add a modulo-11 check digit (PZN8). Input less than 7 digits will be zero-filled. An 8-digit input can be supplied in which case Zint will validate the check digit. -[zint -b PZN --compliantheight -d "2758089"] +[Figure 63: zint -b PZN --compliant -d "2758089"] To encode a PZN7 (obsolete since 2013) instead set --vers=1 (API option_2 = 1) and supply up to 7 digits. As with PZN8, a modulo-11 check digit will be added @@ -3307,7 +3326,7 @@ LOGMARS encodes the same character set as 6.1.7.1 Standard Code 39 (ISO 16388), and the check digit options are also the same. Input is restricted to a maximum of 30 characters. -[zint -b LOGMARS --compliantheight -d "12345/ABCDE" --vers=1] +[Figure 64: zint -b LOGMARS --compliant -d "12345/ABCDE" --vers=1] 6.1.7.6 Code 32 @@ -3316,7 +3335,7 @@ Sanità”) for encoding identifiers on pharmaceutical products. This symbology requires a numeric input up to 8 digits in length. A check digit is added by Zint. -[zint -b CODE32 --compliantheight -d "14352312"] +[Figure 65: zint -b CODE32 --compliant -d "14352312"] 6.1.7.7 HIBC Code 39 @@ -3324,7 +3343,7 @@ This variant adds a leading '+' character and a trailing modulo-49 check digit to a standard Code 39 symbol as required by the Health Industry Barcode standards. -[zint -b HIBC_39 --compliantheight -d "14352312"] +[Figure 66: zint -b HIBC_39 --compliant -d "14352312"] 6.1.7.8 Vehicle Identification Number (VIN) @@ -3332,7 +3351,7 @@ A variation of Code 39 that for vehicle identification numbers used in North America (first character '1' to '5') has a check character verification stage. A 17 character input (0-9, and A-Z excluding 'I', 'O' and 'Q') is required. -[zint -b VIN -d "2FTPX28L0XCA15511" --vers=1] +[Figure 67: zint -b VIN -d "2FTPX28L0XCA15511" --vers=1] An invisible Import character prefix 'I' can be added by setting --vers=1 (API option_2 = 1). @@ -3344,7 +3363,7 @@ and Monarch, this symbology was developed in 1972 from earlier versions by Pitney Bowes-Alpex for retail price marking. The American Blood Commission adopted Codabar in 1979 as the standard barcode for blood products. -[zint -b CODABAR --compliantheight -d "A37859B"] +[Figure 68: zint -b CODABAR --compliant -d "A37859B"] Codabar can encode up to 103 characters starting and ending with the letters A-D and containing between these letters the numbers 0-9, dash (-), dollar ($), @@ -3360,7 +3379,7 @@ Developed by Laetus, Pharmacode One-Track is used for the identification of pharmaceuticals. The symbology is able to encode whole numbers between 3 and 131070. -[zint -b PHARMA --compliantheight -d "130170"] +[Figure 69: zint -b PHARMA --compliant -d "130170"] 6.1.10 Code 128 @@ -3372,7 +3391,7 @@ and uses a three-Code Set system to compress the data into a smaller symbol. Zint automatically switches between Code Sets A, B and C (but see below) and adds a hidden modulo-103 check digit. -[zint -b CODE128 --bind -d "130170X178"] +[Figure 70: zint -b CODE128 --bind -d "130170X178"] Code 128 is the default barcode symbology used by Zint. In addition Zint supports the encoding of ISO/IEC 8859-1 (non-English) characters in Code 128 @@ -3414,10 +3433,10 @@ alphanumerics) are not recommended. 6.1.10.2 Code 128 Suppress Code Set C (Code Sets A and B only) It is sometimes advantageous to stop Code 128 from using Code Set C which -compresses numerical data. The BARCODE_CODE128AB[22] variant (symbology 60) +compresses numerical data. The BARCODE_CODE128AB[23] variant (symbology 60) suppresses Code Set C in favour of Code Sets A and B. -[zint -b CODE128AB -d "130170X178"] +[Figure 71: zint -b CODE128AB -d "130170X178"] Note that the special extra escapes mentioned above are not available for this variant (nor for any other). @@ -3429,8 +3448,8 @@ defined by the GS1 General Specifications. Data should be in one of the formats described in 4.11.3.1 GS1 Data Entry. Here we will use the square bracket format. -[zint -b GS1_128 --compliantheight -d "[01]98898765432106[3202]012345[15]991231" -] +[Figure 72: zint -b GS1_128 --compliant -d "[01]98898765432106[3202]012345[15]99 +1231"] Fixed length data should be entered at the appropriate length for correct encoding. GS1-128 does not support extended ASCII (ISO/IEC 8859-1) characters. @@ -3447,7 +3466,7 @@ digits entered, or a 14-digit number if the standard GS1 check digit is given, in which case the check digit will be verified. The GS1 check digit (if not given) and HRT-only AI "(01)" are added by Zint. -[zint -b EAN14 --compliantheight -d "9889876543210"] +[Figure 73: zint -b EAN14 --compliant -d "9889876543210"] 6.1.10.5 NVE-18 (SSCC-18) @@ -3458,7 +3477,7 @@ which will be prefixed with leading zeros if less than 17 digits given, or an 18-digit input if the GS1 check digit is included, in which case the check digit will be verified. Check digit(s) and HRT-only AI "(00)" are added by Zint. -[zint -b NVE18 --compliantheight -d "37612345000001003"] +[Figure 74: zint -b NVE18 --compliant -d "37612345000001003"] 6.1.10.6 HIBC Code 128 @@ -3466,13 +3485,13 @@ This variation adds a leading '+' character and a trailing modulo-49 check digit to a standard Code 128 symbol as required by the Health Industry Barcode standards. -[zint -b HIBC_128 -d "A123BJC5D6E71"] +[Figure 75: zint -b HIBC_128 -d "A123BJC5D6E71"] 6.1.10.7 DPD Code Another variation of Code 128 as used by DPD (Deutscher Paketdienst). -[zint -b DPD --compliantheight -d "000393206219912345678101040"] +[Figure 76: zint -b DPD --compliant -d "000393206219912345678101040"] DPD Code requires a 27 or 28 character input. For 28 character input, the first character is an identification tag (Barcode ID), which should usually be "%" @@ -3516,7 +3535,7 @@ format "SSNNNNNNNNXCC", where "SS" is a two-character alphabetic service indicator, "NNNNNNNN" is an 8-digit serial number, "X" is a modulo-11 check digit, and "CC" is a two-character ISO 3166-1 country code. -[zint -b UPU_S10 --compliantheight -d "EE876543216CA"] +[Figure 77: zint -b UPU_S10 --compliant -d "EE876543216CA"] The check digit may be omitted in which case Zint will add it. Warnings will be generated if the service indicator is non-standard or the country code is not @@ -3540,13 +3559,13 @@ digit and HRT-only Application Identifier of "(01)" are added by Zint. (A case the check digit will be verified.) Input less than 13 digits will be zero-filled. -[zint -b DBAR_OMN --compliantheight -d "0950110153001"] +[Figure 78: zint -b DBAR_OMN --compliant -d "0950110153001"] GS1 DataBar Omnidirectional symbols should have a height of 33 or greater. To produce a GS1 DataBar Truncated symbol set the symbol height to a value between 13 and 32. Truncated symbols may not be scannable by omnidirectional scanners. -[zint -b DBAR_OMN -d "0950110153001" --height=13] +[Figure 79: zint -b DBAR_OMN -d "0950110153001" --height=13] 6.1.11.2 GS1 DataBar Limited @@ -3558,7 +3577,7 @@ digit and HRT-only Application Identifier of "(01)" are added by Zint, and a 14-digit code may be given in which case the check digit will be verified. Input less than 13 digits will be zero-filled. -[zint -b DBAR_LTD --compliantheight -d "0950110153001"] +[Figure 80: zint -b DBAR_LTD --compliant -d "0950110153001"] 6.1.11.3 GS1 DataBar Expanded @@ -3567,8 +3586,8 @@ encoding multiple AIs in a single symbol. Data should be in one of the formats described in 4.11.3.1 GS1 Data Entry, and will be displayed using parentheses (round brackets) in the Human Readable Text. -[zint -b DBAR_EXP --compliantheight -d "[01]98898765432106[3202]012345[15]991231 -"] +[Figure 81: zint -b DBAR_EXP --compliant -d "[01]98898765432106[3202]012345[15]9 +91231"] The GTIN-14 data for AI (01) must include the standard GS1 check digit as this is not calculated by Zint when this symbology is encoded. Data for fixed-length @@ -3583,7 +3602,7 @@ Expanded input: The Korean Postal Barcode is used to encode a 6-digit number and includes one check digit. -[zint -b KOREAPOST -d "923457"] +[Figure 82: zint -b KOREAPOST -d "923457"] 6.1.13 Channel Code @@ -3593,7 +3612,7 @@ the --vers option (API option_2). It can also be determined by the length of the input data: e.g. a three character input string generates a 4 channel code by default. -[zint -b CHANNEL -d "453678" --compliantheight] +[Figure 83: zint -b CHANNEL -d "453678" --compliant] The maximum values permitted depend on the number of channels used as shown in the table below: @@ -3618,7 +3637,7 @@ input must be alphanumeric, excluding the letter O, and must be from 7 to 18 characters in length. A single check character is added by Zint, appearing in the 2nd character position. Lowercase input is automatically made uppercase. -[zint -b BC412 -d "AQ45670" --compliantheight] +[Figure 84: zint -b BC412 -d "AQ45670" --compliant] 6.2 Stacked Symbologies @@ -3640,7 +3659,7 @@ once on a symbol. For example: error = ZBarcode_Encode(symbol, "That", 0); error = ZBarcode_Print(symbol); -[zint -d "This" -d "That"] +[Figure 85: zint -d "This" -d "That"] Note that the Human Readable Text will be that of the last data, so it’s best to use the option --notext (API show_hrt = 0). @@ -3652,7 +3671,7 @@ can be set by --separator (API option_3): zint --bind --notext --separator=2 -d "This" -d "That" -[zint --notext --bind --separator=2 -d "This" -d "That"] +[Figure 86: zint --notext --bind --separator=2 -d "This" -d "That"] A more sophisticated method is to use some type of line indexing which indicates to the barcode reader which order the stacked symbols should be read in. This is @@ -3665,7 +3684,7 @@ to a maximum length of 2726 symbol characters, meaning for instance up to 2726 all ASCII characters, or 5452 all numeric, or up to 1363 all extended ASCII (ISO/IEC 8859-1). -[zint -b CODABLOCKF -d "CODABLOCK F Symbology" --rows=3] +[Figure 87: zint -b CODABLOCKF -d "CODABLOCK F Symbology" --rows=3] The width of the Codablock F symbol can be set using the --cols option (API option_2), to a value between 9 and 67. The height (number of rows) can be set @@ -3686,7 +3705,7 @@ character encoding in the same manner as Code 128. GS1 data encoding is also supported. The minimum number of rows to use can be set using the --rows option (API option_1), with values from 2 to 16. -[zint -b CODE16K --compliantheight -d "ab0123456789"] +[Figure 88: zint -b CODE16K --compliant -d "ab0123456789"] 6.2.4 PDF417 (ISO 15438) @@ -3695,7 +3714,7 @@ amount of data into a small space. Zint supports encoding up to the ISO standard maximum symbol size of 925 codewords which (at error correction level 0) allows a maximum data size of 1850 text characters, or 2710 digits. -[zint -b PDF417 -d "PDF417"] +[Figure 89: zint -b PDF417 -d "PDF417"] The width of the generated PDF417 symbol can be specified at the command line using the --cols switch (API option_2) followed by a number between 1 and 30, @@ -3727,7 +3746,7 @@ Previously known as Truncated PDF417, Compact PDF417 omits some per-row overhead to produce a narrower but less robust symbol. Options are the same as for PDF417 above. -[zint -b PDF417COMP -d "PDF417"] +[Figure 90: zint -b PDF417COMP -d "PDF417"] 6.2.6 MicroPDF417 (ISO 24728) @@ -3739,7 +3758,7 @@ dependent on symbol size. The number of data columns used can be determined using the --cols switch (API option_2) as with PDF417. The amount of data determines the number of rows. -[zint -b MICROPDF417 -d "12345678"] +[Figure 91: zint -b MICROPDF417 -d "12345678"] MicroPDF417 uses Latin-1 character encoding by default but also supports the ECI encoding mechanism. A separate symbology ID (BARCODE_HIBC_MICPDF) can be used to @@ -3765,7 +3784,7 @@ except that its height is reduced and its central separator is a single row, making it suitable for small items when omnidirectional scanning is not required. -[zint -b DBAR_STK --compliantheight -d "9889876543210"] +[Figure 92: zint -b DBAR_STK --compliant -d "9889876543210"] 6.2.7.2 GS1 DataBar Stacked Omnidirectional @@ -3773,7 +3792,7 @@ A stacked variation of the GS1 DataBar Omnidirectional symbol requiring the same input (see 6.1.11.1 GS1 DataBar Omnidirectional and GS1 DataBar Truncated). The data is encoded in two rows of bars with a central 3-row separator. -[zint -b DBAR_OMNSTK --compliantheight -d "9889876543210"] +[Figure 93: zint -b DBAR_OMNSTK --compliant -d "9889876543210"] 6.2.7.3 GS1 DataBar Expanded Stacked @@ -3781,8 +3800,8 @@ A stacked variation of the GS1 DataBar Expanded symbol for smaller packages. Input is the same as for GS1 DataBar Expanded (see 6.1.11.3 GS1 DataBar Expanded), with the same maximum capacity. -[zint -b DBAR_EXPSTK --compliantheight -d "[01]98898765432106[3202]012345[15]991 -231"] +[Figure 94: zint -b DBAR_EXPSTK --compliant -d "[01]98898765432106[3202]012345[1 +5]991231"] The width of the symbol can be altered using the --cols switch (API option_2). In this case the number of columns (values 1 to 11) relates to the number of @@ -3802,7 +3821,7 @@ or 81 numeric digits. GS1 data encoding is also supported. The minimum number of fixed-width rows to use can be set using the --rows option (API option_1), with values from 2 to 8. -[zint -b CODE49 --compliantheight -d "MULTIPLE ROWS IN CODE 49"] +[Figure 95: zint -b CODE49 --compliant -d "MULTIPLE ROWS IN CODE 49"] 6.3 GS1 Composite Symbols (ISO 24723) @@ -3890,8 +3909,8 @@ which is being used. CC-A can encode up to 56 numeric digits (including AIs) or an alphanumeric string of shorter length (e.g. if all capitals, at most 30, excluding AI). To select CC-A use --mode=1 (API option_1 = 1). -[zint -b EAN13_CC --compliantheight -d "[99]1234-abcd" --mode=1 --primary=331234 -567890] +[Figure 96: zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=1 --primary=3 +31234567890] 6.3.2 CC-B @@ -3901,8 +3920,8 @@ to be encoded and the type of linear component which is being used. CC-B can encode up to 338 numeric digits or an alphanumeric string of shorter length. To select CC-B use --mode=2 (API option_1 = 2). -[zint -b EAN13_CC --compliantheight -d "[99]1234-abcd" --mode=2 --primary=331234 -567890] +[Figure 97: zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=2 --primary=3 +31234567890] 6.3.3 CC-C @@ -3910,8 +3929,8 @@ This system uses PDF417 and can only be used in conjunction with a GS1-128 linear component. CC-C can encode up to 2361 numeric digits or an alphanumeric string of shorter length. To select CC-C use --mode=3 (API option_1 = 3). -[zint -b GS1_128_CC --compliantheight -d "[99]1234-abcd" --mode=3 --primary="[01 -]03312345678903"] +[Figure 98: zint -b GS1_128_CC --compliant -d "[99]1234-abcd" --mode=3 --primary +="[01]03312345678903"] 6.4 Two-Track Symbols @@ -3922,7 +3941,7 @@ One-Track (see 6.1.9 Pharmacode One-Track) used for the identification of pharmaceuticals. The symbology is able to encode whole numbers between 4 and 64570080. -[zint -b PHARMA_TWO --compliantheight -d "29876543"] +[Figure 99: zint -b PHARMA_TWO --compliant -d "29876543"] 6.4.2 POSTNET @@ -3934,7 +3953,7 @@ ZIP input), PostNet10 (5-digit ZIP + 4-digit user data) and PostNet12 (5-digit ZIP + 6-digit user data), and a warning will be issued if the input length is not one of these. -[zint -b POSTNET --compliantheight -d "12345678901"] +[Figure 100: zint -b POSTNET --compliant -d "12345678901"] 6.4.3 PLANET @@ -3946,7 +3965,7 @@ lengths used by USPS were Planet12 (11-digit input) and Planet14 (13-digit input), and as with POSTNET a warning will be issued if the length is not one of these. -[zint -b PLANET --compliantheight -d "4012345235636"] +[Figure 101: zint -b PLANET --compliant -d "4012345235636"] 6.4.4 Brazilian CEPNet @@ -3955,7 +3974,7 @@ service, to encode CEP (Código de Endereçamento Postal) numbers on mail items. Input should consist of eight digits with the check digit being automatically added by Zint. -[zint -b CEPNET --compliantheight -d "12345678"] +[Figure 102: zint -b CEPNET --compliant -d "12345678"] 6.4.5 DX Film Edge Barcode @@ -3963,7 +3982,7 @@ Introduced by Kodak in the 1980s, the DX (Digital Index) barcode is printed on the bottom edge of 35mm film to aid in the reordering and post-processing of prints. -[zint -b DXFILMEDGE --compliantheight -d "112-1/10A"] +[Figure 103: zint -b DXFILMEDGE --compliant -d "112-1/10A"] The data can be in two parts. The first part (required) is the “DX number”, identifying the manufacturer and film type - the National Association of @@ -3976,7 +3995,7 @@ first and last digit are ignored, leaving a 4-digit DX Extract number in any case, which must be in the range 16 to 2047. The second format "NNN-NN" represents the DX Extract as two numbers separated by a dash (-), the first number being 1 to 3 digits (range 1 to 127) and the second 1 to 2 digits (range -0 to 15).[23] +0 to 15).[24] The optional frame number is a number in the range 0 to 63, and may have a half frame indicator "A" appended. Special character sequences (with or without a @@ -3996,7 +4015,7 @@ Barcode 3 are 37-bar, 52-bar and 67-bar specifications respectively, developed by Australia Post for printing Delivery Point ID (DPID) and customer information on mail items. -[zint -b AUSPOST --compliantheight -d "96184209"] +[Figure 104: zint -b AUSPOST --compliant -d "96184209"] Valid data characters are 0-9, A-Z, a-z, space and hash (#). A Format Control Code (FCC) is added by Zint and should not be included in the input data. @@ -4029,21 +4048,21 @@ lengths) if the DPID is all zeroes. A Reply Paid version of the Australia Post 4-State Barcode (FCC 45) which requires an 8-digit DPID input. -[zint -b AUSREPLY --compliantheight -d "12345678"] +[Figure 105: zint -b AUSREPLY --compliant -d "12345678"] 6.5.1.3 Routing Barcode A Routing version of the Australia Post 4-State Barcode (FCC 87) which requires an 8-digit DPID input. -[zint -b AUSROUTE --compliantheight -d "34567890"] +[Figure 106: zint -b AUSROUTE --compliant -d "34567890"] 6.5.1.4 Redirect Barcode A Redirection version of the Australia Post 4-State Barcode (FCC 92) which requires an 8-digit DPID input. -[zint -b AUSREDIRECT --compliantheight -d "98765432"] +[Figure 107: zint -b AUSREDIRECT --compliant -d "98765432"] 6.5.2 Dutch Post KIX Code @@ -4051,7 +4070,7 @@ This symbology is used by Royal Dutch TPG Post (Netherlands) for Postal code and automatic mail sorting. Data input can consist of numbers 0-9 and letters A-Z and needs to be 11 characters in length. No check digit is included. -[zint -b KIX --compliantheight -d "2500GG30250"] +[Figure 108: zint -b KIX --compliant -d "2500GG30250"] 6.5.3 Royal Mail 4-State Customer Code (RM4SCC) @@ -4061,14 +4080,14 @@ A-Z and usually includes delivery postcode followed by house number. For example "W1J0TR01" for 1 Piccadilly Circus in London. Check digit data is generated by Zint. -[zint -b RM4SCC --compliantheight -d "W1J0TR01"] +[Figure 109: zint -b RM4SCC --compliant -d "W1J0TR01"] 6.5.4 Royal Mail 4-State Mailmark Developed in 2014 as a replacement for RM4SCC this 4-state symbol includes Reed- Solomon error correction. -[zint -b MAILMARK_4S --compliantheight -d "21B2254800659JW5O9QA6Y"] +[Figure 110: zint -b MAILMARK_4S --compliant -d "21B2254800659JW5O9QA6Y"] Input is a pre-formatted alphanumeric string of 22 (for Barcode C) or 26 (for Barcode L) characters, producing a symbol with 66 or 78 bars respectively. The @@ -4113,7 +4132,7 @@ Also known as the OneCode barcode and used in the U.S. by the United States Postal Service (USPS), the Intelligent Mail system replaced the POSTNET and PLANET symbologies in 2009. -[zint -b USPS_IMAIL --compliantheight -d "01234567094987654321-01234"] +[Figure 111: zint -b USPS_IMAIL --compliant -d "01234567094987654321-01234"] Intelligent Mail is a fixed length 65-bar symbol which combines routing and customer information in a single symbol. Input data consists of a 20-digit @@ -4131,7 +4150,7 @@ inputs are valid data entries: Used for address data on mail items for Japan Post. Accepted values are 0-9, A-Z and dash (-). A modulo 19 check digit is added by Zint. -[zint -b JAPANPOST --compliantheight -d "15400233-16-4-205"] +[Figure 112: zint -b JAPANPOST --compliant -d "15400233-16-4-205"] 6.5.7 DAFT Code @@ -4141,8 +4160,8 @@ and 'T' where these refer to descender, ascender, full (ascender and descender) and tracker (neither ascender nor descender) respectively. All other characters are invalid. -[zint -b DAFT -d "AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF" --height=8.494 --vers= -256] +[Figure 113: zint -b DAFT -d "AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF" --height=8 +.494 --vers=256] The ratio of the tracker size to full height can be given in thousandths (permille) using the --vers option (API option_2). The default value is 250 @@ -4156,7 +4175,7 @@ For example the following produces the same barcode (see 6.5.3 Royal Mail 4-State Customer Code (RM4SCC)) as - zint -b RM4SCC --compliantheight -d "W1J0TR01" + zint -b RM4SCC --compliant -d "W1J0TR01" 6.6 Matrix Symbols @@ -4166,7 +4185,7 @@ Also known as Semacode this symbology was developed in 1989 by Acuity CiMatrix in partnership with the U.S. DoD and NASA. The symbol can encode a large amount of data in a small area. -[zint -b HIBC_DM -d "/ACMRN123456/V200912190833" --fast --square] +[Figure 114: zint -b HIBC_DM -d "/ACMRN123456/V200912190833" --fast --square] Data Matrix encodes characters in the Latin-1 set by default but also supports encoding in other character sets using the ECI mechanism. It can also encode GS1 @@ -4232,7 +4251,7 @@ Escape Sequences. For instance encodes the data "ABCDEF", where represents the FNC1 character. If the data contains an extra escape sequence, it can be escaped by doubling the caret (^), i.e. "\^^" encodes "\^". Note that if using ECIs with -manual FNC1s then the ECIs must be ASCII compatible.[24] +manual FNC1s then the ECIs must be ASCII compatible.[25] By default Zint uses a “de facto” codeword placement for symbols of size 144 x 144 (version 24). To override this and use the now clarified ISO/IEC standard @@ -4256,7 +4275,8 @@ as "123234". Note that both ID1 and ID2 must be non-zero, so e.g. "123000" or 6.6.2 Royal Mail 2D Mailmark (CMDM) (Data Matrix) -[zint -b MAILMARK_2D -d "JGB 01Z999999900000001EC1A1AA1A0SN35TQ" --vers=30] +[Figure 115: zint -b MAILMARK_2D -d "JGB 01Z999999900000001EC1A1AA1A0SN35TQ" --v +ers=30] This variant of Data Matrix, also known as “Complex Mail Data Mark” (CMDM), was introduced by Royal Mail along with 6.5.4 Royal Mail 4-State Mailmark, and @@ -4330,7 +4350,7 @@ GS1 data, the ECI mechanism, and Structured Append are not supported. Also known as Quick Response Code this symbology was developed by Denso. -[zint -b QRCODE -d "QR Code Symbol" --mask=5] +[Figure 116: zint -b QRCODE -d "QR Code Symbol" --mask=5] Four levels of error correction are available using the --secure option (API option_1) as shown in the following table. @@ -4406,7 +4426,7 @@ symbols can encode either Latin-1 characters or Shift JIS characters. Input should be entered as a UTF-8 stream with conversion to Latin-1 or Shift JIS being carried out automatically by Zint. -[zint -b MICROQR -d "01234567"] +[Figure 117: zint -b MICROQR -d "01234567"] A preferred symbol size can be selected by using the --vers option (API option_2), as shown in the table below. Note that versions M1 and M2 have @@ -4467,7 +4487,7 @@ Latin-1 characters or Shift JIS characters, and other encodings using the ECI mechanism. As with other symbologies data should be entered as UTF-8 with conversion being handled by Zint. -[zint -b RMQR -d "0123456"] +[Figure 118: zint -b RMQR -d "0123456"] The amount of ECC codewords can be adjusted using the --secure option (API option_1), however only ECC levels M and H are valid for this type of symbol. @@ -4540,7 +4560,7 @@ A variation of QR Code used by Združenje Bank Slovenije (Bank Association of Slovenia). The size, error correction level and ECI are set by Zint and do not need to be specified. -[zint -b UPNQR -i upn_utf8.txt --quietzones] +[Figure 119: zint -b UPNQR -i upn_utf8.txt --quietzones] UPNQR is unusual in that it uses Latin-2 (ISO/IEC 8859-2 plus ASCII) formatted data. Zint will accept UTF-8 data and convert it to Latin-2, or if your data is @@ -4548,7 +4568,7 @@ already Latin-2 formatted use the --binary switch (API input_mode = DATA_MODE). The following example creates a symbol from data saved as a Latin-2 file: - zint -o upnqr.png -b UPNQR --scale=3 --binary -i upn.txt + zint -o upnqr.png -b UPNQR --binary -i upn.txt A mask may be manually specified and the --fast option used as with 6.6.3 QR Code (ISO 18004). @@ -4559,8 +4579,8 @@ Developed by UPS the MaxiCode symbology employs a grid of hexagons surrounding a bullseye finder pattern. This symbology is designed for the identification of parcels. -[zint -b MAXICODE -d "1Z00004951\GUPSN\G06X610\G159\G1234567\G1/1\G\GY\G1 MAIN S -T\GNY\GNY\R\E" --esc --primary="152382802000000" --scmvv=96] +[Figure 120: zint -b MAXICODE -d "1Z00004951\GUPSN\G06X610\G159\G1234567\G1/1\G\ +GY\G1 MAIN ST\GNY\GNY\R\E" --esc --primary="152382802000000" --scmvv=96] MaxiCode symbols can be encoded in one of five modes. In modes 2 and 3 MaxiCode symbols are composed of two parts named the primary and secondary messages. The @@ -4655,7 +4675,7 @@ multiplied by 20 instead of 2. Invented by Andrew Longacre at Welch Allyn Inc in 1995 the Aztec Code symbol is a matrix symbol with a distinctive square bullseye finder pattern. -[zint -b AZTEC -d "123456789012"] +[Figure 121: zint -b AZTEC -d "123456789012"] Zint can generate Compact Aztec Code (sometimes called Small Aztec Code) as well as ‘full-range’ Aztec Code symbols and by default will automatically select @@ -4735,7 +4755,7 @@ A truncated version of compact Aztec Code for encoding whole integers between 0 and 255, as defined in ISO/IEC 24778 Annex A. Includes Reed-Solomon error correction. It does not support Structured Append. -[zint -b AZRUNE -d "125"] +[Figure 122: zint -b AZRUNE -d "125"] 6.6.10 Code One @@ -4743,7 +4763,7 @@ A matrix symbology developed by Ted Williams in 1992 which encodes data in a way similar to Data Matrix, Code One is able to encode the Latin-1 character set or GS1 data, and also supports the ECI mechanism. -[zint -b CODEONE -d "1234567890123456789012"] +[Figure 123: zint -b CODEONE -d "1234567890123456789012"] There are two types of Code One symbol - fixed-ratio symbols which are roughly square (versions A through to H) and variable-width versions (versions S and T). @@ -4794,8 +4814,8 @@ GB 2312 being carried out automatically by Zint. Up to around 1529 alphanumeric characters or 2751 digits may be encoded. The symbology also supports the ECI mechanism. Support for GS1 data has not yet been implemented. -[zint -b GRIDMATRIX --eci=29 -d "AAT2556 电池充电器+降压转换器 200mA至2A tel:86 019 825127 -38"] +[Figure 124: zint -b GRIDMATRIX --eci=29 -d "AAT2556 电池充电器+降压转换器 200mA至2A tel:8 +6 019 82512738"] The size of the symbol and the error correction capacity can be specified. If you specify both of these values then Zint will make a ‘best-fit’ attempt to @@ -4845,7 +4865,8 @@ setting the scale of the image to a larger value than the default (e.g. approximately 10) for the dots to be plotted correctly. Approximately 33% of the resulting symbol is comprised of error correction codewords. -[zint -b DOTCODE -d "[01]00012345678905[17]201231[10]ABC123456" --gs1] +[Figure 125: zint -b DOTCODE -d "[01]00012345678905[17]201231[10]ABC123456" --gs +1] DotCode has two sets of 4 masks, designated 0-3 and 0’-3’, the second "prime" set being the same as the first with corners lit. The best mask to use is @@ -4865,7 +4886,7 @@ UTF, i.e. includes all Unicode characters, optimized for Chinese characters) an is also able to support the ECI mechanism. Support for the encoding of GS1 data has not yet been implemented. -[zint -b HANXIN -d "Hanxin Code symbol"] +[Figure 126: zint -b HANXIN -d "Hanxin Code symbol"] The size of the symbol can be specified using the --vers option (API option_2) to a value between 1 and 84 according to the following table. @@ -4936,7 +4957,7 @@ option_3 = (N + 1) << 8 where N is 0-3. To use with ZINT_FULL_MULTIBYTE set This symbology uses a grid of coloured elements to encode data. ECI and GS1 modes are supported. -[zint -b ULTRA -d "HEIMASÍÐA KENNARAHÁSKÓLA ÍSLANDS"] +[Figure 127: zint -b ULTRA -d "HEIMASÍÐA KENNARAHÁSKÓLA ÍSLANDS"] The amount of error correction can be set using the --secure option (API option_1) to a value as shown in the following table. @@ -4982,7 +5003,7 @@ not given, no ID is encoded. Used by the United States Postal Service (USPS), the FIM symbology is used to assist automated mail processing. -[zint -b FIM --compliantheight -d "C"] +[Figure 128: zint -b FIM --compliant -d "C"] There are only 5 valid symbols which can be generated using the characters A-E as shown in the table below. @@ -5005,7 +5026,7 @@ not a true barcode symbol and requires precise knowledge of the position of the mark on the page. The Flattermarken system can encode numeric data up to a maximum of 128 digits and does not include a check digit. -[zint -b FLAT -d "1304056"] +[Figure 129: zint -b FLAT -d "1304056"] 7. Legal and Version Information @@ -5269,7 +5290,7 @@ For full details, see "backend_qt/qzint.h". Annex C. Tcl Backend Binding -A Tcl binding is available in the "backend_tcl” sub-directory. To make on Unix: +A Tcl binding is available in the "backend_tcl" sub-directory. To make on Unix: cd backend_tcl autoconf @@ -5304,7 +5325,7 @@ A demonstration Tcl/Tk program which is also useful in itself is available at which will display the following window. -[Tcl/Tk demonstration program window] +[Figure 130: Tcl/Tk demonstration program window] You can select the symbology, enter the data to encode, and set options (which are the same as those given in the usage message). The raster preview of the @@ -5628,9 +5649,9 @@ OPTIONS --mirror - Use the batch data to determine the filename in batch mode (--batch). The -o - | --output option can be used to specify an output directory (any filename - will be ignored). + Use the data to determine the filename. This is particularly useful in batch + mode (--batch), but also works in standard mode. The -o | --output option + can be used to specify an output directory (any filename will be ignored). --mode=INTEGER @@ -6109,7 +6130,7 @@ the yen sign (¥), and tilde (~) to overline (‾, U+203E). $, @, [, \, ], ^, `, {, |, }, ~ (tilde). [9] Note that unless the --binary switch is used, 8-bit binary data for ECI 899 -must be given as UTF-8, e.g. a byte "\x80" must be represented as the 2 bytes +must be given as UTF-8, e.g. byte "\x80" must be represented as the 2 bytes "\xC2\x80"; similarly "\xC0" as "\xC3\x80", etc. [10] For more information on the “Unbracketed AI” format for GS1 data entry, see @@ -6123,44 +6144,49 @@ using GS1 Application Identifiers”. Note that this applies even to AIs with fixed lengths, so e.g. the data for AI 3940, which has a fixed length of 4, must have a terminating FNC1 (except when the last AI). -[12] BARCODE_MEMORY_FILE textual formats EPS and SVG will have Unix newlines +[12] The --mirror option will replace control characters (including DEL) and +slash (/) with an underscore (_). Additionally on Windows the characters !, ", +*, :, <, >, ?, \ and | will also be replaced with underscores, as they are +prohibited in filenames. + +[13] BARCODE_MEMORY_FILE textual formats EPS and SVG will have Unix newlines (LF) on both Windows and Unix, i.e. not CR+LF on Windows. -[13] The height value is ignored for Aztec (including HIBC and Aztec Rune), Code +[14] The height value is ignored for Aztec (including HIBC and Aztec Rune), Code One, Data Matrix (including HIBC), DotCode, Grid Matrix, Han Xin, MaxiCode, QR Code (including HIBC, Micro QR, rMQR and UPNQR), and Ultracode - all of which have a fixed width-to-height ratio (or, in the case of Code One, a fixed height). -[14] For Windows, outfile is assumed to be UTF-8 encoded. +[15] For Windows, outfile is assumed to be UTF-8 encoded. -[15] The BARCODE_BIND_TOP flag is set by default for DPD - see 6.1.10.7 DPD +[16] The BARCODE_BIND_TOP flag is set by default for DPD - see 6.1.10.7 DPD Code. -[16] The BARCODE_BIND flag is always set for Codablock F, Code 16K and Code 49. +[17] The BARCODE_BIND flag is always set for Codablock F, Code 16K and Code 49. Special considerations apply to ITF-14 - see 6.1.2.6 ITF-14. -[17] Codablock F, Code 16K, Code 49, EAN-13, EAN-8, EAN/UPC add-ons, ISBN, +[18] Codablock F, Code 16K, Code 49, EAN-13, EAN-8, EAN/UPC add-ons, ISBN, ITF-14, UPC-A and UPC-E have compliant quiet zones added by default. -[18] ZINT_CAP_EANUPC was previously named ZINT_CAP_EXTENDABLE, which is still +[19] ZINT_CAP_EANUPC was previously named ZINT_CAP_EXTENDABLE, which is still recognised. -[19] DotCode, Han Xin, Micro QR Code, QR Code and UPNQR have variable masks. +[20] DotCode, Han Xin, Micro QR Code, QR Code and UPNQR have variable masks. Rectangular Micro QR Code has a fixed mask (4). -[20] Except for Japanese Postal Code, whose check character is not truly +[21] Except for Japanese Postal Code, whose check character is not truly representable in the encoded data. -[21] The library libzueci, which can convert both to and from UTF-8 and ECI, is +[22] The library libzueci, which can convert both to and from UTF-8 and ECI, is available at https://sourceforge.net/projects/libzueci/. -[22] BARCODE_CODE128AB previously used the name BARCODE_CODE128B, which is still +[23] BARCODE_CODE128AB previously used the name BARCODE_CODE128B, which is still recognised. -[23] The DX number may be looked up in The (Modified) Big Film Database at +[24] The DX number may be looked up in The (Modified) Big Film Database at https://thebigfilmdatabase.merinorus.com. -[24] ASCII-compatible ECIs are ECIs 3 to 18 and 21 to 27 (see Table 9: ECI +[25] ASCII-compatible ECIs are ECIs 3 to 18 and 21 to 27 (see Table 9: ECI Codes). Note in particular that ECI 899, 8-bit binary, is not considered ASCII-compatible. diff --git a/docs/zint.1 b/docs/zint.1 index 4bbcdc6f..2b8f2b7a 100644 --- a/docs/zint.1 +++ b/docs/zint.1 @@ -325,8 +325,9 @@ Set the masking pattern to use for DotCode, Han Xin or QR Code to \f[I]\f[CI]INTEGER\f[I]\f[R], overriding the automatic selection. .TP \f[B]\f[CB]\-\-mirror\f[B]\f[R] -Use the batch data to determine the filename in batch mode -(\f[CR]\-\-batch\f[R]). +Use the data to determine the filename. +This is particularly useful in batch mode (\f[CR]\-\-batch\f[R]), but +also works in standard mode. The \f[CR]\-o\f[R] | \f[CR]\-\-output\f[R] option can be used to specify an output directory (any filename will be ignored). .TP diff --git a/docs/zint.1.pmd b/docs/zint.1.pmd index 7b65f17a..2221d5c3 100644 --- a/docs/zint.1.pmd +++ b/docs/zint.1.pmd @@ -285,8 +285,9 @@ Paintbrush (`PCX`), Portable Network Format (`PNG`), Scalable Vector Graphic (`S **`--mirror`** -: Use the batch data to determine the filename in batch mode (`--batch`). The `-o` | `--output` option can be used - to specify an output directory (any filename will be ignored). +: Use the data to determine the filename. This is particularly useful in batch mode (`--batch`), but also works in + standard mode. The `-o` | `--output` option can be used to specify an output directory (any filename will be + ignored). **`--mode=`***`INTEGER`* diff --git a/docs/zint_images.sh b/docs/zint_images.sh index 21e77f2f..0d543c44 100755 --- a/docs/zint_images.sh +++ b/docs/zint_images.sh @@ -28,8 +28,8 @@ zint -d "This Text" --fg=00FF00 --scale=$SCALE_LINEAR -o images/code128_green.sv zint -d "This Text" --fg=00FF0055 --scale=$SCALE_LINEAR -o images/code128_green_alpha.svg zint -d "This Text" --rotate=90 --scale=$SCALE_LINEAR -o images/code128_rotate90.svg zint -b DATAMATRIX --eci=17 -d "€" --scale=$SCALE_2D -o images/datamatrix_euro.svg -zint -b DATAMATRIX --eci=28 -d "\u5E38" --esc --scale=$SCALE_2D -o images/datamatrix_big5.svg -zint -b QRCODE --binary -d "\xE2\x82\xAC\xE5\xB8\xB8" --esc --scale=$SCALE_2D -o images/qrcode_binary_utf8.svg +zint -b DATAMATRIX --eci=28 --binary --esc -d "\xBD\x58" --scale=$SCALE_2D -o images/datamatrix_big5.svg +zint -b QRCODE --binary -d "€" --scale=$SCALE_2D -o images/qrcode_binary_utf8.svg zint -b CODEONE -d "123456789012345678" --dotty --vers=9 --scale=$SCALE_DOTTY -o images/codeone_s_dotty.svg zint -b AZTEC --eci=9 -d "Κείμενο" --seg1=7,"Текст" --seg2=20,"文章" --scale=$SCALE_2D -o images/aztec_segs.svg zint -b DATAMATRIX -d "2nd of 3" --structapp="2,3,5006" --scale=$SCALE_2D -o images/datamatrix_structapp.svg @@ -40,86 +40,86 @@ zint -b CODE11 -d "9212320967" --scale=$SCALE_LINEAR -o images/code11.svg zint -b C25STANDARD -d "9212320967" --scale=$SCALE_LINEAR -o images/c25standard.svg zint -b C25IATA -d "9212320967" --scale=$SCALE_LINEAR -o images/c25iata.svg zint -b C25IND -d "9212320967" --scale=$SCALE_LINEAR -o images/c25ind.svg -zint -b C25INTER --compliantheight -d "9212320967" --scale=$SCALE_LINEAR -o images/c25inter.svg +zint -b C25INTER --compliant -d "9212320967" --scale=$SCALE_LINEAR -o images/c25inter.svg zint -b C25LOGIC -d "9212320967" --scale=$SCALE_LINEAR -o images/c25logic.svg -zint -b ITF14 --compliantheight -d "9212320967145" --scale=$SCALE_LINEAR -o images/itf14.svg -zint -b ITF14 --box --compliantheight -d "9212320967145" --scale=$SCALE_LINEAR -o images/itf14_border0.svg +zint -b ITF14 --compliant -d "9212320967145" --scale=$SCALE_LINEAR -o images/itf14.svg +zint -b ITF14 --box --compliant -d "9212320967145" --scale=$SCALE_LINEAR -o images/itf14_border0.svg zint -b DPLEIT -d "9212320967145" --scale=$SCALE_LINEAR -o images/dpleit.svg zint -b DPIDENT -d "91232096712" --scale=$SCALE_LINEAR -o images/dpident.svg -zint -b UPCA --compliantheight -d "01234500005" --scale=$SCALE_UPCEAN -o images/upca.svg -zint -b UPCA --compliantheight -d "01234500005+12345" --scale=$SCALE_UPCEAN -o images/upca_5.svg -zint -b UPCA --compliantheight -d "01234500005+12345" --guardwhitespace --scale=$SCALE_UPCEAN -o images/upca_5_gws.svg -zint -b UPCE --compliantheight -d "123455" --scale=$SCALE_UPCEAN -o images/upce.svg -zint -b UPCE --compliantheight -d "123455+12" --guardwhitespace --scale=$SCALE_UPCEAN -o images/upce_2_gws.svg -zint -b EAN13 --compliantheight -d "952012345678" --scale=$SCALE_UPCEAN -o images/ean13.svg -zint -b EAN13 --compliantheight -d "952012345678+21" --scale=$SCALE_UPCEAN -o images/ean13_2.svg -zint -b EAN13 --compliantheight -d "952012345678" --guarddescent=2.5 --guardwhitespace --scale=$SCALE_UPCEAN -o images/ean13_gd_gws.svg -zint -b EAN8 --compliantheight -d "9520000" --scale=$SCALE_UPCEAN -o images/ean8.svg -zint -b EAN8 --compliantheight -d "9520000" --guardwhitespace --scale=$SCALE_UPCEAN -o images/ean8_gws.svg -zint -b ISBNX --compliantheight -d "9789295055124" --scale=$SCALE_UPCEAN -o images/isbnx.svg -zint -b ISBNX --compliantheight -d "9789295055124" --guardwhitespace --scale=$SCALE_UPCEAN -o images/isbnx_gws.svg -zint -b EAN_2ADDON --compliantheight -d "12" --scale=$SCALE_UPCEAN -o images/ean_2addon.svg -zint -b EAN_5ADDON --compliantheight -d "54321" --guardwhitespace --scale=$SCALE_UPCEAN -o images/ean_5addon_gws.svg +zint -b UPCA --compliant -d "01234500005" --scale=$SCALE_UPCEAN -o images/upca.svg +zint -b UPCA --compliant -d "01234500005+12345" --scale=$SCALE_UPCEAN -o images/upca_5.svg +zint -b UPCA --compliant -d "01234500005+12345" --guardwhitespace --scale=$SCALE_UPCEAN -o images/upca_5_gws.svg +zint -b UPCE --compliant -d "123455" --scale=$SCALE_UPCEAN -o images/upce.svg +zint -b UPCE --compliant -d "123455+12" --guardwhitespace --scale=$SCALE_UPCEAN -o images/upce_2_gws.svg +zint -b EAN13 --compliant -d "952012345678" --scale=$SCALE_UPCEAN -o images/ean13.svg +zint -b EAN13 --compliant -d "952012345678+21" --scale=$SCALE_UPCEAN -o images/ean13_2.svg +zint -b EAN13 --compliant -d "952012345678" --guarddescent=2.5 --guardwhitespace --scale=$SCALE_UPCEAN -o images/ean13_gd_gws.svg +zint -b EAN8 --compliant -d "9520000" --scale=$SCALE_UPCEAN -o images/ean8.svg +zint -b EAN8 --compliant -d "9520000" --guardwhitespace --scale=$SCALE_UPCEAN -o images/ean8_gws.svg +zint -b ISBNX --compliant -d "9789295055124" --scale=$SCALE_UPCEAN -o images/isbnx.svg +zint -b ISBNX --compliant -d "9789295055124" --guardwhitespace --scale=$SCALE_UPCEAN -o images/isbnx_gws.svg +zint -b EAN_2ADDON --compliant -d "12" --scale=$SCALE_UPCEAN -o images/ean_2addon.svg +zint -b EAN_5ADDON --compliant -d "54321" --guardwhitespace --scale=$SCALE_UPCEAN -o images/ean_5addon_gws.svg zint -b PLESSEY -d "C64" --scale=$SCALE_LINEAR -o images/plessey.svg zint -b MSI_PLESSEY -d "6502" --vers=2 --scale=$SCALE_LINEAR -o images/msi_plessey.svg -zint -b TELEPEN --compliantheight -d "Z8000" --scale=$SCALE_LINEAR -o images/telepen.svg -zint -b TELEPEN --compliantheight -d "Z\L8000" --esc --vers=1 --scale=$SCALE_LINEAR -o images/telepen_aim.svg -zint -b TELEPEN_NUM --compliantheight -d "466X33" --scale=$SCALE_LINEAR -o images/telepen_num.svg -zint -b TELEPEN_NUM --compliantheight -d "12\LAB" --esc --scale=$SCALE_LINEAR -o images/telepen_num_asc.svg -zint -b TELEPEN_NUM --compliantheight -d "12\L3" --esc --scale=$SCALE_LINEAR -o images/telepen_num_odd.svg -zint -b CODE39 --compliantheight -d "1A" --vers=1 --scale=$SCALE_LINEAR -o images/code39.svg -zint -b EXCODE39 --compliantheight -d "123.45#@fd" --scale=$SCALE_LINEAR -o images/excode39.svg -zint -b CODE93 --compliantheight -d "C93" --scale=$SCALE_LINEAR -o images/code93.svg -zint -b PZN --compliantheight -d "2758089" --scale=$SCALE_LINEAR -o images/pzn.svg -zint -b LOGMARS --compliantheight -d "12345/ABCDE" --vers=1 --scale=$SCALE_LINEAR -o images/logmars.svg -zint -b CODE32 --compliantheight -d "14352312" --scale=$SCALE_LINEAR -o images/code32.svg -zint -b HIBC_39 --compliantheight -d "14352312" --scale=$SCALE_LINEAR -o images/hibc_39.svg +zint -b TELEPEN --compliant -d "Z8000" --scale=$SCALE_LINEAR -o images/telepen.svg +zint -b TELEPEN --compliant -d "Z\L8000" --esc --vers=1 --scale=$SCALE_LINEAR -o images/telepen_aim.svg +zint -b TELEPEN_NUM --compliant -d "466X33" --scale=$SCALE_LINEAR -o images/telepen_num.svg +zint -b TELEPEN_NUM --compliant -d "12\LAB" --esc --scale=$SCALE_LINEAR -o images/telepen_num_asc.svg +zint -b TELEPEN_NUM --compliant -d "12\L3" --esc --scale=$SCALE_LINEAR -o images/telepen_num_odd.svg +zint -b CODE39 --compliant -d "1A" --vers=1 --scale=$SCALE_LINEAR -o images/code39.svg +zint -b EXCODE39 --compliant -d "123.45#@fd" --scale=$SCALE_LINEAR -o images/excode39.svg +zint -b CODE93 --compliant -d "C93" --scale=$SCALE_LINEAR -o images/code93.svg +zint -b PZN --compliant -d "2758089" --scale=$SCALE_LINEAR -o images/pzn.svg +zint -b LOGMARS --compliant -d "12345/ABCDE" --vers=1 --scale=$SCALE_LINEAR -o images/logmars.svg +zint -b CODE32 --compliant -d "14352312" --scale=$SCALE_LINEAR -o images/code32.svg +zint -b HIBC_39 --compliant -d "14352312" --scale=$SCALE_LINEAR -o images/hibc_39.svg zint -b VIN -d "2FTPX28L0XCA15511" --vers=1 --scale=$SCALE_LINEAR -o images/vin.svg -zint -b CODABAR --compliantheight -d "A37859B" --scale=$SCALE_LINEAR -o images/codabar.svg -zint -b PHARMA --compliantheight -d "130170" --scale=$SCALE_LINEAR -o images/pharma.svg +zint -b CODABAR --compliant -d "A37859B" --scale=$SCALE_LINEAR -o images/codabar.svg +zint -b PHARMA --compliant -d "130170" --scale=$SCALE_LINEAR -o images/pharma.svg zint -b CODE128 --bind -d "130170X178" --scale=$SCALE_LINEAR -o images/code128.svg zint -b CODE128AB -d "130170X178" --scale=$SCALE_LINEAR -o images/code128ab.svg -zint -b GS1_128 --compliantheight -d "[01]98898765432106[3202]012345[15]991231" --scale=$SCALE_LINEAR -o images/gs1_128.svg -zint -b EAN14 --compliantheight -d "9889876543210" --scale=$SCALE_LINEAR -o images/ean14.svg -zint -b NVE18 --compliantheight -d "37612345000001003" --scale=$SCALE_LINEAR -o images/nve18.svg +zint -b GS1_128 --compliant -d "[01]98898765432106[3202]012345[15]991231" --scale=$SCALE_LINEAR -o images/gs1_128.svg +zint -b EAN14 --compliant -d "9889876543210" --scale=$SCALE_LINEAR -o images/ean14.svg +zint -b NVE18 --compliant -d "37612345000001003" --scale=$SCALE_LINEAR -o images/nve18.svg zint -b HIBC_128 -d "A123BJC5D6E71" --scale=$SCALE_LINEAR -o images/hibc_128.svg -zint -b DPD --compliantheight -d "000393206219912345678101040" --scale=$SCALE_LINEAR -o images/dpd.svg -zint -b UPU_S10 --compliantheight -d "EE876543216CA" --scale=$SCALE_LINEAR -o images/upu_s10.svg -zint -b DBAR_OMN --compliantheight -d "0950110153001" --scale=$SCALE_LINEAR -o images/dbar_omn.svg +zint -b DPD --compliant -d "000393206219912345678101040" --scale=$SCALE_LINEAR -o images/dpd.svg +zint -b UPU_S10 --compliant -d "EE876543216CA" --scale=$SCALE_LINEAR -o images/upu_s10.svg +zint -b DBAR_OMN --compliant -d "0950110153001" --scale=$SCALE_LINEAR -o images/dbar_omn.svg zint -b DBAR_OMN -d "0950110153001" --height=13 --scale=$SCALE_LINEAR -o images/dbar_truncated.svg -zint -b DBAR_LTD --compliantheight -d "0950110153001" --scale=$SCALE_LINEAR -o images/dbar_ltd.svg -zint -b DBAR_EXP --compliantheight -d "[01]98898765432106[3202]012345[15]991231" --scale=$SCALE_LINEAR -o images/dbar_exp.svg +zint -b DBAR_LTD --compliant -d "0950110153001" --scale=$SCALE_LINEAR -o images/dbar_ltd.svg +zint -b DBAR_EXP --compliant -d "[01]98898765432106[3202]012345[15]991231" --scale=$SCALE_LINEAR -o images/dbar_exp.svg zint -b KOREAPOST -d "923457" --scale=$SCALE_LINEAR -o images/koreapost.svg -zint -b CHANNEL -d "453678" --compliantheight --scale=$SCALE_LINEAR -o images/channel.svg -zint -b BC412 -d "AQ45670" --compliantheight --scale=$SCALE_LINEAR -o images/bc412.svg +zint -b CHANNEL -d "453678" --compliant --scale=$SCALE_LINEAR -o images/channel.svg +zint -b BC412 -d "AQ45670" --compliant --scale=$SCALE_LINEAR -o images/bc412.svg zint -d "This" -d "That" --scale=$SCALE_LINEAR -o images/code128_stacked.svg zint --notext --bind --separator=2 -d "This" -d "That" --scale=$SCALE_LINEAR -o images/code128_stacked_sep2.svg zint -b CODABLOCKF -d "CODABLOCK F Symbology" --rows=3 --scale=$SCALE_LINEAR -o images/codablockf.svg -zint -b CODE16K --compliantheight -d "ab0123456789" --scale=$SCALE_LINEAR -o images/code16k.svg +zint -b CODE16K --compliant -d "ab0123456789" --scale=$SCALE_LINEAR -o images/code16k.svg zint -b PDF417 -d "PDF417" --scale=$SCALE_LINEAR -o images/pdf417.svg zint -b PDF417COMP -d "PDF417" --scale=$SCALE_LINEAR -o images/pdf417comp.svg zint -b MICROPDF417 -d "12345678" --scale=$SCALE_LINEAR -o images/micropdf417.svg -zint -b DBAR_STK --compliantheight -d "9889876543210" --scale=$SCALE_LINEAR -o images/dbar_stk.svg -zint -b DBAR_OMNSTK --compliantheight -d "9889876543210" --scale=$SCALE_LINEAR -o images/dbar_omnstk.svg -zint -b DBAR_EXPSTK --compliantheight -d "[01]98898765432106[3202]012345[15]991231" --scale=$SCALE_LINEAR -o images/dbar_expstk.svg -zint -b CODE49 --compliantheight -d "MULTIPLE ROWS IN CODE 49" --scale=$SCALE_LINEAR -o images/code49.svg -zint -b EAN13_CC --compliantheight -d "[99]1234-abcd" --mode=1 --primary=331234567890 --scale=$SCALE_UPCEAN -o images/ean13_cc_a.svg -zint -b EAN13_CC --compliantheight -d "[99]1234-abcd" --mode=2 --primary=331234567890 --scale=$SCALE_UPCEAN -o images/ean13_cc_b.svg -zint -b GS1_128_CC --compliantheight -d "[99]1234-abcd" --mode=3 --primary="[01]03312345678903" --scale=$SCALE_UPCEAN -o images/gs1_128_cc_c.svg -zint -b PHARMA_TWO --compliantheight -d "29876543" --scale=$SCALE_TRACK -o images/pharma_two.svg -zint -b POSTNET --compliantheight -d "12345678901" --scale=$SCALE_TRACK -o images/postnet.svg -zint -b PLANET --compliantheight -d "4012345235636" --scale=$SCALE_TRACK -o images/planet.svg -zint -b CEPNET --compliantheight -d "12345678" --scale=$SCALE_TRACK -o images/cepnet.svg -zint -b DXFILMEDGE --compliantheight -d "112-1/10A" --scale=$SCALE_TRACK -o images/dxfilmedge.svg -zint -b AUSPOST --compliantheight -d "96184209" --scale=$SCALE_TRACK -o images/auspost.svg -zint -b AUSROUTE --compliantheight -d "34567890" --scale=$SCALE_TRACK -o images/ausroute.svg -zint -b AUSREPLY --compliantheight -d "12345678" --scale=$SCALE_TRACK -o images/ausreply.svg -zint -b AUSREDIRECT --compliantheight -d "98765432" --scale=$SCALE_TRACK -o images/ausredirect.svg -zint -b KIX --compliantheight -d "2500GG30250" --scale=$SCALE_TRACK -o images/kix.svg -zint -b RM4SCC --compliantheight -d "W1J0TR01" --scale=$SCALE_TRACK -o images/rm4scc.svg -zint -b MAILMARK_4S --compliantheight -d "21B2254800659JW5O9QA6Y" --scale=$SCALE_TRACK -o images/mailmark_4s.svg -zint -b USPS_IMAIL --compliantheight -d "01234567094987654321-01234" --scale=$SCALE_TRACK -o images/usps_imail.svg -zint -b JAPANPOST --compliantheight -d "15400233-16-4-205" --scale=$SCALE_TRACK -o images/japanpost.svg +zint -b DBAR_STK --compliant -d "9889876543210" --scale=$SCALE_LINEAR -o images/dbar_stk.svg +zint -b DBAR_OMNSTK --compliant -d "9889876543210" --scale=$SCALE_LINEAR -o images/dbar_omnstk.svg +zint -b DBAR_EXPSTK --compliant -d "[01]98898765432106[3202]012345[15]991231" --scale=$SCALE_LINEAR -o images/dbar_expstk.svg +zint -b CODE49 --compliant -d "MULTIPLE ROWS IN CODE 49" --scale=$SCALE_LINEAR -o images/code49.svg +zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=1 --primary=331234567890 --scale=$SCALE_UPCEAN -o images/ean13_cc_a.svg +zint -b EAN13_CC --compliant -d "[99]1234-abcd" --mode=2 --primary=331234567890 --scale=$SCALE_UPCEAN -o images/ean13_cc_b.svg +zint -b GS1_128_CC --compliant -d "[99]1234-abcd" --mode=3 --primary="[01]03312345678903" --scale=$SCALE_UPCEAN -o images/gs1_128_cc_c.svg +zint -b PHARMA_TWO --compliant -d "29876543" --scale=$SCALE_TRACK -o images/pharma_two.svg +zint -b POSTNET --compliant -d "12345678901" --scale=$SCALE_TRACK -o images/postnet.svg +zint -b PLANET --compliant -d "4012345235636" --scale=$SCALE_TRACK -o images/planet.svg +zint -b CEPNET --compliant -d "12345678" --scale=$SCALE_TRACK -o images/cepnet.svg +zint -b DXFILMEDGE --compliant -d "112-1/10A" --scale=$SCALE_TRACK -o images/dxfilmedge.svg +zint -b AUSPOST --compliant -d "96184209" --scale=$SCALE_TRACK -o images/auspost.svg +zint -b AUSROUTE --compliant -d "34567890" --scale=$SCALE_TRACK -o images/ausroute.svg +zint -b AUSREPLY --compliant -d "12345678" --scale=$SCALE_TRACK -o images/ausreply.svg +zint -b AUSREDIRECT --compliant -d "98765432" --scale=$SCALE_TRACK -o images/ausredirect.svg +zint -b KIX --compliant -d "2500GG30250" --scale=$SCALE_TRACK -o images/kix.svg +zint -b RM4SCC --compliant -d "W1J0TR01" --scale=$SCALE_TRACK -o images/rm4scc.svg +zint -b MAILMARK_4S --compliant -d "21B2254800659JW5O9QA6Y" --scale=$SCALE_TRACK -o images/mailmark_4s.svg +zint -b USPS_IMAIL --compliant -d "01234567094987654321-01234" --scale=$SCALE_TRACK -o images/usps_imail.svg +zint -b JAPANPOST --compliant -d "15400233-16-4-205" --scale=$SCALE_TRACK -o images/japanpost.svg zint -b HIBC_DM -d "/ACMRN123456/V200912190833" --fast --square --scale=$SCALE_2D_BIGGER -o images/hibc_dm.svg zint -b MAILMARK_2D -d "JGB 01Z999999900000001EC1A1AA1A0SN35TQ" --vers=30 --scale=$SCALE_2D_BIGGER -o images/mailmark_2d.svg zint -b QRCODE -d "QR Code Symbol" --mask=5 --scale=$SCALE_2D_BIGGER -o images/qrcode.svg @@ -134,6 +134,6 @@ zint -b GRIDMATRIX --eci=29 -d "AAT2556 电池充电器+降压转换器 200mA至 zint -b DOTCODE -d "[01]00012345678905[17]201231[10]ABC123456" --gs1 --scale=$SCALE_2D -o images/dotcode.svg zint -b HANXIN -d "Hanxin Code symbol" --scale=$SCALE_2D -o images/hanxin.svg zint -b ULTRA -d "HEIMASÍÐA KENNARAHÁSKÓLA ÍSLANDS" --scale=$SCALE_ULTRA -o images/ultra.svg -zint -b FIM --compliantheight -d "C" --scale=$SCALE_TRACK -o images/fim.svg +zint -b FIM --compliant -d "C" --scale=$SCALE_TRACK -o images/fim.svg zint -b FLAT -d "1304056" --scale=$SCALE_LINEAR -o images/flat.svg zint -b DAFT -d "AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF" --height=8.494 --vers=256 --scale=$SCALE_TRACK -o images/daft_rm4scc.svg diff --git a/frontend/main.c b/frontend/main.c index e96bfe25..a51b048a 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -67,8 +67,10 @@ typedef char static_assert_int_at_least_32bits[sizeof(int) * CHAR_BIT < 32 ? -1 #define z_isdigit(ch) ((ch) <= '9' && (ch) >= '0') #define z_isupper(ch) ((ch) >= 'A' && (ch) <= 'Z') #define z_islower(ch) ((ch) >= 'a' && (ch) <= 'z') +#define z_iscntrl(ch) (!((ch) & ~0x1F) || (ch) == 127) #define ZUCP(p) ((unsigned char *) (p)) +#define ZCUCP(p) ((const unsigned char *) (p)) #define ZCCP(p) ((const char *) (p)) /* End of copy from "backend/common.h" */ @@ -216,7 +218,7 @@ if (have_gs1syntaxengine) { " -i, --input=FILE Read input data from FILE\n" " --init Create Reader Initialisation (Programming) symbol\n" " --mask=INTEGER Set masking pattern to use (QR/Han Xin/DotCode)\n" - " --mirror Use batch data to determine filename\n", stdout); + " --mirror Use data to determine filename\n", stdout); fputs( " --mode=INTEGER Set encoding mode (MaxiCode/Composite)\n", stdout); printf(" --nobackground Remove background (EMF/EPS/GIF%s/SVG/TIF only)\n", no_png_type); fputs( " --noquietzones Disable default quiet zones\n" @@ -373,23 +375,20 @@ static int validate_float(const char source[], const int allow_neg, float *const const char *e; for (e = dot + strlen(dot) - 1; e > dot && *e == '0'; e--); /* Ignore trailing zeroes */ fract_len = (int) (e + 1 - dot); - if (fract_len) { - if (fract_len > 7) { - cpy_str(errbuf, ERRBUF_SIZE, "fractional part must be 7 digits maximum"); - return 0; - } - if (!validate_int(dot, fract_len, &val2)) { - cpy_str(errbuf, ERRBUF_SIZE, "fractional part must be digits only"); - return 0; - } - if (val2 && int_len + fract_len > 7) { - cpy_str(errbuf, ERRBUF_SIZE, "7 significant digits maximum"); - return 0; - } - *p_val = val + val2 * fract_muls[fract_len - 1]; - } else { - *p_val = (float) val; + assert(fract_len); + if (fract_len > 7) { + cpy_str(errbuf, ERRBUF_SIZE, "fractional part must be 7 digits maximum"); + return 0; } + if (!validate_int(dot, fract_len, &val2)) { + cpy_str(errbuf, ERRBUF_SIZE, "fractional part must be digits only"); + return 0; + } + if (val2 && int_len + fract_len > 7) { + cpy_str(errbuf, ERRBUF_SIZE, "7 significant digits maximum"); + return 0; + } + *p_val = val + val2 * fract_muls[fract_len - 1]; } else { *p_val = (float) val; } @@ -417,6 +416,13 @@ static int is_composite(const int symbology) { || symbology == BARCODE_EAN8_CC || symbology == BARCODE_EAN13_CC; } +/* Returns 1 if `symbol` can process EXTRA_ESCAPE_MODE (copied from "library.c") */ +static int supports_extra_escape_mode(const struct zint_symbol *const symbol) { + return symbol->symbology == BARCODE_CODE128 + || ((symbol->symbology == BARCODE_AZTEC || symbol->symbology == BARCODE_DATAMATRIX) + && (symbol->input_mode & 0x07) != GS1_MODE); +} + /* Return symbology id if `barcode_name` a barcode name */ #ifdef ZINT_TEST static int get_barcode_name(const char *const barcode_name, const int test) { @@ -451,7 +457,7 @@ static int get_barcode_name(const char *const barcode_name) { { BARCODE_C25INTER, "c25inter" }, { BARCODE_C25INTER, "c25interleaved" }, /* Synonym */ { BARCODE_C25LOGIC, "c25logic" }, - { BARCODE_C25STANDARD, "c25matrix" }, + { BARCODE_C25STANDARD, "c25matrix" }, /* Synonym */ { BARCODE_C25STANDARD, "c25standard" }, { BARCODE_CEPNET, "cepnet" }, { BARCODE_CHANNEL, "channel" }, @@ -656,6 +662,7 @@ static int get_barcode_name(const char *const barcode_name) { int i, j, length; #ifdef ZINT_TEST +/* LCOV_EXCL_START */ if (test) { /* Ensure array sorted */ for (i = 0; i < e; i++) { @@ -667,6 +674,7 @@ static int get_barcode_name(const char *const barcode_name) { } return 1; } +/* LCOV_EXCL_STOP */ #endif /* Ignore case and any "BARCODE" prefix */ @@ -982,6 +990,104 @@ static int validate_seg(const char *const arg, const int N, struct zint_seg segs return 1; } +/* Use directory if any from `symbol->outfile`, returning length in `p_mirror_start_o` */ +static int mirror_start(const struct zint_symbol *const symbol, const int output_given, int *p_mirror_start_o) { + int warn_number = 0; + + *p_mirror_start_o = 0; + + /* Use directory if any from outfile */ + if (output_given && symbol->outfile[0]) { +#ifndef _WIN32 + const char *dir = strrchr(symbol->outfile, '/'); +#else + const char *dir = strrchr(symbol->outfile, '\\'); + if (!dir) { + dir = strrchr(symbol->outfile, '/'); + } +#endif + if (dir) { + *p_mirror_start_o = (int) (dir + 1 - symbol->outfile); + if (*p_mirror_start_o > 221) { /* Insist on leaving at least ~30 chars for filename */ + fprintf(stderr, "Warning 188: Directory for mirrored output too long (greater than 220)," + " **IGNORED**\n"); + fflush(stderr); + warn_number = ZINT_WARN_INVALID_OPTION; /* TODO: maybe new warning ZINT_WARN_INVALID_INPUT? */ + *p_mirror_start_o = 0; + } + } + } + + return warn_number; +} + +/* Name the output file from the data being processed */ +static void mirror_outfile(struct zint_symbol *const symbol, const unsigned char source[], const int length, + const char *const filetype, char *output_file, int o) { + const int extra_escape_mode = (symbol->input_mode & EXTRA_ESCAPE_MODE) && supports_extra_escape_mode(symbol); + const int escape_mode = (symbol->input_mode & ESCAPE_MODE) || extra_escape_mode; + int i = 0; + + if (output_file == NULL) { + output_file = symbol->outfile; + } + + do { + if (z_iscntrl(source[i])) { + output_file[o] = '_'; + } else { + switch (source[i]) { +#ifndef _WIN32 + case '/': + output_file[o] = '_'; + break; + case '\\': + output_file[o] = escape_mode ? '_' : '\\'; + break; +#else /* These are all forbidden on Windows */ + case '!': + case '"': + case '*': + case '/': + case ':': + case '<': + case '>': + case '?': + case '\\': + case '|': + output_file[o] = '_'; + break; +#endif + default: + output_file[o] = source[i]; + break; + } + } + + /* Skip escape characters */ + if (source[i] == '\\' && escape_mode) { + i++; + if (source[i] == 'x') { + i += 2; + } else if (source[i] == 'd' || source[i] == 'o') { + i += 3; + } else if (source[i] == 'u') { + i += 4; + } else if (source[i] == 'U') { + i += 6; + } else if (extra_escape_mode && source[i] == '^') { + i++; + } + } + i++; + o++; + } while (i < length && o < 251); + + /* Add file extension */ + output_file[o] = '.'; + ncpy_str(output_file + o + 1, ARRAY_SIZE(symbol->outfile) - o - 1, filetype, 3); +} + #ifdef _WIN32 static FILE *win_fopen(const char *const filename, const char *const mode); /* Forward ref */ #endif @@ -992,7 +1098,9 @@ static int batch_process(struct zint_symbol *const symbol, const char *const fil FILE *file; unsigned char buffer[ZINT_MAX_DATA_LEN] = {0}; /* Maximum HanXin input */ unsigned char character = 0; - int buf_posn = 0, error_number = 0, warn_number = 0, line_count = 1; + int buf_posn = 0; + int error_number = 0, warn_number = 0; + int line_count = 1; char output_file[ARRAY_SIZE(symbol->outfile)]; char format_string[ARRAY_SIZE(symbol->outfile)]; int i, mirror_start_o = 0; @@ -1000,27 +1108,9 @@ static int batch_process(struct zint_symbol *const symbol, const char *const fil if (mirror_mode) { /* Use directory if any from outfile */ - if (output_given && symbol->outfile[0]) { -#ifndef _WIN32 - const char *dir = strrchr(symbol->outfile, '/'); -#else - const char *dir = strrchr(symbol->outfile, '\\'); - if (!dir) { - dir = strrchr(symbol->outfile, '/'); - } -#endif - if (dir) { - mirror_start_o = (int) (dir + 1 - symbol->outfile); - if (mirror_start_o > 221) { /* Insist on leaving at least ~30 chars for filename */ - fprintf(stderr, "Warning 188: directory for mirrored batch output too long (greater than 220)," - " **IGNORED**\n"); - fflush(stderr); - warn_number = ZINT_WARN_INVALID_OPTION; /* TODO: maybe new warning ZINT_WARN_INVALID_INPUT? */ - mirror_start_o = 0; - } else { - memcpy(output_file, symbol->outfile, mirror_start_o); - } - } + warn_number = mirror_start(symbol, output_given, &mirror_start_o); + if (mirror_start_o) { + memcpy(output_file, symbol->outfile, mirror_start_o); } } else { if (symbol->outfile[0] == '\0' || !output_given) { @@ -1121,52 +1211,7 @@ static int batch_process(struct zint_symbol *const symbol, const char *const fil } } else { /* Name the output file from the data being processed */ - int o = mirror_start_o; - i = 0; - do { - if (buffer[i] < 0x20) { - output_file[o] = '_'; - } else { - switch (buffer[i]) { - case '!': - case '"': - case '*': - case '/': - case ':': - case '<': - case '>': - case '?': - case '\\': - case '|': - case 0x7f: /* DEL */ - output_file[o] = '_'; - break; - default: - output_file[o] = buffer[i]; - break; - } - } - - /* Skip escape characters */ - if (buffer[i] == '\\' && (symbol->input_mode & ESCAPE_MODE)) { - i++; - if (buffer[i] == 'x') { - i += 2; - } else if (buffer[i] == 'd' || buffer[i] == 'o') { - i += 3; - } else if (buffer[i] == 'u') { - i += 4; - } else if (buffer[i] == 'U') { - i += 6; - } - } - i++; - o++; - } while (i < buf_posn && o < 251); - - /* Add file extension */ - output_file[o] = '.'; - ncpy_str(output_file + o + 1, ARRAY_SIZE(output_file) - o - 1, filetype, 3); + mirror_outfile(symbol, buffer, buf_posn, filetype, output_file, mirror_start_o); } cpy_str(symbol->outfile, ARRAY_SIZE(symbol->outfile), output_file); @@ -1188,6 +1233,9 @@ static int batch_process(struct zint_symbol *const symbol, const char *const fil if (buf_posn >= ARRAY_SIZE(buffer)) { fprintf(stderr, "On line %d: Error 103: Input data too long\n", line_count); fflush(stderr); + if (error_number == 0) { + error_number = ZINT_ERROR_TOO_LONG; + } do { if ((intChar = fgetc(file)) == EOF) { break; @@ -1211,10 +1259,7 @@ static int batch_process(struct zint_symbol *const symbol, const char *const fil warn_number = ZINT_WARN_INVALID_OPTION; /* TODO: maybe new warning e.g. ZINT_WARN_INVALID_INPUT? */ } } - if (error_number == 0) { - error_number = warn_number; - } - return error_number; + return error_number ? error_number : warn_number; } /* Stuff to convert args on Windows command line to UTF-8 */ @@ -1525,7 +1570,6 @@ int main(int argc, char **argv) { int val; int i; int ret; - const char *outfile_extension; int data_arg_num = 0; int seg_count = 0; float x_dim_mm = 0.0f, dpmm = 0.0f; @@ -1685,7 +1729,7 @@ int main(int argc, char **argv) { my_symbol->option_3 = ZINT_AZTEC_FULL | (my_symbol->option_3 & ~0xFF); break; case OPT_BATCH: - if (data_cnt == 0) { + if (data_cnt == 0 && seg_count == 0) { /* Switch to batch processing mode */ batch_mode = 1; } else { @@ -1714,10 +1758,10 @@ int main(int argc, char **argv) { fprintf(stderr, "Error 107: Invalid border width value (digits only)\n"); return do_exit(ZINT_ERROR_INVALID_OPTION); } - if (val <= 1000) { /* `val` >= 0 always */ + if (val <= 100) { /* `val` >= 0 always */ my_symbol->border_width = val; } else { - fprintf(stderr, "Warning 108: Border width '%d' out of range (0 to 1000), **IGNORED**\n", val); + fprintf(stderr, "Warning 108: Border width '%d' out of range (0 to 100), **IGNORED**\n", val); fflush(stderr); warn_number = ZINT_WARN_INVALID_OPTION; } @@ -1774,7 +1818,7 @@ int main(int argc, char **argv) { } /* C40 overwrites Base 256 */ if ((my_symbol->option_3 & DM_B256_C40_START_MASK) == DM_B256_START) { - fprintf(stderr, "Warning 161: previous '--dmb256' overwritten by '--dmc40'\n"); + fprintf(stderr, "Warning 161: Previous '--dmb256' overwritten by '--dmc40'\n"); fflush(stderr); warn_number = ZINT_WARN_INVALID_OPTION; } @@ -2115,7 +2159,7 @@ int main(int argc, char **argv) { case OPT_SQUARE: /* Square overwrites DMRE */ if ((my_symbol->option_3 & DM_SQUARE_DMRE_MASK) == DM_DMRE) { - fprintf(stderr, "Warning 157: previous '--dmre' overwritten by '--square'\n"); + fprintf(stderr, "Warning 157: Previous '--dmre' overwritten by '--square'\n"); fflush(stderr); warn_number = ZINT_WARN_INVALID_OPTION; } @@ -2129,12 +2173,14 @@ int main(int argc, char **argv) { } break; #ifdef ZINT_TEST +/* LCOV_EXCL_START */ case OPT_TEST: if (!test()) { return do_exit(ZINT_ERROR_ENCODING_PROBLEM); } help = 1; /* Mark as help to avoid "No data" warning */ break; +/* LCOV_EXCL_STOP */ #endif case OPT_TEXTGAP: if (!validate_float(optarg, 1 /*allow_neg*/, &float_opt, errbuf)) { @@ -2171,11 +2217,11 @@ int main(int argc, char **argv) { fprintf(stderr, "Error 153: Invalid vertical whitespace value '%s' (digits only)\n", optarg); return do_exit(ZINT_ERROR_INVALID_OPTION); } - if (val <= 1000) { /* `val` >= 0 always */ + if (val <= 100) { /* `val` >= 0 always */ my_symbol->whitespace_height = val; } else { fprintf(stderr, - "Warning 154: Vertical whitespace value '%d' out of range (0 to 1000), **IGNORED**\n", + "Warning 154: Vertical whitespace value '%d' out of range (0 to 100), **IGNORED**\n", val); fflush(stderr); warn_number = ZINT_WARN_INVALID_OPTION; @@ -2219,11 +2265,11 @@ int main(int argc, char **argv) { fprintf(stderr, "Error 120: Invalid horizontal whitespace value '%s' (digits only)\n", optarg); return do_exit(ZINT_ERROR_INVALID_OPTION); } - if (val <= 1000) { /* `val` >= 0 always */ + if (val <= 100) { /* `val` >= 0 always */ my_symbol->whitespace_width = val; } else { fprintf(stderr, - "Warning 121: Horizontal whitespace value '%d' out of range (0 to 1000), **IGNORED**\n", + "Warning 121: Horizontal whitespace value '%d' out of range (0 to 100), **IGNORED**\n", val); fflush(stderr); warn_number = ZINT_WARN_INVALID_OPTION; @@ -2289,14 +2335,14 @@ int main(int argc, char **argv) { return do_exit(ZINT_ERROR_ENCODING_PROBLEM); } if (long_options[i].has_arg) { - fprintf(stderr, "Error 109: option '%s' requires an argument\n", arg); + fprintf(stderr, "Error 109: Option '%s' requires an argument\n", arg); } else { const char *const eqs = strchr(arg, '='); const int optlen = eqs ? (int) (eqs - arg) : (int) strlen(arg); - fprintf(stderr, "Error 126: option '%.*s' does not take an argument\n", optlen, arg); + fprintf(stderr, "Error 126: Option '%.*s' does not take an argument\n", optlen, arg); } } else { - fprintf(stderr, "Error 101: unknown option '%s'\n", arg); + fprintf(stderr, "Error 101: Unknown option '%s'\n", arg); } } return do_exit(ZINT_ERROR_INVALID_OPTION); @@ -2310,9 +2356,9 @@ int main(int argc, char **argv) { } if (optind != argc) { if (optind + 1 == argc) { - fprintf(stderr, "Warning 191: extra argument '%s' **IGNORED**\n", argv[optind]); + fprintf(stderr, "Warning 191: Extra argument '%s' **IGNORED**\n", argv[optind]); } else { - fprintf(stderr, "Warning 192: extra arguments beginning with '%s' **IGNORED**\n", argv[optind]); + fprintf(stderr, "Warning 192: Extra arguments beginning with '%s' **IGNORED**\n", argv[optind]); } fflush(stderr); warn_number = ZINT_WARN_INVALID_OPTION; @@ -2320,7 +2366,7 @@ int main(int argc, char **argv) { if (data_arg_num) { const int symbology = my_symbol->symbology; - const unsigned int cap = ZBarcode_Cap(symbology, ZINT_CAP_EXTENDABLE | ZINT_CAP_FULL_MULTIBYTE + const unsigned int cap = ZBarcode_Cap(symbology, ZINT_CAP_EANUPC | ZINT_CAP_FULL_MULTIBYTE | ZINT_CAP_MASK | ZINT_CAP_BINDABLE); if (fullmultibyte && (cap & ZINT_CAP_FULL_MULTIBYTE)) { my_symbol->option_3 = ZINT_FULL_MULTIBYTE; @@ -2331,7 +2377,7 @@ int main(int argc, char **argv) { if (separator && (cap & ZINT_CAP_BINDABLE)) { my_symbol->option_3 = separator; } - if (addon_gap && (cap & ZINT_CAP_EXTENDABLE)) { + if (addon_gap && (cap & ZINT_CAP_EANUPC)) { my_symbol->option_2 = addon_gap; } if (rows) { @@ -2356,6 +2402,14 @@ int main(int argc, char **argv) { fflush(stderr); warn_number = ZINT_WARN_INVALID_OPTION; } + if (filetype[0] == '\0') { + const char *outfile_extension = get_extension(my_symbol->outfile); + if (outfile_extension && supported_filetype(outfile_extension, no_png, NULL /*png_refused*/)) { + cpy_str(filetype, ARRAY_SIZE(filetype), outfile_extension); + } else { + cpy_str(filetype, ARRAY_SIZE(filetype), no_png ? "gif" : "png"); + } + } if (batch_mode) { /* Take each line of text as a separate data set */ if (data_arg_num > 1) { @@ -2365,34 +2419,16 @@ int main(int argc, char **argv) { fflush(stderr); warn_number = ZINT_WARN_INVALID_OPTION; } - if (seg_count) { - fprintf(stderr, "Warning 169: Segment arguments **IGNORED**\n"); - fflush(stderr); - warn_number = ZINT_WARN_INVALID_OPTION; - } - if (filetype[0] == '\0') { - outfile_extension = get_extension(my_symbol->outfile); - if (outfile_extension && supported_filetype(outfile_extension, no_png, NULL /*png_refused*/)) { - cpy_str(filetype, ARRAY_SIZE(filetype), outfile_extension); - } else { - cpy_str(filetype, ARRAY_SIZE(filetype), no_png ? "gif" : "png"); - } - } - if (dpmm) { /* Allow `x_dim_mm` to be zero */ + assert(seg_count == 0); /* Previous checks ensure this */ + if (dpmm) { + /* Allow `x_dim_mm` to be zero */ if (x_dim_mm == 0.0f) { x_dim_mm = ZBarcode_Default_Xdim(symbology); } float_opt = ZBarcode_Scale_From_XdimDp(symbology, x_dim_mm, dpmm, filetype); - if (float_opt > 0.0f) { - my_symbol->scale = float_opt; - my_symbol->dpmm = dpmm; - } else { - fprintf(stderr, - "Warning 187: Invalid scalexdimdp X-dim '%g', resolution '%g' combo, **IGNORED**\n", - x_dim_mm, dpmm); - fflush(stderr); - warn_number = ZINT_WARN_INVALID_OPTION; - } + assert(float_opt > 0.0f); /* Can't fail due to previous checks */ + my_symbol->scale = float_opt; + my_symbol->dpmm = dpmm; } if (((symbology != BARCODE_MAXICODE && my_symbol->scale < 0.5f) || my_symbol->scale < 0.2f) && is_raster(filetype, no_png)) { @@ -2424,24 +2460,30 @@ int main(int argc, char **argv) { } } } + if (mirror_mode) { + if (arg_opts[0].opt != 'd') { + fprintf(stderr, "Warning 163: '--mirror' given but no data argument, **IGNORED**\n"); + fflush(stderr); + warn_number = ZINT_WARN_INVALID_OPTION; + } else { + int mirror_start_o; + warn_number = mirror_start(my_symbol, output_given, &mirror_start_o); + mirror_outfile(my_symbol, ZUCP(arg_opts[0].arg), (int) strlen(arg_opts[0].arg), filetype, NULL, + mirror_start_o); + } + } if (filetype[0] != '\0') { set_extension(my_symbol->outfile, filetype); } - if (dpmm) { /* Allow `x_dim_mm` to be zero */ + if (dpmm) { + /* Allow `x_dim_mm` to be zero */ if (x_dim_mm == 0.0f) { x_dim_mm = ZBarcode_Default_Xdim(symbology); } float_opt = ZBarcode_Scale_From_XdimDp(symbology, x_dim_mm, dpmm, get_extension(my_symbol->outfile)); - if (float_opt > 0.0f) { - my_symbol->scale = float_opt; - my_symbol->dpmm = dpmm; - } else { - fprintf(stderr, - "Warning 190: Invalid scalexdimdp X-dim '%g', resolution '%g' combo **IGNORED**\n", - x_dim_mm, dpmm); - fflush(stderr); - warn_number = ZINT_WARN_INVALID_OPTION; - } + assert(float_opt > 0.0f); /* Can't fail due to previous checks */ + my_symbol->scale = float_opt; + my_symbol->dpmm = dpmm; } if (((symbology != BARCODE_MAXICODE && my_symbol->scale < 0.5f) || my_symbol->scale < 0.2f) && is_raster(get_extension(my_symbol->outfile), no_png)) { @@ -2500,6 +2542,7 @@ int main(int argc, char **argv) { } #ifdef ZINT_TEST +/* LCOV_EXCL_START */ static int test_cpy_str(void) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ @@ -2624,11 +2667,12 @@ static int test_validate_float(void) { /* 19*/ { "1234.5670", 0, 1234.567f, "", 1 }, /* 20*/ { "1234.56700", 0, 1234.567f, "", 1 }, /* 21*/ { "0.", 0, 0.0f, "", 1 }, - /* 22*/ { "-0", 1, 0.0f, "", 1 }, - /* 23*/ { ".0", 0, 0.0f, "", 1 }, - /* 24*/ { ".", 0, 0.0f, "", 1 }, - /* 25*/ { "+.", 0, 0.0f, "", 1 }, - /* 26*/ { "-.", 1, 0.0f, "", 1 }, + /* 22*/ { "0.0", 0, 0.0f, "", 1 }, + /* 23*/ { "-0", 1, 0.0f, "", 1 }, + /* 24*/ { ".0", 0, 0.0f, "", 1 }, + /* 25*/ { ".", 0, 0.0f, "", 1 }, + /* 26*/ { "+.", 0, 0.0f, "", 1 }, + /* 27*/ { "-.", 1, 0.0f, "", 1 }, }; int i; for (i = 0; i < ARRAY_SIZE(data); i++) { @@ -2929,18 +2973,20 @@ static int test_validate_structapp(void) { /* 1*/ { ",", { -1, -1, "" }, 0, "Structured Append index too short" }, /* 2*/ { "1234567890,", { -1, -1, "" }, 0, "Structured Append index too long" }, /* 3*/ { "123456789,", { -1, -1, "" }, 0, "Structured Append count too short" }, - /* 4*/ { "1,1234567890", { -1, -1, "" }, 0, "Structured Append count too long" }, - /* 5*/ { "1,123456789,", { -1, -1, "" }, 0, "Structured Append ID too short" }, - /* 6*/ { "123456789,123456789,123456789012345678901234567890123", { -1, -1, "" }, 0, "Structured Append ID too long" }, - /* 7*/ { "123456789,123456789,12345678901234567890123456789012", { 123456789, 123456789, {'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2'} }, 1, "" }, - /* 8*/ { "2,3,5006", { 2, 3, "5006" }, 1, "" }, - /* 9*/ { "2,3,,", { 2, 3, "," }, 1, "" }, - /* 10*/ { "1.2,1", { -1, -1, "" }, 0, "Invalid Structured Append index (digits only)" }, - /* 11*/ { "12,1.0", { 12, -1, "" }, 0, "Invalid Structured Append count (digits only)" }, - /* 12*/ { "12,1", { 12, 1, "" }, 0, "Invalid Structured Append count '1', must be greater than or equal to 2" }, - /* 13*/ { "12,11", { 12, 11, "" }, 0, "Structured Append index '12' out of range (1 to count '11')" }, - /* 14*/ { "12,12", { 12, 12, "" }, 1, "" }, - /* 15*/ { "0,2", { 0, 2, "" }, 0, "Structured Append index '0' out of range (1 to count '2')" }, + /* 4*/ { "123456789,,", { -1, -1, "" }, 0, "Structured Append count too short" }, + /* 5*/ { "1,1234567890", { -1, -1, "" }, 0, "Structured Append count too long" }, + /* 6*/ { "1,1234567890,", { -1, -1, "" }, 0, "Structured Append count too long" }, + /* 7*/ { "1,123456789,", { -1, -1, "" }, 0, "Structured Append ID too short" }, + /* 8*/ { "123456789,123456789,123456789012345678901234567890123", { -1, -1, "" }, 0, "Structured Append ID too long" }, + /* 9*/ { "123456789,123456789,12345678901234567890123456789012", { 123456789, 123456789, {'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2'} }, 1, "" }, + /* 10*/ { "2,3,5006", { 2, 3, "5006" }, 1, "" }, + /* 11*/ { "2,3,,", { 2, 3, "," }, 1, "" }, + /* 12*/ { "1.2,1", { -1, -1, "" }, 0, "Invalid Structured Append index (digits only)" }, + /* 13*/ { "12,1.0", { 12, -1, "" }, 0, "Invalid Structured Append count (digits only)" }, + /* 14*/ { "12,1", { 12, 1, "" }, 0, "Invalid Structured Append count '1', must be greater than or equal to 2" }, + /* 15*/ { "12,11", { 12, 11, "" }, 0, "Structured Append index '12' out of range (1 to count '11')" }, + /* 16*/ { "12,12", { 12, 12, "" }, 1, "" }, + /* 17*/ { "0,2", { 0, 2, "" }, 0, "Structured Append index '0' out of range (1 to count '2')" }, }; int i; for (i = 0; i < ARRAY_SIZE(data); i++) { @@ -3034,6 +3080,172 @@ static int test_validate_seg(void) { return 1; } +#define TEST_MIRRORED_LONG "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" /* 250 chars */ + +#define TEST_MIRRORED_DIR_LONG "testdir_9012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/" /* 220 chars */ +#define TEST_MIRRORED_DIR_TOO_LONG "testdir_901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901/" /* 222 chars */ + +static int test_mirror_start(void) { + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct { const char *outfile; int output_given; int ret; int mirror_start_o; } data[] = { + /* 0*/ { NULL, 0, 0, 0 }, + /* 1*/ { "", 0, 0, 0 }, + /* 2*/ { "123.svg", 1, 0, 0 }, + /* 3*/ { "ABCDF/123.svg", 1, 0, 6 }, + /* 4*/ { "ABCDF/", 1, 0, 6 }, + /* 5*/ { TEST_MIRRORED_DIR_LONG, 1, 0, 220 }, + /* 6*/ { TEST_MIRRORED_DIR_TOO_LONG, 1, ZINT_WARN_INVALID_OPTION, 0 }, + }; + int i, ret; + struct zint_symbol s_symbol = {0}; + struct zint_symbol *symbol = &s_symbol; + + for (i = 0; i < ARRAY_SIZE(data); i++) { + int mirror_start_o = -1; + + ZBarcode_Reset(symbol); + + if (data[i].outfile) { + cpy_str(symbol->outfile, ARRAY_SIZE(symbol->outfile), data[i].outfile); + } + + if (data[i].ret) { + printf("++++ Following warning expected, ignore: "); + fflush(stdout); + } + ret = mirror_start(symbol, data[i].output_given, &mirror_start_o); + if (ret != data[i].ret) { + fprintf(stderr, "%d: ret %d != %d\n", i, ret, data[i].ret); + assert(0); + return 0; + } + if (mirror_start_o != data[i].mirror_start_o) { + fprintf(stderr, "%d: mirror_start_o %d != %d\n", i, mirror_start_o, data[i].mirror_start_o); + assert(0); + return 0; + } + } + return 1; +} + +#ifndef _WIN32 +#define TEST_MIRROR_BSLASH "\\" +#define TEST_MIRROR_EXCLAIM "!" +#define TEST_MIRROR_DQUOTE "\"" +#define TEST_MIRROR_ASTERISK "*" +#define TEST_MIRROR_COLON ":" +#define TEST_MIRROR_LANGLE "<" +#define TEST_MIRROR_RANGLE ">" +#define TEST_MIRROR_QUESTION "?" +#define TEST_MIRROR_PIPE "|" +#else +#define TEST_MIRROR_BSLASH "_" +#define TEST_MIRROR_EXCLAIM "_" +#define TEST_MIRROR_DQUOTE "_" +#define TEST_MIRROR_ASTERISK "_" +#define TEST_MIRROR_COLON "_" +#define TEST_MIRROR_LANGLE "_" +#define TEST_MIRROR_RANGLE "_" +#define TEST_MIRROR_QUESTION "_" +#define TEST_MIRROR_PIPE "_" +#endif + +static int test_mirror_outfile(void) { + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct { + int symbology; int input_mode; + const char *source; const char *outfile; const char *filetype; int use_symbol_outfile; int o; + const char *expected_outfile; + } data[] = { + /* 0*/ { -1, -1, "123", NULL, "png", 1, 0, "123.png" }, + /* 1*/ { -1, -1, "123", NULL, "png", 0, 0, "123.png" }, + /* 2*/ { -1, -1, "\001", NULL, "png", 0, 0, "_.png" }, + /* 3*/ { -1, -1, "1!!2", NULL, "png", 0, 0, "1" TEST_MIRROR_EXCLAIM TEST_MIRROR_EXCLAIM "2.png" }, + /* 4*/ { -1, -1, "1!2\"3*4/5:6<7>8?9\\0|1\1772\0173", NULL, "png", 0, 0, "1" TEST_MIRROR_EXCLAIM "2" TEST_MIRROR_DQUOTE "3" TEST_MIRROR_ASTERISK "4_5" TEST_MIRROR_COLON "6" TEST_MIRROR_LANGLE "7" TEST_MIRROR_RANGLE "8" TEST_MIRROR_QUESTION "9" TEST_MIRROR_BSLASH "0" TEST_MIRROR_PIPE "1_2_3.png" }, + /* 5*/ { -1, -1, "ABC\\d123\\o123\\x12\\u1234\\U123456\\0\\E\\a\\N\\U1234", NULL, "png", 1, 0, "ABC" TEST_MIRROR_BSLASH "d123" TEST_MIRROR_BSLASH "o123" TEST_MIRROR_BSLASH "x12" TEST_MIRROR_BSLASH "u1234" TEST_MIRROR_BSLASH "U123456" TEST_MIRROR_BSLASH "0" TEST_MIRROR_BSLASH "E" TEST_MIRROR_BSLASH "a" TEST_MIRROR_BSLASH "N" TEST_MIRROR_BSLASH "U1234.png" }, + /* 6*/ { -1, ESCAPE_MODE, "ABC\\d123\\o123\\x12\\u1234\\U123456\\0\\E\\a\\N\\U1234", NULL, "png", 1, 0, "ABC__________.png" }, /* 10 escape sequences, 10 underscores */ + /* 7*/ { -1, -1, "1!2\\d1233*4\\^15", NULL, "png", 0, 0, "1" TEST_MIRROR_EXCLAIM "2" TEST_MIRROR_BSLASH "d1233" TEST_MIRROR_ASTERISK "4" TEST_MIRROR_BSLASH "^15.png" }, + /* 8*/ { -1, ESCAPE_MODE, "1!2\\d1233*4\\^15", NULL, "png", 0, 0, "1" TEST_MIRROR_EXCLAIM "2_3" TEST_MIRROR_ASTERISK "4_15.png" }, + /* 9*/ { -1, ESCAPE_MODE | EXTRA_ESCAPE_MODE, "1!2\\d1233*4\\^15", NULL, "png", 0, 0, "1" TEST_MIRROR_EXCLAIM "2_3" TEST_MIRROR_ASTERISK "4_5.png" }, + /* 10*/ { -1, EXTRA_ESCAPE_MODE, "1!2\\d1233*4\\^15", NULL, "png", 0, 0, "1" TEST_MIRROR_EXCLAIM "2_3" TEST_MIRROR_ASTERISK "4_5.png" }, + /* 11*/ { BARCODE_DATAMATRIX, GS1_MODE | EXTRA_ESCAPE_MODE, "1!2\\d1233*4\\^15", NULL, "png", 0, 0, "1" TEST_MIRROR_EXCLAIM "2" TEST_MIRROR_BSLASH "d1233" TEST_MIRROR_ASTERISK "4" TEST_MIRROR_BSLASH "^15.png" }, + /* 12*/ { -1, -1, "ABC123", "test_dir/out.png", "png", 1, 0, "test_dir/ABC123.png" }, + /* 13*/ { -1, -1, "ABC123", "test_dir/out.png", "png", 0, 9, "test_dir/ABC123.png" }, + /* 14*/ { -1, -1, TEST_MIRRORED_LONG "123456", NULL, "pcx", 1, 0, TEST_MIRRORED_LONG "1.pcx" }, + /* 15*/ { -1, -1, TEST_MIRRORED_LONG "123456", NULL, "pcx", 0, 0, TEST_MIRRORED_LONG "1.pcx" }, + /* 16*/ { -1, -1, TEST_MIRRORED_LONG, TEST_MIRRORED_DIR_LONG, "eps", 1, 0, TEST_MIRRORED_DIR_LONG "test_67890123456789012345678901.eps" }, + /* 17*/ { -1, -1, TEST_MIRRORED_LONG, TEST_MIRRORED_DIR_LONG, "eps", 0, 220, TEST_MIRRORED_DIR_LONG "test_67890123456789012345678901.eps" }, + }; + int i; + struct zint_symbol s_symbol = {0}; + struct zint_symbol *symbol = &s_symbol; + + for (i = 0; i < ARRAY_SIZE(data); i++) { + const int length = (int) strlen(data[i].source); + char output_file[256] = {0}; + + ZBarcode_Reset(symbol); + + if (data[i].symbology != -1) { + symbol->symbology = data[i].symbology; + } + if (data[i].input_mode != -1) { + symbol->input_mode = data[i].input_mode; + } + + if (data[i].use_symbol_outfile) { + int mirror_start_o; + if (data[i].outfile) { + cpy_str(symbol->outfile, ARRAY_SIZE(symbol->outfile), data[i].outfile); + } + mirror_start(symbol, 1 /*output_given*/, &mirror_start_o); + mirror_outfile(symbol, ZCUCP(data[i].source), length, data[i].filetype, NULL, mirror_start_o); + if (strcmp(symbol->outfile, data[i].expected_outfile) != 0) { + fprintf(stderr, "%d: symbol->outfile \"%s\" != \"%s\"\n", + i, symbol->outfile, data[i].expected_outfile); + assert(0); + return 0; + } + } else { + if (data[i].outfile) { + cpy_str(output_file, ARRAY_SIZE(output_file), data[i].outfile); + } + mirror_outfile(symbol, ZCUCP(data[i].source), length, data[i].filetype, output_file, data[i].o); + if (strcmp(output_file, data[i].expected_outfile) != 0) { + fprintf(stderr, "%d: output_file \"%s\" != \"%s\"\n", i, output_file, data[i].expected_outfile); + assert(0); + return 0; + } + } + } + return 1; +} + +static int test_batch_process(void) { + int ret; + struct zint_symbol s_symbol = {0}; + struct zint_symbol *symbol = &s_symbol; + + const char filename[] = "test_nosuch.file"; + const char filetype[] = "gif"; + int mirror_mode = 0; + int output_given = 0; + int rotate_angle = 0; + + printf("++++ Following error expected, ignore: "); + fflush(stdout); + + ret = batch_process(symbol, filename, mirror_mode, filetype, output_given, rotate_angle); + + if (ret != ZINT_ERROR_INVALID_DATA) { + fprintf(stderr, "batch_process \"%s\", ret %d != \n", filename, ret); + assert(0); + return 0; + } + + return 1; +} + #ifdef _WIN32 static int test_win_CommandLineToArgvW(void) { @@ -3163,6 +3375,9 @@ static int test(void) { ret &= test_validate_scalexdimdp(); ret &= test_validate_structapp(); ret &= test_validate_seg(); + ret &= test_mirror_start(); + ret &= test_mirror_outfile(); + ret &= test_batch_process(); #ifdef _WIN32 ret &= test_win_CommandLineToArgvW(); ret &= test_utf8_to_wide(); @@ -3170,6 +3385,7 @@ static int test(void) { return ret; } +/* LCOV_EXCL_STOP */ #endif /* ZINT_TEST */ /* vim: set ts=4 sw=4 et : */ diff --git a/frontend/tests/test_args.c b/frontend/tests/test_args.c index 299ee30f..5926e805 100644 --- a/frontend/tests/test_args.c +++ b/frontend/tests/test_args.c @@ -191,7 +191,8 @@ static int arg_input(char *cmd, const char *filename, const char *input) { } cnt = (int) fwrite(input, 1, strlen(input), fp); if (cnt != (int) strlen(input)) { - fprintf(stderr, "arg_input: failed to write %d bytes, cnt %d written (%s)\n", (int) strlen(input), cnt, filename); + fprintf(stderr, "arg_input: failed to write %d bytes, cnt %d written (%s)\n", + (int) strlen(input), cnt, filename); fclose(fp); return 0; } @@ -328,43 +329,48 @@ static void test_dump_args(const testCtx *const p_ctx) { /* 13*/ { BARCODE_CODABLOCKF, "ABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "D0 97 BA 86 51 88 B1 11 AC 46 D8 C7 58\nD0 97 BB 12 46 88 C5 1A 3C 55 CC C7 58" }, /* 14*/ { BARCODE_CODABLOCKF, "ABCDEF", NULL, NULL, NULL, -1, -1, 0, 10, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "D0 97 BA 86 51 88 B1 11 AC 44 68 BC 98 EB\nD0 97 BB 12 46 2B BD 7B A3 47 8A 8D 18 EB" }, /* 15*/ { BARCODE_CODABLOCKF, "ABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, 3, -1, 0, -1, "D0 97 BA 58 51 88 B1 11 AC 46 36 C7 58\nD0 97 BB 12 46 88 C5 77 AF 74 62 C7 58\nD0 97 BA CE 5D EB DD 1A 3C 56 88 C7 58" }, - /* 16*/ { BARCODE_CODE11, NULL, NULL, "123", NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "B2 D6 96 CA B5 6D 64" }, - /* 17*/ { BARCODE_CODE11, NULL, NULL, "123", NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, 1, "B2 D6 96 CA B5 64" }, - /* 18*/ { BARCODE_CODE11, "123", NULL, "456", NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, 2, "B2 D6 96 CA B2\nB2 B6 DA 9A B2" }, - /* 19*/ { BARCODE_CODE11, "123", "456", "789", "012", -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, 2, "B2 D6 96 CA B2\nB2 B6 DA 9A B2\nB2 A6 D2 D5 64\nB2 AD AD 2D 64" }, - /* 20*/ { BARCODE_PDF417, "123", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, 0, 0, -1, "FF 54 7A BC 3A 9C 1D 5C 0F E8 A4\nFF 54 7E AE 3C 11 5F AB 8F E8 A4\nFF 54 6A F8 29 9F 1D 5F 8F E8 A4\nFF 54 57 9E 37 BA 1A F7 CF E8 A4\nFF 54 75 CC 36 F0 5D 73 0F E8 A4" }, - /* 21*/ { BARCODE_DATAMATRIX, "ABC", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA 8\nB3 4\n8F 0\nB2 C\nA6 0\nBA C\nD6 0\nEB 4\nE2 8\nFF C" }, - /* 22*/ { BARCODE_DATAMATRIX, "ABC", NULL, NULL, NULL, -1, READER_INIT, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A\nAC 7\n8A 4\nA0 3\nC2 2\nB5 1\n82 2\nBA 7\n8C C\nA0 5\n86 A\nFF F" }, - /* 23*/ { BARCODE_DATAMATRIX, "ABCDEFGH", NULL, NULL, NULL, FAST_MODE, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nA6 8C\nB2 F0\n98 B4\nB9 A8\nB8 CC\nF0 78\nA0 3C\n99 70\n85 1C\nDA B0\nE5 94\nA7 50\nFF FC" }, - /* 24*/ { BARCODE_DATAMATRIX, "ABCDEFGH", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\n80 04\n82 60\nC5 24\n98 A8\nA3 9C\nCB B8\nAF DC\n86 58\nF6 44\nAC 18\n90 54\nCF 30\nFF FC" }, - /* 25*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJK", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA AA AA AA\n80 09 F9 BD\n82 4A E2 58\nC5 CD C9 A5\nD8 5C A5 FC\nE0 35 88 69\nCC FC B3 E6\nFF FF FF FF" }, - /* 26*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJK", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 1, -1, "AA AA\n80 25\n82 24\nC5 5D\n98 90\nA4 C7\nC8 A6\nB9 E9\n8E 02\nDE 91\nCD 6C\nA0 BB\n85 80\n98 2D\nE4 CA\nFF FF" }, - /* 27*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA AA A8\nBA 5A 44\n8B 4D 28\nBF 77 64\n97 85 50\nBA D8 AC\nCD ED B8\nD4 B5 2C\nD1 A8 00\n81 FB 2C\nE4 75 78\n96 E8 2C\nF3 75 78\nEE 1D 04\nCA BA 98\nB1 8F B4\nA0 4F 00\nE4 A7 74\nF1 D3 90\nEF E1 BC\n91 10 38\nFF FF FC" }, - /* 28*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 1, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA AA AA AA AA AA AA AA\nBA 03 BA 7D E5 31 B0 0D\n8B 6A 93 B6 E0 0A B8 3C\nBF 1D EA A7 EB ED A1 FB\n96 66 86 B6 C9 AE 92 40\nBF 65 E7 95 BC B7 FA E3\nCC 7C 90 CC D1 24 AB 5A\nFF FF FF FF FF FF FF FF" }, - /* 29*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 1, -1, 0, -1, -1, NULL, -1, -1, 1, -1, "Warning 157: previous '--dmre' overwritten by '--square'\nAA AA A8\nBA 5A 44\n8B 4D 28\nBF 77 64\n97 85 50\nBA D8 AC\nCD ED B8\nD4 B5 2C\nD1 A8 00\n81 FB 2C\nE4 75 78\n96 E8 2C\nF3 75 78\nEE 1D 04\nCA BA 98\nB1 8F B4\nA0 4F 00\nE4 A7 74\nF1 D3 90\nEF E1 BC\n91 10 38\nFF FF FC" }, - /* 30*/ { BARCODE_DATAMATRIX, "[91]12[92]34", NULL, NULL, NULL, GS1_MODE, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nFA 9C\nBC 00\nD7 84\nED E0\nA4 E4\nA7 40\n9D 3C\nBF 50\nFA 24\nB1 68\nE5 04\n92 70\nFF FC" }, - /* 31*/ { BARCODE_DATAMATRIX, "[91]12[92]34", NULL, NULL, NULL, GS1_MODE, GS1_GS_SEPARATOR, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nF9 DC\nBF 20\nD6 C4\nED 10\nA0 0C\nA7 C0\n96 5C\nBA 70\nBB A4\nE2 18\nDD 14\n9C 40\nFF FC" }, - /* 32*/ { BARCODE_DATAMATRIX, "[9\\x31]12[92]34", NULL, NULL, NULL, GS1_MODE | ESCAPE_MODE, GS1_GS_SEPARATOR, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nF9 DC\nBF 20\nD6 C4\nED 10\nA0 0C\nA7 C0\n96 5C\nBA 70\nBB A4\nE2 18\nDD 14\n9C 40\nFF FC" }, - /* 33*/ { BARCODE_DATAMATRIX, "(9\\x31)12(92)34", NULL, NULL, NULL, GS1_MODE | ESCAPE_MODE | GS1PARENS_MODE, GS1_GS_SEPARATOR, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nF9 DC\nBF 20\nD6 C4\nED 10\nA0 0C\nA7 C0\n96 5C\nBA 70\nBB A4\nE2 18\nDD 14\n9C 40\nFF FC" }, - /* 34*/ { BARCODE_DATAMATRIX, "abc", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA 8\nB3 C\nC6 0\nBA C\nBD 0\nB4 C\nDC 0\nEB C\nD1 8\nFF C" }, - /* 35*/ { BARCODE_DATAMATRIX, "abc", NULL, NULL, NULL, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A\n8B F\nD4 C\nC2 7\n9E C\nCF 3\n8E 8\nBB F\n86 2\n95 D\nCB A\nFF F" }, - /* 36*/ { BARCODE_DATAMATRIX, "abc", NULL, NULL, NULL, -1, -1, 0, -1, -1, 1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A\n8C F\n9E 4\nC5 7\nA9 6\n9F F\n97 0\nFA 9\nAA C\nDD D\nD2 2\nFF F" }, - /* 37*/ { BARCODE_DATAMATRIX, "abc", NULL, NULL, NULL, -1, -1, 0, -1, 0, 1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "Warning 161: previous '--dmb256' overwritten by '--dmc40'\nAA A\n8C F\n9E 4\nC5 7\nA9 6\n9F F\n97 0\nFA 9\nAA C\nDD D\nD2 2\nFF F" }, - /* 38*/ { BARCODE_DATAMATRIX, "A\\^1BC\\^^1DEF", NULL, NULL, NULL, EXTRA_ESCAPE_MODE, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA AA AA AA\nE0 B9 88 59\nD0 08 A3 14\n8D 9D DD DB\n8E 3E E5 E8\nDF 3B A5 A1\nB6 20 A6 02\nFF FF FF FF" }, - /* 39*/ { BARCODE_EANX_CC, "[91]12", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, "12345678+12", -1, -1, 0, -1, "DB BC D3 9C 44 E9 D2 2C 19 E7 A2 D8 A0 00 00 00\nDB 31 1C 9C C7 29 92 47 D9 E9 40 C8 A0 00 00 00\nDA 3B EB 10 AF 09 9A 18 9D 7D 82 E8 A0 00 00 00\n10 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00\n20 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00\n10 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00\n14 68 D1 A6 49 BD 55 C9 D4 22 48 B9 40 59 94 98" }, - /* 40*/ { BARCODE_EANX_CC, "[91]12", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, 2, "12345678+12", -1, -1, 0, -1, "D3 A3 E9 DB F5 C9 DB 43 D9 CB 98 D2 20 00 00 00\nD3 25 0F 11 E4 49 D3 51 F1 AC FC D6 20 00 00 00\nD1 33 48 19 39 E9 93 18 49 D8 98 D7 20 00 00 00\nD1 A6 FC DA 1C 49 9B C5 05 E2 84 D7 A0 00 00 00\n10 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00\n20 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00\n10 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00\n14 68 D1 A6 49 BD 55 C9 D4 22 48 B9 40 59 94 98" }, - /* 41*/ { BARCODE_MAXICODE, "abc", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, "1234567", -1, -1, 0, -1, "C0 55 55 5C\nC0 00 00 08\nE7 AA AA A0\n55 55 55 58\n00 00 00 0C\nAA AA AA A8\n55 55 55 50\n00 00 00 08\nAA AA AA A4\n55 B1 35 50\n00 90 08 0C\nAA C0 52 A0\n54 40 05 58\n01 00 08 00\nAA C0 0A A0\n55 00 01 58\n02 80 08 08\nAB 80 1E A8\n54 00 05 54\n03 80 0C 00\nA8 00 02 AC\n55 40 25 50\n00 60 40 0C\nAA 60 66 A0\n55 55 53 B0\n00 00 07 A0\nAA AA AE 0C\nA3 CE E2 C8\nB3 F4 AB 20\n47 0F 3C 48\nD0 6C C5 D8\nE4 CD BF 18\n81 5F 38 58" }, - /* 42*/ { BARCODE_QRCODE, "点", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, 1, 0, -1, "Warning 760: Converted to Shift JIS but no ECI specified\nFE 2B F8\n82 AA 08\nBA B2 E8\nBA 0A E8\nBA FA E8\n82 E2 08\nFE AB F8\n00 80 00\nD3 3B B0\n60 95 68\n7A B3 A0\n1D 0F 98\nAA D7 30\n00 E6 A8\nFE DA D0\n82 42 20\nBA 0E 38\nBA C7 18\nBA 17 68\n82 B9 40\nFE C5 28" }, - /* 43*/ { BARCODE_QRCODE, "点", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, 26, 0, -1, -1, NULL, -1, 1, 0, -1, "FE 5B F8\n82 72 08\nBA DA E8\nBA 52 E8\nBA 2A E8\n82 0A 08\nFE AB F8\n00 D8 00\nEF F6 20\nB5 C2 28\n36 28 88\nFD 42 10\n62 2A C8\n00 95 70\nFE B7 38\n82 FD D8\nBA 97 00\nBA 43 60\nBA C8 C8\n82 C3 68\nFE EA F8" }, - /* 44*/ { BARCODE_QRCODE, "\223\137", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, 1, 0, -1, "FE 2B F8\n82 0A 08\nBA A2 E8\nBA 0A E8\nBA 5A E8\n82 72 08\nFE AB F8\n00 A0 00\nEF AE 20\n75 B5 20\n82 F7 58\nF4 9D C8\n5E 17 28\n00 C2 20\nFE 88 80\n82 82 38\nBA EA A8\nBA 55 50\nBA D7 68\n82 BD D0\nFE B7 78" }, - /* 45*/ { BARCODE_QRCODE, "\223\137", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 1, -1, -1, NULL, -1, 1, 0, -1, "FE 2B F8\n82 AA 08\nBA B2 E8\nBA 0A E8\nBA FA E8\n82 E2 08\nFE AB F8\n00 80 00\nD3 3B B0\n60 95 68\n7A B3 A0\n1D 0F 98\nAA D7 30\n00 E6 A8\nFE DA D0\n82 42 20\nBA 0E 38\nBA C7 18\nBA 17 68\n82 B9 40\nFE C5 28" }, - /* 46*/ { BARCODE_QRCODE, "\\x93\\x5F", NULL, NULL, NULL, DATA_MODE | ESCAPE_MODE, -1, 0, -1, -1, -1, 0, -1, 1, -1, -1, NULL, -1, 1, 0, -1, "FE 2B F8\n82 AA 08\nBA B2 E8\nBA 0A E8\nBA FA E8\n82 E2 08\nFE AB F8\n00 80 00\nD3 3B B0\n60 95 68\n7A B3 A0\n1D 0F 98\nAA D7 30\n00 E6 A8\nFE DA D0\n82 42 20\nBA 0E 38\nBA C7 18\nBA 17 68\n82 B9 40\nFE C5 28" }, - /* 47*/ { BARCODE_QRCODE, "点", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, 2, -1, NULL, -1, 1, 0, -1, "Warning 760: Converted to Shift JIS but no ECI specified\nFE 4B F8\n82 92 08\nBA 42 E8\nBA 92 E8\nBA 3A E8\n82 EA 08\nFE AB F8\n00 38 00\nFB CD 50\nA5 89 18\n0B 74 B8\nFC 81 A0\n92 34 B8\n00 DE 48\nFE AB 10\n82 5E 50\nBA C9 20\nBA C9 20\nBA F4 E0\n82 81 A0\nFE B4 E8" }, - /* 48*/ { BARCODE_HANXIN, "é", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 1, -1, -1, NULL, -1, -1, 0, -1, "FE 8A FE\n80 28 02\nBE E8 FA\nA0 94 0A\nAE 3E EA\nAE D2 EA\nAE 74 EA\n00 AA 00\n15 B4 80\n0B 48 74\nA2 4A A4\nB5 56 2C\nA8 5A A8\n9F 18 50\n02 07 50\n00 A6 00\nFE 20 EA\n02 C2 EA\nFA C4 EA\n0A 42 0A\nEA 52 FA\nEA 24 02\nEA AA FE" }, - /* 49*/ { BARCODE_HANXIN, "é", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 1, 3, -1, NULL, -1, -1, 0, -1, "FE 16 FE\n80 E2 02\nBE C2 FA\nA0 A0 0A\nAE F6 EA\nAE 98 EA\nAE BA EA\n00 E0 00\n15 83 80\n44 7E AE\n92 9C 78\n25 BF 08\n47 4B 8C\n0D F9 74\n03 E7 50\n00 3A 00\nFE C2 EA\n02 22 EA\nFA DA EA\n0A 22 0A\nEA B2 FA\nEA 9A 02\nEA E8 FE" }, - /* 50*/ { BARCODE_HANXIN, "é", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 1, 4, -1, NULL, -1, -1, 0, -1, "FE 8A FE\n80 28 02\nBE E8 FA\nA0 94 0A\nAE 3E EA\nAE D2 EA\nAE 74 EA\n00 AA 00\n15 B4 80\n0B 48 74\nA2 4A A4\nB5 56 2C\nA8 5A A8\n9F 18 50\n02 07 50\n00 A6 00\nFE 20 EA\n02 C2 EA\nFA C4 EA\n0A 42 0A\nEA 52 FA\nEA 24 02\nEA AA FE" }, - /* 51*/ { BARCODE_TELEPEN, "ABC\020123", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, -1, -1, -1, NULL, -1, -1, 0, 1, "AB A8 BB B8 E3 B8 AE EA EE BA EA BA E2 22 BA B8 EA 2A" }, - /* 52*/ { BARCODE_TELEPEN_NUM, "123\020ABC", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, -1, -1, -1, NULL, -1, -1, 0, 1, "AA E8 EA BA E2 22 EE BA BB B8 E3 B8 AE EA BA B8 E8 AA" }, + /* 16*/ { BARCODE_PDF417, "ABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, 3, -1, 0, -1, "FF 54 75 70 3D 4F 1E AF 0A 73 86 82 C3 A9 C1 FD 14 8\nFF 54 7A 84 39 76 1F 6A 0F D2 E7 26 0B EA C1 FD 14 8\nFF 54 6A 7C 20 C5 D0 CD E8 76 E6 1D 72 A1 E1 FD 14 8" }, + /* 17*/ { BARCODE_CODE16K, "ABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, 3, -1, 0, -1, "E5 73 6B 9D D3 BB 94 EE 34\nCD 72 EE 74 BD 97 B2 F6 64\nD9 2F 65 EC BD BC B4 8E 4C" }, + /* 18*/ { BARCODE_CODE49, "ABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, 3, -1, 0, -1, "BF 6C A7 B0 A1 10 B2 C1 BC\nB3 CB AB BF 33 CB AE 41 BC\nB3 CB BA 0B AA 38 34 7B BC" }, + /* 19*/ { BARCODE_CODE11, NULL, NULL, "123", NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "B2 D6 96 CA B5 6D 64" }, + /* 20*/ { BARCODE_CODE11, NULL, NULL, "123", NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "B2 D6 96 CA B5 6D 64" }, + /* 21*/ { BARCODE_CODE11, NULL, NULL, "123", NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, 1, "B2 D6 96 CA B5 64" }, + /* 22*/ { BARCODE_CODE11, "123", NULL, "456", NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, 2, "B2 D6 96 CA B2\nB2 B6 DA 9A B2" }, + /* 23*/ { BARCODE_CODE11, "123", "456", "789", "012", -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, 2, "B2 D6 96 CA B2\nB2 B6 DA 9A B2\nB2 A6 D2 D5 64\nB2 AD AD 2D 64" }, + /* 24*/ { BARCODE_PDF417, "123", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, 0, 0, -1, "FF 54 7A BC 3A 9C 1D 5C 0F E8 A4\nFF 54 7E AE 3C 11 5F AB 8F E8 A4\nFF 54 6A F8 29 9F 1D 5F 8F E8 A4\nFF 54 57 9E 37 BA 1A F7 CF E8 A4\nFF 54 75 CC 36 F0 5D 73 0F E8 A4" }, + /* 25*/ { BARCODE_DATAMATRIX, "ABC", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA 8\nB3 4\n8F 0\nB2 C\nA6 0\nBA C\nD6 0\nEB 4\nE2 8\nFF C" }, + /* 26*/ { BARCODE_DATAMATRIX, "ABC", NULL, NULL, NULL, -1, READER_INIT, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A\nAC 7\n8A 4\nA0 3\nC2 2\nB5 1\n82 2\nBA 7\n8C C\nA0 5\n86 A\nFF F" }, + /* 27*/ { BARCODE_DATAMATRIX, "ABCDEFGH", NULL, NULL, NULL, FAST_MODE, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nA6 8C\nB2 F0\n98 B4\nB9 A8\nB8 CC\nF0 78\nA0 3C\n99 70\n85 1C\nDA B0\nE5 94\nA7 50\nFF FC" }, + /* 28*/ { BARCODE_DATAMATRIX, "ABCDEFGH", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\n80 04\n82 60\nC5 24\n98 A8\nA3 9C\nCB B8\nAF DC\n86 58\nF6 44\nAC 18\n90 54\nCF 30\nFF FC" }, + /* 29*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJK", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA AA AA AA\n80 09 F9 BD\n82 4A E2 58\nC5 CD C9 A5\nD8 5C A5 FC\nE0 35 88 69\nCC FC B3 E6\nFF FF FF FF" }, + /* 30*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJK", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 1, -1, "AA AA\n80 25\n82 24\nC5 5D\n98 90\nA4 C7\nC8 A6\nB9 E9\n8E 02\nDE 91\nCD 6C\nA0 BB\n85 80\n98 2D\nE4 CA\nFF FF" }, + /* 31*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA AA A8\nBA 5A 44\n8B 4D 28\nBF 77 64\n97 85 50\nBA D8 AC\nCD ED B8\nD4 B5 2C\nD1 A8 00\n81 FB 2C\nE4 75 78\n96 E8 2C\nF3 75 78\nEE 1D 04\nCA BA 98\nB1 8F B4\nA0 4F 00\nE4 A7 74\nF1 D3 90\nEF E1 BC\n91 10 38\nFF FF FC" }, + /* 32*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 1, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA AA AA AA AA AA AA AA\nBA 03 BA 7D E5 31 B0 0D\n8B 6A 93 B6 E0 0A B8 3C\nBF 1D EA A7 EB ED A1 FB\n96 66 86 B6 C9 AE 92 40\nBF 65 E7 95 BC B7 FA E3\nCC 7C 90 CC D1 24 AB 5A\nFF FF FF FF FF FF FF FF" }, + /* 33*/ { BARCODE_DATAMATRIX, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 1, -1, 0, -1, -1, NULL, -1, -1, 1, -1, "Warning 157: Previous '--dmre' overwritten by '--square'\nAA AA A8\nBA 5A 44\n8B 4D 28\nBF 77 64\n97 85 50\nBA D8 AC\nCD ED B8\nD4 B5 2C\nD1 A8 00\n81 FB 2C\nE4 75 78\n96 E8 2C\nF3 75 78\nEE 1D 04\nCA BA 98\nB1 8F B4\nA0 4F 00\nE4 A7 74\nF1 D3 90\nEF E1 BC\n91 10 38\nFF FF FC" }, + /* 34*/ { BARCODE_DATAMATRIX, "[91]12[92]34", NULL, NULL, NULL, GS1_MODE, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nFA 9C\nBC 00\nD7 84\nED E0\nA4 E4\nA7 40\n9D 3C\nBF 50\nFA 24\nB1 68\nE5 04\n92 70\nFF FC" }, + /* 35*/ { BARCODE_DATAMATRIX, "[91]12[92]34", NULL, NULL, NULL, GS1_MODE, GS1_GS_SEPARATOR, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nF9 DC\nBF 20\nD6 C4\nED 10\nA0 0C\nA7 C0\n96 5C\nBA 70\nBB A4\nE2 18\nDD 14\n9C 40\nFF FC" }, + /* 36*/ { BARCODE_DATAMATRIX, "[9\\x31]12[92]34", NULL, NULL, NULL, GS1_MODE | ESCAPE_MODE, GS1_GS_SEPARATOR, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nF9 DC\nBF 20\nD6 C4\nED 10\nA0 0C\nA7 C0\n96 5C\nBA 70\nBB A4\nE2 18\nDD 14\n9C 40\nFF FC" }, + /* 37*/ { BARCODE_DATAMATRIX, "(9\\x31)12(92)34", NULL, NULL, NULL, GS1_MODE | ESCAPE_MODE | GS1PARENS_MODE, GS1_GS_SEPARATOR, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A8\nF9 DC\nBF 20\nD6 C4\nED 10\nA0 0C\nA7 C0\n96 5C\nBA 70\nBB A4\nE2 18\nDD 14\n9C 40\nFF FC" }, + /* 38*/ { BARCODE_DATAMATRIX, "abc", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA 8\nB3 C\nC6 0\nBA C\nBD 0\nB4 C\nDC 0\nEB C\nD1 8\nFF C" }, + /* 39*/ { BARCODE_DATAMATRIX, "abc", NULL, NULL, NULL, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A\n8B F\nD4 C\nC2 7\n9E C\nCF 3\n8E 8\nBB F\n86 2\n95 D\nCB A\nFF F" }, + /* 40*/ { BARCODE_DATAMATRIX, "abc", NULL, NULL, NULL, -1, -1, 0, -1, -1, 1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA A\n8C F\n9E 4\nC5 7\nA9 6\n9F F\n97 0\nFA 9\nAA C\nDD D\nD2 2\nFF F" }, + /* 41*/ { BARCODE_DATAMATRIX, "abc", NULL, NULL, NULL, -1, -1, 0, -1, 0, 1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "Warning 161: Previous '--dmb256' overwritten by '--dmc40'\nAA A\n8C F\n9E 4\nC5 7\nA9 6\n9F F\n97 0\nFA 9\nAA C\nDD D\nD2 2\nFF F" }, + /* 42*/ { BARCODE_DATAMATRIX, "A\\^1BC\\^^1DEF", NULL, NULL, NULL, EXTRA_ESCAPE_MODE, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, -1, 0, -1, "AA AA AA AA\nE0 B9 88 59\nD0 08 A3 14\n8D 9D DD DB\n8E 3E E5 E8\nDF 3B A5 A1\nB6 20 A6 02\nFF FF FF FF" }, + /* 43*/ { BARCODE_EANX_CC, "[91]12", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, "12345678+12", -1, -1, 0, -1, "DB BC D3 9C 44 E9 D2 2C 19 E7 A2 D8 A0 00 00 00\nDB 31 1C 9C C7 29 92 47 D9 E9 40 C8 A0 00 00 00\nDA 3B EB 10 AF 09 9A 18 9D 7D 82 E8 A0 00 00 00\n10 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00\n20 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00\n10 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00\n14 68 D1 A6 49 BD 55 C9 D4 22 48 B9 40 59 94 98" }, + /* 44*/ { BARCODE_EANX_CC, "[91]12", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, 2, "12345678+12", -1, -1, 0, -1, "D3 A3 E9 DB F5 C9 DB 43 D9 CB 98 D2 20 00 00 00\nD3 25 0F 11 E4 49 D3 51 F1 AC FC D6 20 00 00 00\nD1 33 48 19 39 E9 93 18 49 D8 98 D7 20 00 00 00\nD1 A6 FC DA 1C 49 9B C5 05 E2 84 D7 A0 00 00 00\n10 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00\n20 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00\n10 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00\n14 68 D1 A6 49 BD 55 C9 D4 22 48 B9 40 59 94 98" }, + /* 45*/ { BARCODE_EANX_CC, "[91]12", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, 2, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", -1, -1, 0, -1, "Warning 115: Primary data string too long (127 character maximum), **TRUNCATING**\nError 449: Input length 127 wrong (linear component)" }, + /* 46*/ { BARCODE_MAXICODE, "abc", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, "1234567", -1, -1, 0, -1, "C0 55 55 5C\nC0 00 00 08\nE7 AA AA A0\n55 55 55 58\n00 00 00 0C\nAA AA AA A8\n55 55 55 50\n00 00 00 08\nAA AA AA A4\n55 B1 35 50\n00 90 08 0C\nAA C0 52 A0\n54 40 05 58\n01 00 08 00\nAA C0 0A A0\n55 00 01 58\n02 80 08 08\nAB 80 1E A8\n54 00 05 54\n03 80 0C 00\nA8 00 02 AC\n55 40 25 50\n00 60 40 0C\nAA 60 66 A0\n55 55 53 B0\n00 00 07 A0\nAA AA AE 0C\nA3 CE E2 C8\nB3 F4 AB 20\n47 0F 3C 48\nD0 6C C5 D8\nE4 CD BF 18\n81 5F 38 58" }, + /* 47*/ { BARCODE_QRCODE, "点", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, 1, 0, -1, "Warning 760: Converted to Shift JIS but no ECI specified\nFE 2B F8\n82 AA 08\nBA B2 E8\nBA 0A E8\nBA FA E8\n82 E2 08\nFE AB F8\n00 80 00\nD3 3B B0\n60 95 68\n7A B3 A0\n1D 0F 98\nAA D7 30\n00 E6 A8\nFE DA D0\n82 42 20\nBA 0E 38\nBA C7 18\nBA 17 68\n82 B9 40\nFE C5 28" }, + /* 48*/ { BARCODE_QRCODE, "点", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, 26, 0, -1, -1, NULL, -1, 1, 0, -1, "FE 5B F8\n82 72 08\nBA DA E8\nBA 52 E8\nBA 2A E8\n82 0A 08\nFE AB F8\n00 D8 00\nEF F6 20\nB5 C2 28\n36 28 88\nFD 42 10\n62 2A C8\n00 95 70\nFE B7 38\n82 FD D8\nBA 97 00\nBA 43 60\nBA C8 C8\n82 C3 68\nFE EA F8" }, + /* 49*/ { BARCODE_QRCODE, "\223\137", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, NULL, -1, 1, 0, -1, "FE 2B F8\n82 0A 08\nBA A2 E8\nBA 0A E8\nBA 5A E8\n82 72 08\nFE AB F8\n00 A0 00\nEF AE 20\n75 B5 20\n82 F7 58\nF4 9D C8\n5E 17 28\n00 C2 20\nFE 88 80\n82 82 38\nBA EA A8\nBA 55 50\nBA D7 68\n82 BD D0\nFE B7 78" }, + /* 50*/ { BARCODE_QRCODE, "\223\137", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 1, -1, -1, NULL, -1, 1, 0, -1, "FE 2B F8\n82 AA 08\nBA B2 E8\nBA 0A E8\nBA FA E8\n82 E2 08\nFE AB F8\n00 80 00\nD3 3B B0\n60 95 68\n7A B3 A0\n1D 0F 98\nAA D7 30\n00 E6 A8\nFE DA D0\n82 42 20\nBA 0E 38\nBA C7 18\nBA 17 68\n82 B9 40\nFE C5 28" }, + /* 51*/ { BARCODE_QRCODE, "\\x93\\x5F", NULL, NULL, NULL, DATA_MODE | ESCAPE_MODE, -1, 0, -1, -1, -1, 0, -1, 1, -1, -1, NULL, -1, 1, 0, -1, "FE 2B F8\n82 AA 08\nBA B2 E8\nBA 0A E8\nBA FA E8\n82 E2 08\nFE AB F8\n00 80 00\nD3 3B B0\n60 95 68\n7A B3 A0\n1D 0F 98\nAA D7 30\n00 E6 A8\nFE DA D0\n82 42 20\nBA 0E 38\nBA C7 18\nBA 17 68\n82 B9 40\nFE C5 28" }, + /* 52*/ { BARCODE_QRCODE, "点", NULL, NULL, NULL, -1, -1, 0, -1, -1, -1, 0, -1, 0, 2, -1, NULL, -1, 1, 0, -1, "Warning 760: Converted to Shift JIS but no ECI specified\nFE 4B F8\n82 92 08\nBA 42 E8\nBA 92 E8\nBA 3A E8\n82 EA 08\nFE AB F8\n00 38 00\nFB CD 50\nA5 89 18\n0B 74 B8\nFC 81 A0\n92 34 B8\n00 DE 48\nFE AB 10\n82 5E 50\nBA C9 20\nBA C9 20\nBA F4 E0\n82 81 A0\nFE B4 E8" }, + /* 53*/ { BARCODE_HANXIN, "é", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 1, -1, -1, NULL, -1, -1, 0, -1, "FE 8A FE\n80 28 02\nBE E8 FA\nA0 94 0A\nAE 3E EA\nAE D2 EA\nAE 74 EA\n00 AA 00\n15 B4 80\n0B 48 74\nA2 4A A4\nB5 56 2C\nA8 5A A8\n9F 18 50\n02 07 50\n00 A6 00\nFE 20 EA\n02 C2 EA\nFA C4 EA\n0A 42 0A\nEA 52 FA\nEA 24 02\nEA AA FE" }, + /* 54*/ { BARCODE_HANXIN, "é", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 1, 3, -1, NULL, -1, -1, 0, -1, "FE 16 FE\n80 E2 02\nBE C2 FA\nA0 A0 0A\nAE F6 EA\nAE 98 EA\nAE BA EA\n00 E0 00\n15 83 80\n44 7E AE\n92 9C 78\n25 BF 08\n47 4B 8C\n0D F9 74\n03 E7 50\n00 3A 00\nFE C2 EA\n02 22 EA\nFA DA EA\n0A 22 0A\nEA B2 FA\nEA 9A 02\nEA E8 FE" }, + /* 55*/ { BARCODE_HANXIN, "é", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, 1, 4, -1, NULL, -1, -1, 0, -1, "FE 8A FE\n80 28 02\nBE E8 FA\nA0 94 0A\nAE 3E EA\nAE D2 EA\nAE 74 EA\n00 AA 00\n15 B4 80\n0B 48 74\nA2 4A A4\nB5 56 2C\nA8 5A A8\n9F 18 50\n02 07 50\n00 A6 00\nFE 20 EA\n02 C2 EA\nFA C4 EA\n0A 42 0A\nEA 52 FA\nEA 24 02\nEA AA FE" }, + /* 56*/ { BARCODE_TELEPEN, "ABC\020123", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, -1, -1, -1, NULL, -1, -1, 0, 1, "AB A8 BB B8 E3 B8 AE EA EE BA EA BA E2 22 BA B8 EA 2A" }, + /* 57*/ { BARCODE_TELEPEN_NUM, "123\020ABC", NULL, NULL, NULL, DATA_MODE, -1, 0, -1, -1, -1, 0, -1, -1, -1, -1, NULL, -1, -1, 0, 1, "AA E8 EA BA E2 22 EE BA BB B8 E3 B8 AE EA BA B8 E8 AA" }, }; int data_size = ARRAY_SIZE(data); int i; @@ -413,13 +419,16 @@ static void test_dump_args(const testCtx *const p_ctx) { strcat(cmd, " 2>&1"); assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); - assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); if (have_input1) { - assert_zero(testUtilRemove(input1_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, input1_filename, errno, strerror(errno)); + assert_zero(testUtilRemove(input1_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, input1_filename, errno, strerror(errno)); } if (have_input2) { - assert_zero(testUtilRemove(input2_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, input2_filename, errno, strerror(errno)); + assert_zero(testUtilRemove(input2_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, input2_filename, errno, strerror(errno)); } } @@ -432,30 +441,35 @@ static void test_dump_segs(const testCtx *const p_ctx) { struct item { int b; + int batch; const char *data; const char *data_seg1; const char *data_seg2; int eci; int eci_seg1; int eci_seg2; + int num_seg2; const char *expected; }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { -1, "123", NULL, NULL, -1, -1, -1, "D3 96 72 F7 65 C9 61 8E B" }, - /* 1*/ { -1, "123", NULL, NULL, -1, 3, -1, "Error 166: Invalid segment argument, expect \"ECI,DATA\"" }, - /* 2*/ { -1, "123", "456", NULL, -1, -1, -1, "Error 166: Invalid segment ECI (digits only)" }, - /* 3*/ { -1, "123", "456", NULL, -1, 1000000, -1, "Error 166: Segment ECI code '1000000' out of range (0 to 999999)" }, - /* 4*/ { -1, "123", "456", NULL, -1, 3, -1, "Error 775: Symbology does not support multiple segments" }, - /* 5*/ { BARCODE_AZTEC, "123", "456", NULL, -1, 3, -1, "2B 7A\nC7 02\nF0 6E\n3F FE\n70 1C\nB7 D6\nB4 58\n15 54\n94 56\nB7 DC\n30 1A\n1F FC\n4C 66\n22 DA\n1E C6" }, - /* 6*/ { BARCODE_AZTEC, "123", NULL, "789", -1, -1, 3, "Error 172: Segments must be consecutive - segment 1 missing" }, + /* 0*/ { -1, 0, "123", NULL, NULL, -1, -1, -1, -1, "D3 96 72 F7 65 C9 61 8E B" }, + /* 1*/ { -1, 0, "123", NULL, NULL, -1, 3, -1, -1, "Error 166: Invalid segment argument, expect \"ECI,DATA\"" }, + /* 2*/ { -1, 0, "123", "456", NULL, -1, -1, -1, -1, "Error 166: Invalid segment ECI (digits only)" }, + /* 3*/ { -1, 0, "123", "456", NULL, -1, 1000000, -1, -1, "Error 166: Segment ECI code '1000000' out of range (0 to 999999)" }, + /* 4*/ { -1, 0, "123", "456", NULL, -1, 3, -1, -1, "Error 775: Symbology does not support multiple segments" }, + /* 5*/ { BARCODE_AZTEC, 0, "123", "456", NULL, -1, 3, -1, -1, "2B 7A\nC7 02\nF0 6E\n3F FE\n70 1C\nB7 D6\nB4 58\n15 54\n94 56\nB7 DC\n30 1A\n1F FC\n4C 66\n22 DA\n1E C6" }, + /* 6*/ { BARCODE_AZTEC, 0, "123", NULL, "789", -1, -1, 3, -1, "Error 172: Segments must be consecutive - segment 1 missing" }, + /* 7*/ { BARCODE_AZTEC, 1, "123", "456", NULL, -1, 3, -1, -1, "Warning 122: Can't define data in batch mode, **IGNORED** '123'\nWarning 165: Can't define segments in batch mode, **IGNORED** '3,456'\nWarning 124: No data received, no symbol generated" }, + /* 8*/ { BARCODE_AZTEC, 0, "123", "456", "789", -1, 3, 4, 1, "Error 164: Duplicate segment 1" }, }; int data_size = ARRAY_SIZE(data); int i; char cmd[4096]; char buf[4096]; + char seg2_buf[16]; testStart("test_dump_segs"); @@ -470,6 +484,9 @@ static void test_dump_segs(const testCtx *const p_ctx) { arg_int(cmd, "-b ", data[i].b); + if (data[i].batch) { + strcat(cmd, " --batch"); + } if (data[i].data && data[i].data[0]) { arg_data(cmd, "-d ", data[i].data); } @@ -483,16 +500,18 @@ static void test_dump_segs(const testCtx *const p_ctx) { arg_seg(cmd, "--seg1=", NULL, data[i].eci_seg1); } + sprintf(seg2_buf, "--seg%d=", data[i].num_seg2 != -1 ? data[i].num_seg2 : 2); if (data[i].data_seg2 && data[i].data_seg2[0]) { - arg_seg(cmd, "--seg2=", data[i].data_seg2, data[i].eci_seg2); + arg_seg(cmd, seg2_buf, data[i].data_seg2, data[i].eci_seg2); } else if (data[i].eci_seg2 >= 0) { - arg_seg(cmd, "--seg2=", NULL, data[i].eci_seg2); + arg_seg(cmd, seg2_buf, NULL, data[i].eci_seg2); } strcat(cmd, " 2>&1"); assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); - assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); } testFinish(); @@ -501,15 +520,33 @@ static void test_dump_segs(const testCtx *const p_ctx) { static void test_input(const testCtx *const p_ctx) { int debug = p_ctx->debug; -#define TEST_INPUT_LONG "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" +#define TEST_INPUT_LONG "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" /* 250 chars */ -#define TEST_MIRRORED_DIR_LONG "testdir_9012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/" -#define TEST_MIRRORED_DIR_TOO_LONG "testdir_901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901/" +#define TEST_MIRRORED_DIR_LONG "testdir_9012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/" /* 220 chars */ +#define TEST_MIRRORED_DIR_TOO_LONG "testdir_901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901/" /* 222 chars */ #ifndef _WIN32 #define TEST_INPUT_AMPERSAND_EXPECTED "***1.gif\000***2.gif" +#define TEST_INPUT_BSLASH "\\" +#define TEST_INPUT_EXCLAIM "!" +#define TEST_INPUT_DQUOTE "\"" +#define TEST_INPUT_ASTERISK "*" +#define TEST_INPUT_COLON ":" +#define TEST_INPUT_LANGLE "<" +#define TEST_INPUT_RANGLE ">" +#define TEST_INPUT_QUESTION "?" +#define TEST_INPUT_PIPE "|" #else #define TEST_INPUT_AMPERSAND_EXPECTED "+++1.gif\000+++2.gif" +#define TEST_INPUT_BSLASH "_" +#define TEST_INPUT_EXCLAIM "_" +#define TEST_INPUT_DQUOTE "_" +#define TEST_INPUT_ASTERISK "_" +#define TEST_INPUT_COLON "_" +#define TEST_INPUT_LANGLE "_" +#define TEST_INPUT_RANGLE "_" +#define TEST_INPUT_QUESTION "_" +#define TEST_INPUT_PIPE "_" #endif struct item { @@ -517,6 +554,7 @@ static void test_input(const testCtx *const p_ctx) { int batch; int input_mode; int mirror; + const char *opt; const char *filetype; const char *input_filename; const char *input; @@ -525,57 +563,69 @@ static void test_input(const testCtx *const p_ctx) { int num_expected; const char *expected; }; - /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { BARCODE_CODE128, 1, -1, 0, "gif", NULL, "123\n456\n", "", 2, "00001.gif\00000002.gif" }, - /* 1*/ { BARCODE_CODE128, 1, -1, 0, "gif", NULL, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", "~~~.gif", 10, "001.gif\000002.gif\000003.gif\000004.gif\000005.gif\000006.gif\000007.gif\000008.gif\000009.gif\000010.gif" }, - /* 2*/ { BARCODE_CODE128, 1, -1, 0, "gif", NULL, "123\n456\n", "@@@@.gif", 2, TEST_INPUT_AMPERSAND_EXPECTED }, - /* 3*/ { BARCODE_CODE128, 1, -1, 0, "gif", NULL, "123\n456\n789\n", "#####.gif", 3, " 1.gif\000 2.gif\000 3.gif" }, - /* 4*/ { BARCODE_CODE128, 1, -1, 0, "gif", NULL, "123\n456\n", "test_batch~.gif", 2, "test_batch1.gif\000test_batch2.gif" }, - /* 5*/ { BARCODE_CODE128, 1, -1, 1, "gif", NULL, "123\n456\n7890123456789\n", NULL, 3, "123.gif\000456.gif\0007890123456789.gif" }, - /* 6*/ { BARCODE_CODE128, 1, -1, 1, "gif", NULL, "123\n456\n7890123456789\n", "test_input_dir/", 3, "test_input_dir/123.gif\000test_input_dir/456.gif\000test_input_dir/7890123456789.gif" }, - /* 7*/ { BARCODE_CODE128, 1, -1, 1, "svg", NULL, "123\n456\n7890123456789\n", NULL, 3, "123.svg\000456.svg\0007890123456789.svg" }, - /* 8*/ { BARCODE_CODE128, 1, -1, 1, "gif", NULL, "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A_xA0B.gif" }, - /* 9*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, "gif", NULL, "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A_B.gif" }, - /* 10*/ { BARCODE_CODE128, 1, -1, 1, "gif", NULL, "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A_u00A0B.gif" }, - /* 11*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, "gif", NULL, "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A_B.gif" }, - /* 12*/ { BARCODE_CODE128, 1, -1, 1, "gif", NULL, "1!2\"3*\n/:45<6>\n?7890\\\\12345|6789\177\nA\\U0000A0B\n", NULL, 4, "1_2_3_.gif\000__45_6_.gif\000_7890__12345_6789_.gif\000A_U0000A0B.gif" }, - /* 13*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, "gif", NULL, "!\"*\n/:45<6>\n?7890\\\\12345|6789\177\nA\\U0000A0B\n", NULL, 4, "___.gif\000__45_6_.gif\000_7890_12345_6789_.gif\000A_B.gif" }, - /* 14*/ { BARCODE_CODE128, 1, -1, 1, "gif", NULL, "1\\d123*9\n\\o1234:5\n#$%&'()+,-.;=@[]^`{}\n", NULL, 3, "1_d123_9.gif\000_o1234_5.gif\000#$%&'()+,-.;=@[]^`{}.gif" }, - /* 15*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, "gif", NULL, "1\\d123*2\n\\o1234:5\n#$%&'()+,-.;=@[]^`{}\n", NULL, 3, "1__2.gif\000_4_5.gif\000#$%&'()+,-.;=@[]^`{}.gif" }, - /* 16*/ { BARCODE_CODE128, 1, -1, 0, "gif", NULL, "\n", "test_batch.gif", 0, NULL }, - /* 17*/ { BARCODE_CODE128, 1, -1, 0, "gif", NULL, "123\n456\n", TEST_INPUT_LONG "~.gif", 2, TEST_INPUT_LONG "1.gif\000" TEST_INPUT_LONG "2.gif" }, - /* 18*/ { BARCODE_CODE128, 0, -1, 0, "svg", NULL, "123", TEST_INPUT_LONG "1.gif", 1, TEST_INPUT_LONG "1.svg" }, - /* 19*/ { BARCODE_CODE128, 1, -1, 0, "svg", NULL, "123\n", TEST_INPUT_LONG "1.gif", 1, TEST_INPUT_LONG "1.svg" }, - /* 20*/ { BARCODE_CODE128, 1, -1, 0, "gif", NULL, "123\n", "test_batch.jpeg", 1, "test_batch.gif" }, - /* 21*/ { BARCODE_CODE128, 1, -1, 0, "gif", NULL, "123\n", "test_batch.jpg", 1, "test_batch.gif" }, - /* 22*/ { BARCODE_CODE128, 1, -1, 0, "emf", NULL, "123\n", "test_batch.jpegg", 1, "test_batch.jpegg.emf" }, - /* 23*/ { BARCODE_CODE128, 1, -1, 0, "emf", NULL, "123\n", "test_batch.jpg", 1, "test_batch.emf" }, - /* 24*/ { BARCODE_CODE128, 1, -1, 0, "eps", NULL, "123\n", "test_batch.ps", 1, "test_batch.eps" }, - /* 25*/ { BARCODE_CODE128, 1, -1, 1, "gif", NULL, "1234567890123456789012345678901\n1234567890123456789012345678902\n", TEST_MIRRORED_DIR_LONG, 2, TEST_MIRRORED_DIR_LONG "1234567890123456789012345678901.gif\000" TEST_MIRRORED_DIR_LONG "1234567890123456789012345678902.gif" }, - /* 26*/ { BARCODE_CODE128, 1, -1, 1, "gif", NULL, "123\n456\n", TEST_MIRRORED_DIR_TOO_LONG, 2, "123.gif\000456.gif" }, - /* 27*/ { BARCODE_CODE128, 1, -1, 0, "gif", "testé_input.txt", "123\n456\n", "", 2, "00001.gif\00000002.gif" }, - /* 28*/ { BARCODE_CODE128, 1, -1, 0, "gif", "testก_input.txt", "123\n456\n", "test_input_δir/testé~~~.gif", 2, "test_input_δir/testé001.gif\000test_input_δir/testé002.gif" }, + /* 0*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", NULL, "123\n456\n", "", 2, "00001.gif\00000002.gif" }, + /* 1*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", NULL, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", "~~~.gif", 10, "001.gif\000002.gif\000003.gif\000004.gif\000005.gif\000006.gif\000007.gif\000008.gif\000009.gif\000010.gif" }, + /* 2*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", NULL, "123\n456\n", "@@@@.gif", 2, TEST_INPUT_AMPERSAND_EXPECTED }, + /* 3*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", NULL, "123\n456\n789\n", "#####.gif", 3, " 1.gif\000 2.gif\000 3.gif" }, + /* 4*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", NULL, "123\n456\n", "test_batch~.gif", 2, "test_batch1.gif\000test_batch2.gif" }, + /* 5*/ { BARCODE_CODE128, 1, -1, 1, NULL, "gif", NULL, "123\n456\n7890123456789\n", NULL, 3, "123.gif\000456.gif\0007890123456789.gif" }, + /* 6*/ { BARCODE_CODE128, 1, -1, 1, NULL, "gif", NULL, "123\n456\n7890123456789\n", "test_input_dir/", 3, "test_input_dir/123.gif\000test_input_dir/456.gif\000test_input_dir/7890123456789.gif" }, + /* 7*/ { BARCODE_CODE128, 1, -1, 1, NULL, "svg", NULL, "123\n456\n7890123456789\n", NULL, 3, "123.svg\000456.svg\0007890123456789.svg" }, + /* 8*/ { BARCODE_CODE128, 1, -1, 1, NULL, "gif", NULL, "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A" TEST_INPUT_BSLASH "xA0B.gif" }, + /* 9*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, NULL, "gif", NULL, "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A_B.gif" }, + /* 10*/ { BARCODE_CODE128, 1, -1, 1, NULL, "gif", NULL, "1!2\"3*\n/:45<6>\n?7890\\\\12345|6789\177\nA\\U0000A0B\n", NULL, 4, "1" TEST_INPUT_EXCLAIM "2" TEST_INPUT_DQUOTE "3" TEST_INPUT_ASTERISK ".gif\000_" TEST_INPUT_COLON "45" TEST_INPUT_LANGLE "6" TEST_INPUT_RANGLE ".gif\000" TEST_INPUT_QUESTION "7890" TEST_INPUT_BSLASH TEST_INPUT_BSLASH "12345" TEST_INPUT_PIPE "6789_.gif\000A" TEST_INPUT_BSLASH "U0000A0B.gif" }, + /* 11*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, NULL, "gif", NULL, "!\"*\n/:45<6>\n?7890\\\\12345|6789\177\nA\\U0000A0B\n", NULL, 4, TEST_INPUT_EXCLAIM TEST_INPUT_DQUOTE TEST_INPUT_ASTERISK ".gif\000_" TEST_INPUT_COLON "45" TEST_INPUT_LANGLE "6" TEST_INPUT_RANGLE ".gif\000" TEST_INPUT_QUESTION "7890_12345" TEST_INPUT_PIPE "6789_.gif\000A_B.gif" }, + /* 12*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", NULL, "\n", "test_batch.gif", 0, NULL }, + /* 13*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", NULL, "123\n456\n", TEST_INPUT_LONG "~.gif", 2, TEST_INPUT_LONG "1.gif\000" TEST_INPUT_LONG "2.gif" }, + /* 14*/ { BARCODE_CODE128, 0, -1, 0, NULL, "svg", NULL, "123", TEST_INPUT_LONG "1.gif", 1, TEST_INPUT_LONG "1.svg" }, + /* 15*/ { BARCODE_CODE128, 1, -1, 0, NULL, "svg", NULL, "123\n", TEST_INPUT_LONG "1.gif", 1, TEST_INPUT_LONG "1.svg" }, + /* 16*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", NULL, "123\n", "test_batch.jpeg", 1, "test_batch.gif" }, + /* 17*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", NULL, "123\n", "test_batch.jpg", 1, "test_batch.gif" }, + /* 18*/ { BARCODE_CODE128, 1, -1, 0, NULL, "emf", NULL, "123\n", "test_batch.jpegg", 1, "test_batch.jpegg.emf" }, + /* 19*/ { BARCODE_CODE128, 1, -1, 0, NULL, "emf", NULL, "123\n", "test_batch.jpg", 1, "test_batch.emf" }, + /* 20*/ { BARCODE_CODE128, 1, -1, 0, NULL, "eps", NULL, "123\n", "test_batch.ps", 1, "test_batch.eps" }, + /* 21*/ { BARCODE_CODE128, 1, -1, 1, NULL, "gif", NULL, "1234567890123456789012345678901\n1234567890123456789012345678902\n", TEST_MIRRORED_DIR_LONG, 2, TEST_MIRRORED_DIR_LONG "1234567890123456789012345678901.gif\000" TEST_MIRRORED_DIR_LONG "1234567890123456789012345678902.gif" }, + /* 22*/ { BARCODE_CODE128, 1, -1, 1, NULL, "gif", NULL, "123\n456\n", TEST_MIRRORED_DIR_TOO_LONG, 2, "123.gif\000456.gif" }, + /* 23*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", "testé_input.txt", "123\n456\n", "", 2, "00001.gif\00000002.gif" }, + /* 24*/ { BARCODE_CODE128, 1, -1, 0, NULL, "gif", "testก_input.txt", "123\n456\n", "test_input_δir/testé~~~.gif", 2, "test_input_δir/testé001.gif\000test_input_δir/testé002.gif" }, + /* 25*/ { BARCODE_CODE128, 0, -1, 1, NULL, NULL, "", "123", "out", 1, "123.XXX" }, + /* 26*/ { BARCODE_CODE128, 0, -1, 1, NULL, NULL, "", "123", "out.jpg", 1, "123.XXX" }, + /* 27*/ { BARCODE_CODE128, 0, -1, 1, NULL, "svg", "", "123", NULL, 1, "123.svg" }, + /* 28*/ { BARCODE_CODE128, 0, -1, 1, NULL, "svg", "", "!é?", NULL, 1, TEST_INPUT_EXCLAIM "é" TEST_INPUT_QUESTION ".svg" }, + /* 29*/ { BARCODE_CODE128, 1, -1, 1, " --scale=0.4", "gif", NULL, "123\n", NULL, 1, "123.gif" }, + /* 30*/ { BARCODE_QRCODE, 0, -1, 1, NULL, "svg", "", TEST_INPUT_LONG "1", NULL, 1, TEST_INPUT_LONG "1.svg" }, + /* 31*/ { BARCODE_QRCODE, 0, -1, 1, NULL, "svg", "", TEST_INPUT_LONG "12", NULL, 1, TEST_INPUT_LONG "1.svg" }, }; int data_size = ARRAY_SIZE(data); int i; char cmd[4096]; - char buf[4096]; + char buf[8192]; const char *input_filename; const char *outfile; + char outfile_buf[256] = {0}; testStart("test_input"); for (i = 0; i < data_size; i++) { int j; const char *slash; + int expected_len; if (testContinue(p_ctx, i)) continue; #ifdef _WIN32 if (data[i].outfile && (int) strlen(data[i].outfile) > 50) { - if (debug & ZINT_DEBUG_TEST_PRINT) printf("%d not Windows compatible (outfile length %d > 50)\n", i, (int) strlen(data[i].outfile)); + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("%d not Windows compatible (outfile length %d > 50)\n", i, (int) strlen(data[i].outfile)); + } + continue; + } + if (!data[i].outfile && data[i].num_expected == 1 && strlen(data[i].expected) > 50) { + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("%d not Windows compatible (expected length %d > 50)\n", i, (int) strlen(data[i].expected)); + } continue; } #endif @@ -589,35 +639,56 @@ static void test_input(const testCtx *const p_ctx) { arg_bool(cmd, "--batch", data[i].batch); arg_input_mode(cmd, data[i].input_mode); arg_bool(cmd, "--mirror", data[i].mirror); + if (data[i].opt) { + strcat(cmd, data[i].opt); + } arg_data(cmd, "--filetype=", data[i].filetype); input_filename = data[i].input_filename ? data[i].input_filename : "test_input.txt"; - arg_input(cmd, input_filename, data[i].input); + if (*input_filename) { + arg_input(cmd, input_filename, data[i].input); + } else { + arg_data(cmd, "-d ", data[i].input); + } arg_data(cmd, "-o ", data[i].outfile); if (!data[i].expected || (data[i].batch && data[i].mirror && data[i].outfile && data[i].outfile[0] - && strcmp(data[i].outfile, TEST_MIRRORED_DIR_LONG) == 0)) { + && strcmp(data[i].outfile, TEST_MIRRORED_DIR_LONG) == 0) + || (data[i].opt && strncmp(data[i].opt, " --scale", 8) == 0)) { printf("++++ Following %s expected, ignore: ", data[i].expected ? "warning" : "error"); fflush(stdout); } assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); outfile = data[i].expected; + if (data[i].num_expected == 1 && (expected_len = (int) strlen(outfile)) > 3 + && strcmp(outfile + expected_len - 3, "XXX") == 0) { + strcpy(outfile_buf, outfile); + strcpy(outfile_buf + expected_len - 3, ZBarcode_NoPng() ? "gif" : "png"); + outfile = outfile_buf; + } for (j = 0; j < data[i].num_expected; j++) { assert_nonzero(testUtilExists(outfile), "i:%d j:%d testUtilExists(%s) != 1\n", i, j, outfile); - assert_zero(testUtilRemove(outfile), "i:%d j:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, j, outfile, errno, strerror(errno)); + assert_zero(testUtilRemove(outfile), "i:%d j:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, j, outfile, errno, strerror(errno)); outfile += strlen(outfile) + 1; } - assert_zero(testUtilRemove(input_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, input_filename, errno, strerror(errno)); + if (*input_filename) { + assert_zero(testUtilRemove(input_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, input_filename, errno, strerror(errno)); + } /* Remove directory if any */ - if (data[i].outfile && (slash = strrchr(data[i].outfile, '/')) != NULL && strcmp(data[i].outfile, TEST_MIRRORED_DIR_TOO_LONG) != 0) { + if (data[i].outfile && (slash = strrchr(data[i].outfile, '/')) != NULL + && strcmp(data[i].outfile, TEST_MIRRORED_DIR_TOO_LONG) != 0) { char dirpath[256]; - assert_nonzero((size_t) (slash - data[i].outfile) < sizeof(dirpath), "i: %d output directory too long\n", i); + assert_nonzero((size_t) (slash - data[i].outfile) < sizeof(dirpath), "i: %d output directory too long\n", + i); strncpy(dirpath, data[i].outfile, slash - data[i].outfile); dirpath[slash - data[i].outfile] = '\0'; - assert_zero(testUtilRmDir(dirpath), "i:%d testUtilRmDir(%s) != 0 (%d: %s)\n", i, dirpath, errno, strerror(errno)); + assert_zero(testUtilRmDir(dirpath), "i:%d testUtilRmDir(%s) != 0 (%d: %s)\n", + i, dirpath, errno, strerror(errno)); } } @@ -663,7 +734,8 @@ static void test_stdin_input(const testCtx *const p_ctx) { assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); assert_nonzero(testUtilExists(data[i].outfile), "i:%d testUtilExists(%s) != 1\n", i, data[i].outfile); - assert_zero(testUtilRemove(data[i].outfile), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, data[i].outfile, errno, strerror(errno)); + assert_zero(testUtilRemove(data[i].outfile), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, data[i].outfile, errno, strerror(errno)); } testFinish(); @@ -678,14 +750,19 @@ static void test_batch_input(const testCtx *const p_ctx) { const char *data; const char *input; const char *input2; + const char *opt; const char *expected; }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { BARCODE_CODE128, "123", NULL, NULL, "Warning 122: Can't define data in batch mode, **IGNORED** '123'\nWarning 124: No data received, no symbol generated" }, - /* 1*/ { BARCODE_CODE128, "123", "123\n456\n", NULL, "Warning 122: Can't define data in batch mode, **IGNORED** '123'\nD3 96 72 F7 65 C9 61 8E B\nD3 97 62 F7 67 49 19 8E B" }, - /* 2*/ { BARCODE_CODE128, NULL, "123\n456\n", "789\n", "Warning 143: Can only define one input file in batch mode, **IGNORED** 'test_batch_input2.txt'\nD3 96 72 F7 65 C9 61 8E B\nD3 97 62 F7 67 49 19 8E B" }, + /* 0*/ { BARCODE_CODE128, "123", NULL, NULL, NULL, "Warning 122: Can't define data in batch mode, **IGNORED** '123'\nWarning 124: No data received, no symbol generated" }, + /* 1*/ { BARCODE_CODE128, "123", "123\n456\n", NULL, NULL, "Warning 122: Can't define data in batch mode, **IGNORED** '123'\nD3 96 72 F7 65 C9 61 8E B\nD3 97 62 F7 67 49 19 8E B" }, + /* 2*/ { BARCODE_CODE128, NULL, "123\n456\n", "789\n", NULL, "Warning 143: Can only define one input file in batch mode, **IGNORED** 'test_batch_input2.txt'\nD3 96 72 F7 65 C9 61 8E B\nD3 97 62 F7 67 49 19 8E B" }, + /* 3*/ { BARCODE_CODE128, NULL, "123\r\n456\n", NULL, NULL, "D3 96 72 F7 65 C9 61 8E B\nD3 97 62 F7 67 49 19 8E B" }, + /* 4*/ { BARCODE_CODE128, NULL, "123\r\n456\r\n", NULL, NULL, "D3 96 72 F7 65 C9 61 8E B\nD3 97 62 F7 67 49 19 8E B" }, + /* 5*/ { BARCODE_CODE128, NULL, "123\n456", NULL, NULL, "D3 96 72 F7 65 C9 61 8E B\nWarning 104: No newline at end of input file, last line **IGNORED**" }, + /* 6*/ { BARCODE_EAN13, NULL, "123\r\n456\n", NULL, " --scalexdimdp", "A3 46 8D 1A 34 6A B9 72 CD B2 15 0A\nA3 46 8D 1A 34 6A B9 72 B9 3A 84 EA" }, }; int data_size = ARRAY_SIZE(data); int i; @@ -713,6 +790,9 @@ static void test_batch_input(const testCtx *const p_ctx) { arg_data(cmd, "-d ", data[i].data); have_input1 = arg_input(cmd, input1_filename, data[i].input); have_input2 = arg_input(cmd, input2_filename, data[i].input2); + if (data[i].opt) { + strcat(cmd, data[i].opt); + } strcat(cmd, " 2>&1"); @@ -720,10 +800,12 @@ static void test_batch_input(const testCtx *const p_ctx) { assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s)\n", i, buf, data[i].expected); if (have_input1) { - assert_zero(testUtilRemove(input1_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, input1_filename, errno, strerror(errno)); + assert_zero(testUtilRemove(input1_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, input1_filename, errno, strerror(errno)); } if (have_input2) { - assert_zero(testUtilRemove(input2_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, input2_filename, errno, strerror(errno)); + assert_zero(testUtilRemove(input2_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, input2_filename, errno, strerror(errno)); } } @@ -738,20 +820,23 @@ static void test_batch_large(const testCtx *const p_ctx) { int mirror; const char *pattern; int length; + int noeol; const char *expected; }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { BARCODE_HANXIN, 0, "1", 7827, "00001.gif" }, - /* 1*/ { BARCODE_HANXIN, 1, "1", 7827, "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.gif" }, - /* 2*/ { BARCODE_HANXIN, 0, "1", 7828, NULL }, + /* 0*/ { BARCODE_HANXIN, 0, "1", 7827, 0, "00001.gif" }, + /* 1*/ { BARCODE_HANXIN, 1, "1", 7827, 0, "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.gif" }, + /* 2*/ { BARCODE_HANXIN, 0, "1", 7828, 0, NULL }, + /* 3*/ { BARCODE_HANXIN, 0, "1", ZINT_MAX_DATA_LEN, 0, NULL }, + /* 4*/ { BARCODE_HANXIN, 0, "1", ZINT_MAX_DATA_LEN + 1, 1, NULL }, }; int data_size = ARRAY_SIZE(data); int i; char cmd[16384]; - char data_buf[8192]; + char data_buf[ZINT_MAX_DATA_LEN + 4]; char buf[16384]; const char *input_filename = "test_batch_large.txt"; @@ -777,22 +862,31 @@ static void test_batch_large(const testCtx *const p_ctx) { arg_bool(cmd, "--mirror", data[i].mirror); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - strcat(data_buf, "\n"); + if (!data[i].noeol) { + strcat(data_buf, "\n"); + } have_input = arg_input(cmd, input_filename, data_buf); if (!data[i].expected) { - printf("++++ Following error expected, ignore: "); + if (data[i].noeol) { + printf("++++ Following error and warning expected, ignore: "); + } else { + printf("++++ Following error expected, ignore: "); + } fflush(stdout); } assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); if (data[i].expected) { - assert_zero(testUtilRemove(data[i].expected), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, data[i].expected, errno, strerror(errno)); + assert_zero(testUtilRemove(data[i].expected), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, data[i].expected, errno, strerror(errno)); } else { - assert_zero(testUtilExists("out.gif"), "i:%d testUtilExists(out.gif) != 0 (%d: %s) (%s)\n", i, errno, strerror(errno), cmd); + assert_zero(testUtilExists("out.gif"), "i:%d testUtilExists(out.gif) != 0 (%d: %s) (%s)\n", + i, errno, strerror(errno), cmd); } - if (have_input) { - assert_zero(testUtilRemove(input_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, input_filename, errno, strerror(errno)); + if (have_input && (p_ctx->index == -1 || data[i].expected)) { + assert_zero(testUtilRemove(input_filename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, input_filename, errno, strerror(errno)); } } @@ -831,45 +925,59 @@ static void test_checks(const testCtx *const p_ctx) { /* 0*/ { -2, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 139: Invalid add-on gap value (digits only)" }, /* 1*/ { 6, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 140: Add-on gap '6' out of range (7 to 12), **IGNORED**" }, /* 2*/ { 13, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 140: Add-on gap '13' out of range (7 to 12), **IGNORED**" }, - /* 3*/ { -1, -2, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 107: Invalid border width value (digits only)" }, - /* 4*/ { -1, 1001, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 108: Border width '1001' out of range (0 to 1000), **IGNORED**" }, - /* 5*/ { -1, -1, -1, -1, -5.1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 195: Text gap '-5.1' out of range (-5 to 10), **IGNORED**" }, - /* 6*/ { -1, -1, -1, -1, 10.01, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 195: Text gap '10.01' out of range (-5 to 10), **IGNORED**" }, - /* 7*/ { -1, -1, -1, 12345678, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 181: Invalid dot radius floating point (integer part must be 7 digits maximum)" }, - /* 8*/ { -1, -1, -1, 0.009, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 106: Invalid dot radius value (less than 0.01), **IGNORED**" }, - /* 9*/ { -1, -1, -2, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 131: Invalid columns value (digits only)" }, - /* 10*/ { -1, -1, 201, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 111: Number of columns '201' out of range (1 to 200), **IGNORED**" }, - /* 11*/ { -1, -1, -1, -1, -1, -2, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 138: Invalid ECI code (digits only)" }, - /* 12*/ { -1, -1, -1, -1, -1, 1000000, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 118: ECI code '1000000' out of range (0 to 999999), **IGNORED**" }, - /* 13*/ { -1, -1, -1, -1, -1, -1, "jpg", -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 142: File type 'jpg' not supported, **IGNORED**" }, - /* 14*/ { -1, -1, -1, -1, -1, -1, "giff", -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 142: File type 'giff' not supported, **IGNORED**" }, - /* 15*/ { -1, -1, -1, -1, -1, -1, "tiff", -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "" }, /* Allow "tiff" */ - /* 16*/ { -1, -1, -1, -1, -1, -1, NULL, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 183: Invalid symbol height floating point (negative value not permitted)" }, - /* 17*/ { -1, -1, -1, -1, -1, -1, NULL, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 110: Symbol height '0' out of range (0.5 to 2000), **IGNORED**" }, - /* 18*/ { -1, -1, -1, -1, -1, -1, NULL, 2001, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 110: Symbol height '2001' out of range (0.5 to 2000), **IGNORED**" }, - /* 19*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 182: Invalid guard bar descent floating point (negative value not permitted)" }, - /* 20*/ { -1, -1, -1, -1, -1, -1, NULL, -1, 50.1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 135: Guard bar descent '50.1' out of range (0 to 50), **IGNORED**" }, - /* 21*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 148: Invalid mask value (digits only)" }, - /* 22*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 147: Mask value '8' out of range (0 to 7), **IGNORED**" }, - /* 23*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 116: Mode value '7' out of range (0 to 6), **IGNORED**" }, - /* 24*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, "Error 117: Invalid rotation value (digits only)" }, - /* 25*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 137: Rotation value '45' out of range (0, 90, 180 or 270 only), **IGNORED**" }, - /* 26*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, "Error 132: Invalid rows value (digits only)" }, - /* 27*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, 91, -1, -1, -1, -1, -1, -1, -1, "Warning 112: Number of rows '91' out of range (1 to 90), **IGNORED**" }, - /* 28*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, "Error 184: Invalid scale floating point (negative value not permitted)" }, - /* 29*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, 0.49, -1, -1, -1, -1, -1, -1, "Warning 146: Scaling less than 0.5 will be set to 0.5 for 'gif' output" }, - /* 30*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, "Error 149: Invalid Structured Carrier Message version value (digits only)" }, - /* 31*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, "Warning 150: Structured Carrier Message version '100' out of range (0 to 99), **IGNORED**" }, - /* 32*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, "Error 134: Invalid ECC value (digits only)" }, - /* 33*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, 9, -1, -1, -1, -1, "Warning 114: ECC level '9' out of range (0 to 8), **IGNORED**" }, - /* 34*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, "Error 128: Invalid separator value (digits only)" }, - /* 35*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1, "Warning 127: Separator value '5' out of range (0 to 4), **IGNORED**" }, - /* 36*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, "Error 133: Invalid version value (digits only)" }, - /* 37*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1000, -1, -1, "Warning 113: Version value '1000' out of range (1 to 999), **IGNORED**" }, - /* 38*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, "Error 153: Invalid vertical whitespace value '-2' (digits only)" }, - /* 39*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1001, -1, "Warning 154: Vertical whitespace value '1001' out of range (0 to 1000), **IGNORED**" }, - /* 40*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, "Error 120: Invalid horizontal whitespace value '-2' (digits only)" }, - /* 41*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1001, "Warning 121: Horizontal whitespace value '1001' out of range (0 to 1000), **IGNORED**" }, + /* 3*/ { 12, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "" }, + /* 4*/ { -1, -2, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 107: Invalid border width value (digits only)" }, + /* 5*/ { -1, 101, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 108: Border width '101' out of range (0 to 100), **IGNORED**" }, + /* 6*/ { -1, 100, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "" }, + /* 7*/ { -1, -1, -1, -1, .12345678, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 194: Invalid text gap floating point (fractional part must be 7 digits maximum)" }, + /* 8*/ { -1, -1, -1, -1, -5.1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 195: Text gap '-5.1' out of range (-5 to 10), **IGNORED**" }, + /* 9*/ { -1, -1, -1, -1, 10.01, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 195: Text gap '10.01' out of range (-5 to 10), **IGNORED**" }, + /* 10*/ { -1, -1, -1, -1, 10.0, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "" }, + /* 11*/ { -1, -1, -1, 12345678, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 181: Invalid dot radius floating point (integer part must be 7 digits maximum)" }, + /* 12*/ { -1, -1, -1, 0.009, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 106: Invalid dot radius value (less than 0.01), **IGNORED**" }, + /* 13*/ { -1, -1, -1, 0.01, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "" }, + /* 14*/ { -1, -1, -2, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 131: Invalid columns value (digits only)" }, + /* 15*/ { -1, -1, 201, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 111: Number of columns '201' out of range (1 to 200), **IGNORED**" }, + /* 16*/ { -1, -1, -1, -1, -1, -2, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 138: Invalid ECI code (digits only)" }, + /* 17*/ { -1, -1, -1, -1, -1, 1000000, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 118: ECI code '1000000' out of range (0 to 999999), **IGNORED**" }, + /* 18*/ { -1, -1, -1, -1, -1, -1, "jpg", -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 142: File type 'jpg' not supported, **IGNORED**" }, + /* 19*/ { -1, -1, -1, -1, -1, -1, "giff", -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 142: File type 'giff' not supported, **IGNORED**" }, + /* 20*/ { -1, -1, -1, -1, -1, -1, "tiff", -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "" }, /* Allow "tiff" */ + /* 21*/ { -1, -1, -1, -1, -1, -1, NULL, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 183: Invalid symbol height floating point (negative value not permitted)" }, + /* 22*/ { -1, -1, -1, -1, -1, -1, NULL, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 110: Symbol height '0' out of range (0.5 to 2000), **IGNORED**" }, + /* 23*/ { -1, -1, -1, -1, -1, -1, NULL, 2001, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 110: Symbol height '2001' out of range (0.5 to 2000), **IGNORED**" }, + /* 24*/ { -1, -1, -1, -1, -1, -1, NULL, 2000, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "" }, + /* 25*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 182: Invalid guard bar descent floating point (negative value not permitted)" }, + /* 26*/ { -1, -1, -1, -1, -1, -1, NULL, -1, 50.1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 135: Guard bar descent '50.1' out of range (0 to 50), **IGNORED**" }, + /* 27*/ { -1, -1, -1, -1, -1, -1, NULL, -1, 50.0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "" }, + /* 28*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 148: Invalid mask value (digits only)" }, + /* 29*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 147: Mask value '8' out of range (0 to 7), **IGNORED**" }, + /* 30*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 116: Mode value '7' out of range (0 to 6), **IGNORED**" }, + /* 31*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 136: Invalid mode value (digits only)" }, + /* 32*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, "" }, + /* 33*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, "Error 117: Invalid rotation value (digits only)" }, + /* 34*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 137: Rotation value '45' out of range (0, 90, 180 or 270 only), **IGNORED**" }, + /* 35*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, "" }, + /* 36*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, "Error 132: Invalid rows value (digits only)" }, + /* 37*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, 91, -1, -1, -1, -1, -1, -1, -1, "Warning 112: Number of rows '91' out of range (1 to 90), **IGNORED**" }, + /* 38*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, "Error 184: Invalid scale floating point (negative value not permitted)" }, + /* 39*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, 0.49, -1, -1, -1, -1, -1, -1, "Warning 146: Scaling less than 0.5 will be set to 0.5 for 'gif' output" }, + /* 40*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, 0.009, -1, -1, -1, -1, -1, -1, "Warning 105: Invalid scale value '0.009' (less than 0.01), **IGNORED**" }, + /* 41*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, "Error 149: Invalid Structured Carrier Message version value (digits only)" }, + /* 42*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, "Warning 150: Structured Carrier Message version '100' out of range (0 to 99), **IGNORED**" }, + /* 43*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, "Error 134: Invalid ECC value (digits only)" }, + /* 44*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, 9, -1, -1, -1, -1, "Warning 114: ECC level '9' out of range (0 to 8), **IGNORED**" }, + /* 45*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, "Error 128: Invalid separator value (digits only)" }, + /* 46*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1, "Warning 127: Separator value '5' out of range (0 to 4), **IGNORED**" }, + /* 47*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, "" }, + /* 48*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, "Error 133: Invalid version value (digits only)" }, + /* 49*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1000, -1, -1, "Warning 113: Version value '1000' out of range (1 to 999), **IGNORED**" }, + /* 50*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, "Error 153: Invalid vertical whitespace value '-2' (digits only)" }, + /* 51*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 101, -1, "Warning 154: Vertical whitespace value '101' out of range (0 to 100), **IGNORED**" }, + /* 52*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, "" }, + /* 53*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, "Error 120: Invalid horizontal whitespace value '-2' (digits only)" }, + /* 54*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 101, "Warning 121: Horizontal whitespace value '101' out of range (0 to 100), **IGNORED**" }, + /* 55*/ { -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100, "" }, }; int data_size = ARRAY_SIZE(data); int i; @@ -889,7 +997,10 @@ static void test_checks(const testCtx *const p_ctx) { strcat(cmd, " --verbose"); } - arg_int(cmd, "--addongap=", data[i].addongap); + if (data[i].addongap != -1) { + arg_int(cmd, "--addongap=", data[i].addongap); + arg_int(cmd, "-b ", BARCODE_EAN8); + } arg_int(cmd, "--border=", data[i].border); arg_int(cmd, "--cols=", data[i].cols); arg_double(cmd, "--dotsize=", data[i].dotsize); @@ -913,10 +1024,12 @@ static void test_checks(const testCtx *const p_ctx) { strcat(cmd, " 2>&1"); assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); - assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); if (strncmp(data[i].expected, "Warning", 7) == 0) { - assert_zero(testUtilRemove(outfilename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, outfilename, errno, strerror(errno)); + assert_zero(testUtilRemove(outfilename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, outfilename, errno, strerror(errno)); } } @@ -992,9 +1105,11 @@ static void test_barcode_symbology(const testCtx *const p_ctx) { assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); if (!data[i].fail) { - assert_zero(testUtilRemove(outfilename), "i:%d testUtilRemove(%s) != 0 (%d: %s) (%s)\n", i, outfilename, errno, strerror(errno), cmd); + assert_zero(testUtilRemove(outfilename), "i:%d testUtilRemove(%s) != 0 (%d: %s) (%s)\n", + i, outfilename, errno, strerror(errno), cmd); } - assert_nonnull(strstr(buf, data[i].expected), "i:%d strstr(%s, %s) == NULL (%s)\n", i, buf, data[i].expected, cmd); + assert_nonnull(strstr(buf, data[i].expected), "i:%d strstr(%s, %s) == NULL (%s)\n", + i, buf, data[i].expected, cmd); } testFinish(); @@ -1021,8 +1136,8 @@ static void test_other_opts(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { BARCODE_CODE128, "1", -1, " --test", "", "", 0 }, /* Do internal test */ - /* 1*/ { BARCODE_AZTEC, "1", -1, " --azfull", "", "", 0 }, + /* 0*/ { BARCODE_CODE128, "1", -1, " --test", NULL, "++++ Following warning expected, ignore: Warning 188: Directory for mirrored output too long (greater than 220), **IGNORED**\n++++ Following error expected, ignore: Error 102: Unable to read input file 'test_nosuch.file' (", 1 }, /* Do internal test */ + /* 1*/ { BARCODE_AZTEC, "1", -1, " --azfull", NULL, "", 0 }, /* 2*/ { BARCODE_CODE128, "1", -1, " --bg=", "EF9900", "", 0 }, /* 3*/ { BARCODE_CODE128, "1", -1, " -bg=", "EF9900", "", 0 }, /* 4*/ { BARCODE_CODE128, "1", -1, " --bg=", "EF9900AA", "", 0 }, @@ -1036,15 +1151,15 @@ static void test_other_opts(const testCtx *const p_ctx) { /* 12*/ { BARCODE_CODE128, "1", -1, " --fg=", "0,0,0,100", "", 0 }, /* 13*/ { BARCODE_CODE128, "1", -1, " --fgcolor=", "111111", "", 0 }, /* 14*/ { BARCODE_CODE128, "1", -1, " --fgcolour=", "111111", "", 0 }, - /* 15*/ { BARCODE_CODE128, "1", -1, " --compliantheight", "", "", 0 }, - /* 16*/ { BARCODE_DATAMATRIX, "1", -1, " --dmiso144", "", "", 0 }, - /* 17*/ { BARCODE_EANX, "123456", -1, " --guardwhitespace", "", "", 0 }, - /* 18*/ { BARCODE_EANX, "123456", -1, " --embedfont", "", "", 0 }, - /* 19*/ { BARCODE_CODE128, "1", -1, " --nobackground", "", "", 0 }, - /* 20*/ { BARCODE_CODE128, "1", -1, " --noquietzones", "", "", 0 }, - /* 21*/ { BARCODE_CODE128, "1", -1, " --notext", "", "", 0 }, - /* 22*/ { BARCODE_CODE128, "1", -1, " --quietzones", "", "", 0 }, - /* 23*/ { BARCODE_CODE128, "1", -1, " --reverse", "", "", 0 }, + /* 15*/ { BARCODE_CODE128, "1", -1, " --compliantheight", NULL, "", 0 }, + /* 16*/ { BARCODE_DATAMATRIX, "1", -1, " --dmiso144", NULL, "", 0 }, + /* 17*/ { BARCODE_EANX, "123456", -1, " --guardwhitespace", NULL, "", 0 }, + /* 18*/ { BARCODE_EANX, "123456", -1, " --embedfont", NULL, "", 0 }, + /* 19*/ { BARCODE_CODE128, "1", -1, " --nobackground", NULL, "", 0 }, + /* 20*/ { BARCODE_CODE128, "1", -1, " --noquietzones", NULL, "", 0 }, + /* 21*/ { BARCODE_CODE128, "1", -1, " --notext", NULL, "", 0 }, + /* 22*/ { BARCODE_CODE128, "1", -1, " --quietzones", NULL, "", 0 }, + /* 23*/ { BARCODE_CODE128, "1", -1, " --reverse", NULL, "", 0 }, /* 24*/ { BARCODE_CODE128, "1", -1, " --werror", NULL, "", 0 }, /* 25*/ { 19, "1", -1, " --werror", NULL, "Error 207: Codabar 18 not supported", 0 }, /* 26*/ { BARCODE_GS1_128, "[01]12345678901231", -1, "", NULL, "", 0 }, @@ -1072,7 +1187,7 @@ static void test_other_opts(const testCtx *const p_ctx) { /* 48*/ { BARCODE_AZTEC, "1", -1, " --structapp=", "0,2,12345678901234567890123456789012", "Error 155: Structured Append index '0' out of range (1 to count '2')", 0 }, /* 49*/ { BARCODE_AZTEC, "1", -1, " --structapp=", "3,2,12345678901234567890123456789012", "Error 155: Structured Append index '3' out of range (1 to count '2')", 0 }, /* 50*/ { BARCODE_AZTEC, "1", -1, " --structapp=", "2,3,12345678901234567890123456789012", "", 0 }, - /* 51*/ { BARCODE_PDF417, "1", -1, " --heightperrow", "", "", 0 }, + /* 51*/ { BARCODE_PDF417, "1", -1, " --heightperrow", NULL, "", 0 }, /* 52*/ { -1, NULL, -1, " -v", NULL, "Zint version ", 1 }, /* 53*/ { -1, NULL, -1, " --version", NULL, "Zint version ", 1 }, /* 54*/ { -1, NULL, -1, " -h", NULL, "Encode input data in a barcode ", 1 }, @@ -1118,11 +1233,14 @@ static void test_other_opts(const testCtx *const p_ctx) { assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); if (data[i].strstr_cmp) { - assert_nonnull(strstr(buf, data[i].expected), "i:%d strstr buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_nonnull(strstr(buf, data[i].expected), "i:%d strstr buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); } else { - assert_zero(strcmp(buf, data[i].expected), "i:%d strcmp buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_zero(strcmp(buf, data[i].expected), "i:%d strcmp buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); if (strstr(data[i].expected, "Error") == NULL) { - assert_zero(testUtilRemove(outfilename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, outfilename, errno, strerror(errno)); + assert_zero(testUtilRemove(outfilename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, outfilename, errno, strerror(errno)); } } } @@ -1168,12 +1286,15 @@ static void test_combos(const testCtx *const p_ctx) { assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); if (data[i].strstr_cmp) { - assert_nonnull(strstr(buf, data[i].expected), "i:%d strstr buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_nonnull(strstr(buf, data[i].expected), "i:%d strstr buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); } else { - assert_zero(strcmp(buf, data[i].expected), "i:%d strcmp buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_zero(strcmp(buf, data[i].expected), "i:%d strcmp buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); } if (data[i].outfilename != NULL) { - assert_zero(remove(data[i].outfilename), "i:%d remove(%s) != 0 (%d: %s)\n", i, data[i].outfilename, errno, strerror(errno)); + assert_zero(remove(data[i].outfilename), "i:%d remove(%s) != 0 (%d: %s)\n", + i, data[i].outfilename, errno, strerror(errno)); } } @@ -1232,9 +1353,11 @@ static void test_exit_status(const testCtx *const p_ctx) { strcat(cmd, " 2>&1"); assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, &exit_status), "i:%d exec(%s) NULL\n", i, cmd); - assert_equal(exit_status, data[i].expected, "i:%d exit_status %d != expected (%d) (%s), (cmd: %s)\n", i, exit_status, data[i].expected, buf, cmd); + assert_equal(exit_status, data[i].expected, "i:%d exit_status %d != expected (%d) (%s), (cmd: %s)\n", + i, exit_status, data[i].expected, buf, cmd); if (data[i].expected < ZINT_ERROR) { - assert_zero(testUtilRemove(outfilename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", i, outfilename, errno, strerror(errno)); + assert_zero(testUtilRemove(outfilename), "i:%d testUtilRemove(%s) != 0 (%d: %s)\n", + i, outfilename, errno, strerror(errno)); } } @@ -1255,9 +1378,9 @@ static void test_bad_args(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { - /* 0*/ { BARCODE_CODE128, NULL, -1, NULL, NULL, "Error 109: option '-d' requires an argument" }, - /* 1*/ { BARCODE_CODE128, "1", -1, " -o", NULL, "Error 109: option '-o' requires an argument" }, - /* 2*/ { BARCODE_CODE128, "1", -1, " --fast=", "1", "Error 126: option '--fast' does not take an argument" }, + /* 0*/ { BARCODE_CODE128, NULL, -1, NULL, NULL, "Error 109: Option '-d' requires an argument" }, + /* 1*/ { BARCODE_CODE128, "1", -1, " -o", NULL, "Error 109: Option '-o' requires an argument" }, + /* 2*/ { BARCODE_CODE128, "1", -1, " --fast=", "1", "Error 126: Option '--fast' does not take an argument" }, }; int data_size = ARRAY_SIZE(data); int i; @@ -1293,7 +1416,8 @@ static void test_bad_args(const testCtx *const p_ctx) { strcat(cmd, " 2>&1"); assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, &exit_status), "i:%d exec(%s) NULL\n", i, cmd); - assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); } testFinish(); @@ -1334,6 +1458,55 @@ static void test_too_many_args(const testCtx *const p_ctx) { " -d 300", "Error 129: Too many data args (maximum 300)" }, + /* 2*/ { BARCODE_CODE128, + " -d 000 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 010 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 020 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 030 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 040 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 050 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 060 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 070 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 080 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 090 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9", + " -d 100 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 110 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 120 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 130 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 140 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 150 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 160 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 170 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 180 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 190 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9", + " -d 200 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 210 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 220 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 230 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 240 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 250 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 260 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 270 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 280 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 290 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9", + " -i 300", + "Error 130: Too many data args (maximum 300)" + }, + /* 3*/ { BARCODE_CODE16K, + " -d 000 -d 1", + "", + "", + "", + "Error 173: Symbology must be stackable if multiple data arguments given" + }, + /* 4*/ { BARCODE_CODE128, + " -d 000 blah", + "", + "", + "", + "Warning 191: Extra argument 'blah' **IGNORED**" + }, + /* 5*/ { BARCODE_CODE128, + " -d 000 blah blah", + "", + "", + "", + "Warning 192: Extra arguments beginning with 'blah' **IGNORED**" + }, + /* 6*/ { BARCODE_CODE128, + " -d 000 -d 1 --seg1=0,1", + "", + "", + "", + "Error 170: Cannot specify segments and multiple data arguments together" + }, + /* 7*/ { BARCODE_CODE128, + " -i gosh.txt --seg1=0,1", + "", + "", + "", + "Error 171: Cannot use input argument with segment arguments" + }, + /* 8*/ { BARCODE_CODE128, + " -i gosh.txt --mirror", + "", + "", + "", + "Warning 163: '--mirror' given but no data argument, **IGNORED**\nError 229: Unable to read input file \"gosh.txt\" (2: No such file or directory)" + }, }; int data_size = ARRAY_SIZE(data); int i; @@ -1360,7 +1533,8 @@ static void test_too_many_args(const testCtx *const p_ctx) { strcat(cmd, " 2>&1"); assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, &exit_status), "i:%d exec(%s) == NULL\n", i, cmd); - assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); } testFinish(); @@ -1380,9 +1554,15 @@ static void test_optional_args(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ struct item data[] = { /* 0*/ { BARCODE_DATAMATRIX, "123", NULL, " --dmb256", "AA A\n88 F\nD0 C\nC7 F\nAF A\nFF 3\nF5 4\nA1 B\nB5 0\nE1 D\nE9 A\nFF F" }, - /* 1*/ { BARCODE_DATAMATRIX, "123", NULL, " --dmc40", "AA 8\n80 4\nC0 8\n81 C\nB7 0\nAB C\nE1 0\nE5 4\nBC 0\nFF C" }, - /* 2*/ { BARCODE_EAN13, "123", NULL, " --scalexdimdp", "A3 46 8D 1A 34 6A B9 72 CD B2 15 0A" }, - /* 3*/ { BARCODE_MAXICODE, "123", "1234567", " --scmvv", "D7 6F BF FC\n55 70 D8 08\nDB 12 A6 78\n55 55 55 50\n00 00 00 08\nAA AA AA A8\n55 55 55 54\n00 00 00 00\nAA AA AA AC\n55 B1 35 58\n00 90 08 0C\nAA C0 52 A8\n54 40 05 50\n01 00 08 00\nAA C0 0A AC\n55 00 01 58\n02 80 08 0C\nAB 80 1E A0\n54 00 05 5C\n03 80 0C 08\nA8 00 02 A4\n55 40 25 58\n00 60 40 08\nAA 60 66 A0\n55 55 5B FC\n00 00 02 30\nAA AA A1 E0\n5E CF C1 E8\nD0 62 E5 84\n20 1B 10 D8\nDB 8E B6 80\n21 96 26 C0\nC3 C9 89 F8" }, + /* 1*/ { BARCODE_DATAMATRIX, "123", NULL, " --dmb256=", "AA A\n88 F\nD0 C\nC7 F\nAF A\nFF 3\nF5 4\nA1 B\nB5 0\nE1 D\nE9 A\nFF F" }, + /* 2*/ { BARCODE_DATAMATRIX, "123", NULL, " --dmb256=A", "Error 158: Invalid Data Matrix Base 256 mode length value (digits only)" }, + /* 3*/ { BARCODE_DATAMATRIX, "123", NULL, " --dmc40", "AA 8\n80 4\nC0 8\n81 C\nB7 0\nAB C\nE1 0\nE5 4\nBC 0\nFF C" }, + /* 4*/ { BARCODE_DATAMATRIX, "123", NULL, " --dmc40=", "AA 8\n80 4\nC0 8\n81 C\nB7 0\nAB C\nE1 0\nE5 4\nBC 0\nFF C" }, + /* 5*/ { BARCODE_DATAMATRIX, "123", NULL, " --dmc40=-1", "Error 160: Invalid Data Matrix C40 mode length value (digits only)" }, + /* 6*/ { BARCODE_DATAMATRIX, "123", NULL, " --dmc40 --dmb256", "Warning 159: '--dmc40' already set, '--dmb256' **IGNORED**\nAA 8\n80 4\nC0 8\n81 C\nB7 0\nAB C\nE1 0\nE5 4\nBC 0\nFF C" }, + /* 7*/ { BARCODE_DATAMATRIX, "123", NULL, " --square --dmre", "Warning 156: '--square' already set, '--dmre' **IGNORED**\nAA 8\n85 4\nE5 8\nC9 4\nCC 0\nB1 C\n98 0\nB6 4\nA2 0\nFF C" }, + /* 8*/ { BARCODE_EAN13, "123", NULL, " --scalexdimdp", "A3 46 8D 1A 34 6A B9 72 CD B2 15 0A" }, + /* 9*/ { BARCODE_MAXICODE, "123", "1234567", " --scmvv", "D7 6F BF FC\n55 70 D8 08\nDB 12 A6 78\n55 55 55 50\n00 00 00 08\nAA AA AA A8\n55 55 55 54\n00 00 00 00\nAA AA AA AC\n55 B1 35 58\n00 90 08 0C\nAA C0 52 A8\n54 40 05 50\n01 00 08 00\nAA C0 0A AC\n55 00 01 58\n02 80 08 0C\nAB 80 1E A0\n54 00 05 5C\n03 80 0C 08\nA8 00 02 A4\n55 40 25 58\n00 60 40 08\nAA 60 66 A0\n55 55 5B FC\n00 00 02 30\nAA AA A1 E0\n5E CF C1 E8\nD0 62 E5 84\n20 1B 10 D8\nDB 8E B6 80\n21 96 26 C0\nC3 C9 89 F8" }, }; int data_size = ARRAY_SIZE(data); int i; @@ -1411,7 +1591,8 @@ static void test_optional_args(const testCtx *const p_ctx) { strcat(cmd, " 2>&1"); assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, NULL), "i:%d exec(%s) NULL\n", i, cmd); - assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); + assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", + i, buf, data[i].expected, cmd); } testFinish();