From 9b4d097516737ab10ec88d7e98cab6c4b85e610c Mon Sep 17 00:00:00 2001 From: gitlost Date: Fri, 5 Sep 2025 17:23:18 +0100 Subject: [PATCH] RAW_TEXT: change `source` to be unconverted, i.e. UTF-8 (unless `DATA_MODE`); allows ZXing-C++ to be built in writer-only mode without needing "libzueci" library: in GS1 mode check that ECI if any is ASCII compatible general: some code fiddling, `mode` -> `modes` --- ChangeLog | 5 +- backend/aztec.c | 15 +- backend/codablock.c | 14 +- backend/code1.c | 18 +- backend/code128.c | 10 +- backend/code16k.c | 10 +- backend/common.c | 103 ++++++---- backend/common.h | 19 +- backend/dmatrix.c | 31 +-- backend/dotcode.c | 21 +-- backend/eci.c | 27 +-- backend/eci.h | 10 +- backend/gridmtx.c | 29 ++- backend/hanxin.c | 95 +++++----- backend/library.c | 331 +++++++++++++++++++-------------- backend/mailmark.c | 11 ++ backend/maxicode.c | 8 +- backend/pdf417.c | 13 +- backend/qr.c | 158 ++++++++-------- backend/telepen.c | 2 +- backend/tests/test_aztec.c | 14 +- backend/tests/test_codablock.c | 6 +- backend/tests/test_code1.c | 32 ++-- backend/tests/test_code128.c | 6 +- backend/tests/test_code16k.c | 2 +- backend/tests/test_common.c | 165 ++++++++++------ backend/tests/test_dmatrix.c | 13 +- backend/tests/test_dotcode.c | 9 +- backend/tests/test_gridmtx.c | 16 +- backend/tests/test_hanxin.c | 16 +- backend/tests/test_library.c | 52 ++++-- backend/tests/test_maxicode.c | 8 +- backend/tests/test_pdf417.c | 20 +- backend/tests/test_qr.c | 41 ++-- backend/tests/test_ultra.c | 9 +- backend/ultra.c | 18 +- docs/manual.html | 17 +- docs/manual.pmd | 27 +-- docs/manual.txt | 27 +-- 39 files changed, 798 insertions(+), 630 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6b3d5c9..c9685e2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -Version 2.15.0.9 (dev) not released yet (2025-08-25) +Version 2.15.0.9 (dev) not released yet (2025-09-05) ==================================================== **Incompatible changes** @@ -21,7 +21,8 @@ Version 2.15.0.9 (dev) not released yet (2025-08-25) Changes ------- - Add new `BARCODE_RAW_TEXT` option for `output_options` which sets new fields - `raw_segs` and `raw_seg_count` with encoded data + `raw_segs` and `raw_seg_count` with encoded data (pre-converted, i.e. UTF-8 + unless input mode is `DATA_MODE`) - Add API funcs `ZBarcode_UTF8_To_ECI()` and `ZBarcode_Dest_Len_ECI()` - Set `option_1`, `option_2`, `option_3` to values used in encodation, and add new access methods `encodedOption1()` etc. to Qt Backend, and use in GUI to diff --git a/backend/aztec.c b/backend/aztec.c index 520c8163..f15d48c2 100644 --- a/backend/aztec.c +++ b/backend/aztec.c @@ -110,7 +110,7 @@ static int aztec_text_process(const unsigned char source[], int length, int bp, char *reduced_encode_mode = (char *) z_alloca(length + 1); for (i = 0; i < length; i++) { - if (source[i] >= 128) { + if (!z_isascii(source[i])) { encode_mode[i] = 'B'; } else if (gs1 && source[i] == '\x1D') { encode_mode[i] = 'P'; /* For FLG(n) & FLG(0) = FNC1 */ @@ -678,20 +678,17 @@ static int aztec_text_process_segs(struct zint_symbol *symbol, struct zint_seg s char binary_string[], const int gs1, const int gs1_bp, int *data_length, const int debug_print) { int i; char current_mode = 'U'; - /* GS1 raw text dealt with by `ZBarcode_Encode_Segs()` */ - const int raw_text = (symbol->input_mode & 0x07) != GS1_MODE && (symbol->output_options & BARCODE_RAW_TEXT); - - if (raw_text && z_rt_init_segs(symbol, seg_count)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ - } + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback. + Note not updating `eci` for GS1 mode as not converted */ + const int raw_text = !gs1 && (symbol->output_options & BARCODE_RAW_TEXT); for (i = 0; i < seg_count; i++) { if (!aztec_text_process(segs[i].source, segs[i].length, bp, binary_string, gs1, gs1_bp, segs[i].eci, ¤t_mode, &bp, debug_print)) { return ZINT_ERROR_TOO_LONG; /* `aztec_text_process()` only fails with too long */ } - if (raw_text && z_rt_cpy_seg(symbol, i, &segs[i])) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` only fails with OOM */ + if (raw_text && segs[i].eci) { + z_rt_set_seg_eci(symbol, i, segs[i].eci); } } diff --git a/backend/codablock.c b/backend/codablock.c index 10bf7977..5f9c1eb7 100644 --- a/backend/codablock.c +++ b/backend/codablock.c @@ -566,7 +566,7 @@ INTERNAL int zint_codablockf(struct zint_symbol *symbol, unsigned char source[], if (symbol->border_width == 0) { /* Allow override if non-zero */ symbol->border_width = 1; /* AIM ISS-X-24 Section 4.6.1 b) (note change from previous default 2) */ } - z_hrt_cpy_nochk(symbol, (const unsigned char *) "", 0); /* Zap HRT for compatibility with CODABLOCKF */ + z_hrt_cpy_nochk(symbol, ZCUCP(""), 0); /* Zap HRT for compatibility with CODABLOCKF */ /* Use `raw_text` from `zint_code128()` */ if (symbol->output_options & COMPLIANT_HEIGHT) { /* AIM ISS-X-24 Section 4.6.1 minimum row height 8X (for compatibility with CODABLOCKF, not specced @@ -603,7 +603,7 @@ INTERNAL int zint_codablockf(struct zint_symbol *symbol, unsigned char source[], } /* Replace all Codes>127 with Code-128 */ for (charCur = 0; charCur < length; charCur++) { - if (source[charCur] > 127) { + if (!z_isascii(source[charCur])) { data[dataLength++] = aFNC4; data[dataLength++] = (unsigned char) (source[charCur] & 127); } else @@ -882,8 +882,14 @@ INTERNAL int zint_codablockf(struct zint_symbol *symbol, unsigned char source[], symbol->border_width = 1; /* AIM ISS-X-24 Section 4.6.1 b) (note change from previous default 2) */ } - if (raw_text && z_rt_cpy(symbol, source, length)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy()` only fails with OOM */ + if (raw_text) { + if ((symbol->input_mode & 0x07) == DATA_MODE) { + if (z_rt_cpy(symbol, source, length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_cpy()` only fails with OOM */ + } + } else if (z_rt_cpy_iso8859_1(symbol, source, length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_cpy_iso8859_1()` only fails with OOM */ + } } return error_number; diff --git a/backend/code1.c b/backend/code1.c index faa4143f..a331e8c1 100644 --- a/backend/code1.c +++ b/backend/code1.c @@ -981,17 +981,14 @@ static int c1_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co unsigned int target[], int *p_data_length, int *p_last_mode) { int i; int tp = 0; - /* GS1 raw text dealt with by `ZBarcode_Encode_Segs()` */ + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback. + Note not updating `eci` for GS1 mode as not converted (and ignored & not written anyway) */ const int raw_text = !gs1 && (symbol->output_options & BARCODE_RAW_TEXT); - if (raw_text && z_rt_init_segs(symbol, seg_count)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ - } - for (i = 0; i < seg_count; i++) { tp = c1_encode(symbol, segs[i].source, segs[i].length, segs[i].eci, seg_count, gs1, target, &tp, p_last_mode); - if (raw_text && z_rt_cpy_seg(symbol, i, &segs[i])) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` only fails with OOM */ + if (raw_text && segs[i].eci) { + z_rt_set_seg_eci(symbol, i, segs[i].eci); } } @@ -1073,7 +1070,6 @@ INTERNAL int zint_codeone(struct zint_symbol *symbol, struct zint_seg segs[], co large_uint elreg; unsigned int target[30], ecc[15]; int block_width; - const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; /* GS1 mode ignored for Version S */ if (seg_count > 1) { return z_errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 715, "Multiple segments not supported for Version S"); @@ -1109,10 +1105,6 @@ INTERNAL int zint_codeone(struct zint_symbol *symbol, struct zint_seg segs[], co printf("Subversion: %d\n", sub_version); } - if (raw_text && z_rt_cpy(symbol, segs[0].source, segs[0].length)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy()` only fails with OOM */ - } - /* Convert value plus one to binary */ zint_large_load_str_u64(&elreg, segs[0].source, segs[0].length); zint_large_add_u64(&elreg, 1); @@ -1152,6 +1144,8 @@ INTERNAL int zint_codeone(struct zint_symbol *symbol, struct zint_seg segs[], co symbol->rows = 8; symbol->width = 10 * sub_version + 1; + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, and `eci` feedback can't change as numeric only */ + } else if (symbol->option_2 == 10) { /* Version T */ unsigned int target[C1_MAX_CWS + C1_MAX_ECCS]; /* Use same buffer size as A to H to avail of loop checks */ diff --git a/backend/code128.c b/backend/code128.c index a5024985..975da73f 100644 --- a/backend/code128.c +++ b/backend/code128.c @@ -497,8 +497,14 @@ INTERNAL int zint_code128(struct zint_symbol *symbol, unsigned char source[], in } error_number = z_hrt_cpy_iso8859_1(symbol, src, length); /* Returns warning only */ - if (raw_text && z_rt_cpy(symbol, src, length)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy()` only fails with OOM */ + if (raw_text) { + if ((symbol->input_mode & 0x07) == DATA_MODE) { + if (z_rt_cpy(symbol, src, length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_cpy()` only fails with OOM */ + } + } else if (z_rt_cpy_iso8859_1(symbol, src, length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_cpy_iso8859_1()` only fails with OOM */ + } } return error_number; diff --git a/backend/code16k.c b/backend/code16k.c index e0c03fe7..8331430a 100644 --- a/backend/code16k.c +++ b/backend/code16k.c @@ -593,8 +593,14 @@ INTERNAL int zint_code16k(struct zint_symbol *symbol, unsigned char source[], in symbol->border_width = 1; /* BS EN 12323:2005 Section 4.3.7 minimum (note change from previous default 2) */ } - if (raw_text && z_rt_cpy(symbol, source, length)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy()` only fails with OOM */ + if (raw_text) { + if ((symbol->input_mode & 0x07) == DATA_MODE) { + if (z_rt_cpy(symbol, source, length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_cpy()` only fails with OOM */ + } + } else if (z_rt_cpy_iso8859_1(symbol, source, length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_cpy_iso8859_1()` only fails with OOM */ + } } return error_number; diff --git a/backend/common.c b/backend/common.c index b89bad6c..507f6809 100644 --- a/backend/common.c +++ b/backend/common.c @@ -946,7 +946,7 @@ INTERNAL void z_rt_free_segs(struct zint_symbol *symbol) { } /* Helper to initialize `raw_segs[seg_idx]` to receive text of `length` */ -static int z_rt_init_seg_source(struct zint_symbol *symbol, const int seg_idx, const int length) { +static int rt_init_seg_source(struct zint_symbol *symbol, const int seg_idx, const int length) { assert(symbol->raw_segs); assert(seg_idx >= 0 && seg_idx < symbol->raw_seg_count); assert(!symbol->raw_segs[seg_idx].source); @@ -958,44 +958,41 @@ static int z_rt_init_seg_source(struct zint_symbol *symbol, const int seg_idx, c return 0; } -/* Copy `seg` to raw seg `seg_idx`. If `seg->eci` not set, raw seg eci set to 3. On error sets `errtxt`, returning - BARCODE_ERROR_MEMORY */ -INTERNAL int z_rt_cpy_seg(struct zint_symbol *symbol, const int seg_idx, const struct zint_seg *seg) { - if (z_rt_init_seg_source(symbol, seg_idx, seg->length)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_seg_source()` only fails with OOM */ +/* Copy `segs` to raw segs. Seg source copied as-is. If seg length <= 0, raw reg length set to `strlen()`. + If seg eci not set, raw seg eci set to 3. On error sets `errxtxt`, returning BARCODE_ERROR_MEMORY */ +INTERNAL int z_rt_cpy_segs(struct zint_symbol *symbol, const struct zint_seg segs[], const int seg_count) { + int seg_idx; + + assert(!symbol->raw_segs); /* Trap unintended double setting */ + if (z_rt_init_segs(symbol, seg_count)) { + return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ + } + for (seg_idx = 0; seg_idx < seg_count; seg_idx++) { + const struct zint_seg *const seg = segs + seg_idx; + const int length = seg->length > 0 ? seg->length : (int) z_ustrlen(seg->source); + if (rt_init_seg_source(symbol, seg_idx, length)) { + return ZINT_ERROR_MEMORY; /* `rt_init_seg_source()` only fails with OOM */ + } + memcpy(symbol->raw_segs[seg_idx].source, seg->source, (size_t) length); + symbol->raw_segs[seg_idx].length = length; + symbol->raw_segs[seg_idx].eci = seg->eci ? seg->eci : 3; } - memcpy(symbol->raw_segs[seg_idx].source, seg->source, (size_t) seg->length); - symbol->raw_segs[seg_idx].length = seg->length; - symbol->raw_segs[seg_idx].eci = seg->eci ? seg->eci : 3; return 0; } -/* Copy `seg` to raw seg `seg_idx` using `ddata` converted to chars as source. If `eci` set, used instead of - `seg->eci`, and if neither set, sets raw seg eci to 3. On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ -INTERNAL int z_rt_cpy_seg_ddata(struct zint_symbol *symbol, const int seg_idx, const struct zint_seg *seg, - const int eci, const unsigned int *ddata) { - unsigned char *s; - int i; - - if (z_rt_init_seg_source(symbol, seg_idx, seg->length * 2)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_seg_source()` only fails with OOM */ - } - for (i = 0, s = symbol->raw_segs[seg_idx].source; i < seg->length; i++) { - if (ddata[i] & 0xFF00) { - *s++ = (unsigned char) ((ddata[i] >> 8) & 0xFF); - } - *s++ = (unsigned char) (ddata[i] & 0xFF); - } - symbol->raw_segs[seg_idx].length = (int) (s - symbol->raw_segs[seg_idx].source); - symbol->raw_segs[seg_idx].eci = eci ? eci : seg->eci ? seg->eci : 3; - return 0; +/* Update the ECI of raw seg `seg_idx` to `eci`, to reflect (feedback) the actual ECI used */ +INTERNAL void z_rt_set_seg_eci(struct zint_symbol *symbol, const int seg_idx, const int eci) { + assert(symbol->raw_segs); + assert(seg_idx >= 0 && seg_idx < symbol->raw_seg_count); + symbol->raw_segs[seg_idx].eci = eci; } /* Copy `source` to raw seg 0 buffer, setting raw seg ECI to 3. On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ INTERNAL int z_rt_cpy(struct zint_symbol *symbol, const unsigned char source[], const int length) { - if (z_rt_init_segs(symbol, 1 /*seg_count*/) || z_rt_init_seg_source(symbol, 0 /*seg_idx*/, length)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `z_rt_init_seg_source()` only fail with OOM */ + assert(!symbol->raw_segs); /* Trap unintended double setting */ + if (z_rt_init_segs(symbol, 1 /*seg_count*/) || rt_init_seg_source(symbol, 0 /*seg_idx*/, length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `rt_init_seg_source()` only fail with OOM */ } memcpy(symbol->raw_segs[0].source, source, (size_t) length); symbol->raw_segs[0].length = length; @@ -1010,8 +1007,9 @@ INTERNAL int z_rt_cpy_cat(struct zint_symbol *symbol, const unsigned char source unsigned char *s; const int total_length = (length > 0 ? length : 0) + z_isascii(separator) + (cat_length > 0 ? cat_length : 0); - if (z_rt_init_segs(symbol, 1 /*seg_count*/) || z_rt_init_seg_source(symbol, 0 /*seg_idx*/, total_length)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `z_rt_init_seg_source()` only fail with OOM */ + assert(!symbol->raw_segs); /* Trap unintended double setting */ + if (z_rt_init_segs(symbol, 1 /*seg_count*/) || rt_init_seg_source(symbol, 0 /*seg_idx*/, total_length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `rt_init_seg_source()` only fail with OOM */ } s = symbol->raw_segs[0].source; if (length > 0) { @@ -1029,14 +1027,51 @@ INTERNAL int z_rt_cpy_cat(struct zint_symbol *symbol, const unsigned char source return 0; } +/* Convert ISO/IEC 8859-1 (binary) `source` to UTF-8, and copy to raw seg 0 buffer, setting raw seg ECI to 3. + On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ +INTERNAL int z_rt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char source[], const int length) { + int i; + int iso_cnt = 0; + unsigned char *s; + + assert(!symbol->raw_segs); /* Trap unintended double setting */ + for (i = 0; i < length; i++) { + iso_cnt += !z_isascii(source[i]); + } + + if (z_rt_init_segs(symbol, 1 /*seg_count*/) || rt_init_seg_source(symbol, 0 /*seg_idx*/, length + iso_cnt)) { + return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `rt_init_seg_source()` only fail with OOM */ + } + s = symbol->raw_segs[0].source; + + for (i = 0; i < length; i++) { + if (z_isascii(source[i])) { + *s++ = source[i]; + } else if (source[i] < 0xC0) { /* Including < 0xA0, i.e. treating as binary */ + *s++ = 0xC2; + *s++ = source[i]; + } else { + *s++ = 0xC3; + *s++ = source[i] - 0x40; + } + } + assert((int) (s - symbol->raw_segs[0].source) == length + iso_cnt); + + symbol->raw_segs[0].length = length + iso_cnt; + symbol->raw_segs[0].eci = 3; + + return 0; +} + /* `sprintf()` into raw seg 0 buffer, assuming formatted data less than 256 bytes. Sets raw seg ECI to 3. On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ INTERNAL int z_rt_printf_256(struct zint_symbol *symbol, const char *fmt, ...) { va_list ap; int size; - if (z_rt_init_segs(symbol, 1 /*seg_count*/) || z_rt_init_seg_source(symbol, 0 /*seg_idx*/, 256)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `z_rt_init_seg_source()` only fail with OOM */ + assert(!symbol->raw_segs); /* Trap unintended double setting */ + if (z_rt_init_segs(symbol, 1 /*seg_count*/) || rt_init_seg_source(symbol, 0 /*seg_idx*/, 256)) { + return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `rt_init_seg_source()` only fail with OOM */ } va_start(ap, fmt); diff --git a/backend/common.h b/backend/common.h index fda705ed..7e900aa5 100644 --- a/backend/common.h +++ b/backend/common.h @@ -140,7 +140,7 @@ typedef unsigned __int64 uint64_t; #define z_isdigit(c) ((c) <= '9' && (c) >= '0') #define z_isupper(c) ((c) >= 'A' && (c) <= 'Z') #define z_islower(c) ((c) >= 'a' && (c) <= 'z') -#define z_isascii(c) (((c) & 0x7F) == (c)) +#define z_isascii(c) (!((c) & ~0x7F)) #define z_iscntrl(c) (z_isascii(c) && ((c) < 32 || (c) == 127)) /* Shorthands to cast away char pointer signedness */ @@ -306,6 +306,7 @@ INTERNAL int z_is_valid_utf8(const unsigned char source[], const int length); INTERNAL int z_utf8_to_unicode(struct zint_symbol *symbol, const unsigned char source[], unsigned int vals[], int *length, const int disallow_4byte); + /* Treats source as ISO/IEC 8859-1 and copies into `symbol->text`, converting to UTF-8. Control chars (incl. DEL) and non-ISO/IEC 8859-1 (0x80-9F) are replaced with spaces. Returns warning if truncated, else 0 */ INTERNAL int z_hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char source[], const int length); @@ -341,14 +342,12 @@ INTERNAL int z_rt_init_segs(struct zint_symbol *symbol, const int seg_count); /* Free `raw_segs` along with any `source` buffers */ INTERNAL void z_rt_free_segs(struct zint_symbol *symbol); -/* Copy `seg` to raw seg `seg_idx`. If `seg->eci` not set, raw seg eci set to 3. On error sets `errtxt`, returning - BARCODE_ERROR_MEMORY */ -INTERNAL int z_rt_cpy_seg(struct zint_symbol *symbol, const int seg_idx, const struct zint_seg *seg); +/* Copy `segs` to raw segs. Seg source copied as-is. If seg length <= 0, raw reg length set to `strlen()`. + If seg eci not set, raw seg eci set to 3. On error sets `errxtxt`, returning BARCODE_ERROR_MEMORY */ +INTERNAL int z_rt_cpy_segs(struct zint_symbol *symbol, const struct zint_seg segs[], const int seg_count); -/* Copy `seg` to raw seg `seg_idx` using `ddata` converted to chars as source. If `eci` set, used instead of - `seg->eci`, and if neither set, sets raw seg eci to 3. On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ -INTERNAL int z_rt_cpy_seg_ddata(struct zint_symbol *symbol, const int seg_idx, const struct zint_seg *seg, - const int eci, const unsigned int *ddata); +/* Update the ECI of raw seg `seg_idx` to `eci`, to reflect (feedback) the actual ECI used */ +INTERNAL void z_rt_set_seg_eci(struct zint_symbol *symbol, const int seg_idx, const int eci); /* Copy `source` to raw seg 0 buffer, setting raw seg ECI to 3. On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ @@ -359,6 +358,10 @@ INTERNAL int z_rt_cpy(struct zint_symbol *symbol, const unsigned char source[], INTERNAL int z_rt_cpy_cat(struct zint_symbol *symbol, const unsigned char source[], const int length, const char separator, const unsigned char cat[], const int cat_length); +/* Convert ISO/IEC 8859-1 (binary) `source` to UTF-8, and copy to raw seg 0 buffer, setting raw seg ECI to 3. + On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ +INTERNAL int z_rt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char source[], const int length); + /* `sprintf()` into raw seg 0 buffer, assuming formatted data less than 256 bytes. Sets raw seg ECI to 3. On error sets `errtxt`, returning BARCODE_ERROR_MEMORY */ INTERNAL int z_rt_printf_256(struct zint_symbol *symbol, const char *fmt, ...) ZINT_FORMAT_PRINTF(2, 3); diff --git a/backend/dmatrix.c b/backend/dmatrix.c index 03964f96..a760fe1b 100644 --- a/backend/dmatrix.c +++ b/backend/dmatrix.c @@ -974,7 +974,7 @@ static void dm_addEdges(struct zint_symbol *symbol, const unsigned char source[] } /* Calculate optimized encoding modes */ -static int dm_define_mode(struct zint_symbol *symbol, char modes[], const unsigned char source[], const int length, +static int dm_define_modes(struct zint_symbol *symbol, char modes[], const unsigned char source[], const int length, const int last_seg, const int gs1, const int debug_print) { int i, j, v_i; @@ -1062,7 +1062,7 @@ static int dm_minimalenc(struct zint_symbol *symbol, const unsigned char source[ assert(length <= 10921); /* Can only handle (10921 + 1) * 6 = 65532 < 65536 (2*16) due to sizeof(previous) */ - if (!dm_define_mode(symbol, modes, source, length, last_seg, gs1, debug_print)) { + if (!dm_define_modes(symbol, modes, source, length, last_seg, gs1, debug_print)) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 728, "Insufficient memory for mode buffers"); } @@ -1684,11 +1684,13 @@ static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co int error_number; int i; int tp = 0; - int gs1; int in_macro = 0; const struct zint_seg *last_seg = &segs[seg_count - 1]; - /* GS1 raw text dealt with by `ZBarcode_Encode_Segs()` */ - const int raw_text = (symbol->input_mode & 0x07) != GS1_MODE && (symbol->output_options & BARCODE_RAW_TEXT); + /* gs1 flag values: 0: no GS1, 1: GS1 with FNC1 serparator, 2: GS separator */ + const int gs1 = (symbol->input_mode & 0x07) == GS1_MODE ? 1 + !!(symbol->output_options & GS1_GS_SEPARATOR) : 0; + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback. + Note not updating `eci` for GS1 mode as not converted */ + const int raw_text = !gs1 && (symbol->output_options & BARCODE_RAW_TEXT); const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; if ((i = z_segs_length(segs, seg_count)) > 3116) { /* Max is 3166 digits */ @@ -1751,17 +1753,6 @@ static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co target[tp++] = id2; } - /* gs1 flag values: 0: no gs1, 1: gs1 with FNC1 serparator, 2: GS separator */ - if ((symbol->input_mode & 0x07) == GS1_MODE) { - if (symbol->output_options & GS1_GS_SEPARATOR) { - gs1 = 2; - } else { - gs1 = 1; - } - } else { - gs1 = 0; - } - if (gs1) { target[tp++] = 232; if (debug_print) fputs("FN1 ", stdout); @@ -1802,10 +1793,6 @@ static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co in_macro = 1; } - if (raw_text && z_rt_init_segs(symbol, seg_count)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ - } - for (i = 0; i < seg_count; i++) { int src_inc = 0, len_dec = 0; if (in_macro) { @@ -1821,8 +1808,8 @@ static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co assert(error_number >= ZINT_ERROR); return error_number; } - if (raw_text && z_rt_cpy_seg(symbol, i, &segs[i])) { /* Note including macro header and RS + EOT */ - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` only fails with OOM */ + if (raw_text && segs[i].eci) { + z_rt_set_seg_eci(symbol, i, segs[i].eci); } } diff --git a/backend/dotcode.c b/backend/dotcode.c index 93a0e2cf..5085b0f5 100644 --- a/backend/dotcode.c +++ b/backend/dotcode.c @@ -982,7 +982,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou } /* Call `dc_encode_message()` for each segment */ -static int dc_encode_message_segs(struct zint_symbol *symbol, const struct zint_seg segs[], const int seg_count, +static void dc_encode_message_segs(struct zint_symbol *symbol, const struct zint_seg segs[], const int seg_count, unsigned char *codeword_array, int *p_binary_finish, int *p_data_length, unsigned char structapp_array[], int *p_structapp_size) { int i; @@ -994,7 +994,8 @@ static int dc_encode_message_segs(struct zint_symbol *symbol, const struct zint_ int inside_macro = 0; uint64_t bin_buf = 0; int bin_buf_size = 0; - /* GS1 raw text dealt with by `ZBarcode_Encode_Segs()` */ + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback. + Note not updating `eci` for GS1 mode as not converted */ const int raw_text = (symbol->input_mode & 0x07) != GS1_MODE && (symbol->output_options & BARCODE_RAW_TEXT); const struct zint_seg *last_seg = &segs[seg_count - 1]; @@ -1004,23 +1005,17 @@ static int dc_encode_message_segs(struct zint_symbol *symbol, const struct zint_ last_RSEOT = last_seg->source[last_seg->length - 2] == 30; /* RS */ } - if (raw_text && z_rt_init_segs(symbol, seg_count)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ - } - for (i = 0; i < seg_count; i++) { ap = dc_encode_message(symbol, segs[i].source, segs[i].length, segs[i].eci, i == seg_count - 1 /*last_seg*/, last_EOT, last_RSEOT, ap, codeword_array, &encoding_mode, &inside_macro, &bin_buf, &bin_buf_size, structapp_array, p_structapp_size); - if (raw_text && z_rt_cpy_seg(symbol, i, &segs[i])) { /* Note including macro header and RS + EOT */ - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` only fails with OOM */ + if (raw_text && segs[i].eci) { + z_rt_set_seg_eci(symbol, i, segs[i].eci); } } *p_binary_finish = encoding_mode == 'X'; *p_data_length = ap + *p_structapp_size; - - return 0; } /* Convert codewords to binary data stream */ @@ -1267,10 +1262,8 @@ INTERNAL int zint_dotcode(struct zint_symbol *symbol, struct zint_seg segs[], co } } - if (dc_encode_message_segs(symbol, segs, seg_count, codeword_array, &binary_finish, &data_length, - structapp_array, &structapp_size)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` etc. only fail with OOM */ - } + dc_encode_message_segs(symbol, segs, seg_count, codeword_array, &binary_finish, &data_length, structapp_array, + &structapp_size); /* Suppresses clang-tidy clang-analyzer-core.UndefinedBinaryOperatorResult/uninitialized.ArraySubscript * warnings */ diff --git a/backend/eci.c b/backend/eci.c index d653811a..12372d11 100644 --- a/backend/eci.c +++ b/backend/eci.c @@ -913,20 +913,15 @@ INTERNAL void zint_sjis_cpy(const unsigned char source[], int *p_length, unsigne } /* Call `zint_sjis_cpy()` for each segment */ -INTERNAL int zint_sjis_cpy_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, - unsigned int *ddata, const int full_multibyte) { +INTERNAL void zint_sjis_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata, + const int full_multibyte) { int i; unsigned int *dd = ddata; - const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; /* Note only called for DATA_MODE */ for (i = 0; i < seg_count; i++) { zint_sjis_cpy(segs[i].source, &segs[i].length, dd, full_multibyte); - if (raw_text && z_rt_cpy_seg_ddata(symbol, i, &segs[i], 0 /*eci*/, dd)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg_ddata()` only fails with OOM */ - } dd += segs[i].length; } - return 0; } /* Convert UTF-8 string to ECI and place in array of ints using `zint_sjis_cpy()` */ @@ -1020,21 +1015,20 @@ INTERNAL void zint_test_gb2312_cpy(const unsigned char source[], int *p_length, #endif /* Call `gb2312_cpy()` for each segment */ -INTERNAL int zint_gb2312_cpy_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, +INTERNAL void zint_gb2312_cpy_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, unsigned int *ddata, const int full_multibyte) { int i; unsigned int *dd = ddata; const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; for (i = 0; i < seg_count; i++) { - const int eci = segs[i].eci ? segs[i].eci : 29; /* Need to set as `z_rt_cpy_seg_ddata()` defaults to 3 */ gb2312_cpy(segs[i].source, &segs[i].length, dd, full_multibyte); - if (raw_text && z_rt_cpy_seg_ddata(symbol, i, &segs[i], eci, dd)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg_ddata()` only fails with OOM */ + if (raw_text) { + /* Need to set as `z_rt_cpy_segs()` defaults to 3 */ + z_rt_set_seg_eci(symbol, i, segs[i].eci ? segs[i].eci : 29); } dd += segs[i].length; } - return 0; } /* Convert UTF-8 string to ECI and place in array of ints using `gb2312_cpy()` */ @@ -1145,20 +1139,15 @@ INTERNAL void zint_test_gb18030_cpy(const unsigned char source[], int *p_length, #endif /* Call `gb18030_cpy()` for each segment */ -INTERNAL int zint_gb18030_cpy_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, - unsigned int *ddata, const int full_multibyte) { +INTERNAL void zint_gb18030_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata, + const int full_multibyte) { int i; unsigned int *dd = ddata; - const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; for (i = 0; i < seg_count; i++) { gb18030_cpy(segs[i].source, &segs[i].length, dd, full_multibyte); - if (raw_text && z_rt_cpy_seg_ddata(symbol, i, &segs[i], 0 /*eci*/, dd)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg_ddata()` only fails with OOM */ - } dd += segs[i].length; } - return 0; } /* Convert UTF-8 string to ECI and place in array of ints using `gb18030_cpy()` */ diff --git a/backend/eci.h b/backend/eci.h index 0d05b491..28b2b861 100644 --- a/backend/eci.h +++ b/backend/eci.h @@ -53,15 +53,15 @@ INTERNAL int zint_sjis_utf8(struct zint_symbol *symbol, const unsigned char sour unsigned int *ddata); INTERNAL void zint_sjis_cpy(const unsigned char source[], int *p_length, unsigned int *ddata, const int full_multibyte); -INTERNAL int zint_sjis_cpy_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, - unsigned int *ddata, const int full_multibyte); +INTERNAL void zint_sjis_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata, + const int full_multibyte); INTERNAL int zint_sjis_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *ddata, const int full_multibyte); /* GRIDMATRIX GB 2312 helpers */ INTERNAL int zint_gb2312_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length, unsigned int *ddata); -INTERNAL int zint_gb2312_cpy_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, +INTERNAL void zint_gb2312_cpy_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, unsigned int *ddata, const int full_multibyte); INTERNAL int zint_gb2312_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *ddata, const int full_multibyte); @@ -69,8 +69,8 @@ INTERNAL int zint_gb2312_utf8_to_eci(const int eci, const unsigned char source[] /* HANXIN GB 18030 helpers */ INTERNAL int zint_gb18030_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length, unsigned int *ddata); -INTERNAL int zint_gb18030_cpy_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, - unsigned int *ddata, const int full_multibyte); +INTERNAL void zint_gb18030_cpy_segs(struct zint_seg segs[], const int seg_count, unsigned int *ddata, + const int full_multibyte); INTERNAL int zint_gb18030_utf8_to_eci(const int eci, const unsigned char source[], int *p_length, unsigned int *ddata, const int full_multibyte); diff --git a/backend/gridmtx.c b/backend/gridmtx.c index fcb24db1..5304168e 100644 --- a/backend/gridmtx.c +++ b/backend/gridmtx.c @@ -43,7 +43,7 @@ static const char EUROPIUM[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl static const char EUROPIUM_UPR[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "; static const char EUROPIUM_LWR[] = "abcdefghijklmnopqrstuvwxyz "; -/* gm_define_mode() stuff */ +/* gm_define_modes() stuff */ /* Bits multiplied by this for costs, so as to be whole integer divisible by 2 and 3 */ #define GM_MULT 6 @@ -126,7 +126,7 @@ static int gm_in_numeral(const unsigned int ddata[], const int length, const int /* Calculate optimized encoding modes. Adapted from Project Nayuki */ /* Copyright (c) Project Nayuki. (MIT License) See qr.c for detailed notice */ -static void gm_define_mode(char *mode, const unsigned int ddata[], const int length, const int debug_print) { +static void gm_define_modes(char *modes, const unsigned int ddata[], const int length, const int debug_print) { /* Must be in same order as GM_H etc */ static const char mode_types[] = { GM_CHINESE, GM_NUMBER, GM_LOWER, GM_UPPER, GM_MIXED, GM_BYTE, '\0' }; @@ -281,11 +281,11 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len for (i = length - 1; i >= 0; i--) { j = z_posn(mode_types, cur_mode); cur_mode = char_modes[i][j]; - mode[i] = cur_mode; + modes[i] = cur_mode; } if (debug_print) { - printf(" Mode: %.*s\n", length, mode); + printf(" Modes: %.*s\n", length, modes); } } @@ -338,7 +338,7 @@ static int gm_encode(unsigned int ddata[], const int length, char binary[], cons int byte_count = 0; int shift; int bp = *p_bp; - char *mode = (char *) z_alloca(length); + char *modes = (char *) z_alloca(length); if (eci != 0) { /* ECI assignment according to Table 8 */ @@ -354,10 +354,10 @@ static int gm_encode(unsigned int ddata[], const int length, char binary[], cons } } - gm_define_mode(mode, ddata, length, debug_print); + gm_define_modes(modes, ddata, length, debug_print); do { - const int next_mode = mode[sp]; + const int next_mode = modes[sp]; if (next_mode != current_mode) { switch (current_mode) { @@ -539,7 +539,7 @@ static int gm_encode(unsigned int ddata[], const int length, char binary[], cons break; } sp++; - } while (p < 3 && sp < length && mode[sp] == GM_NUMBER); + } while (p < 3 && sp < length && modes[sp] == GM_NUMBER); if (ppos != -1) { switch (punt) { @@ -986,6 +986,7 @@ INTERNAL int zint_gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], const struct zint_structapp *p_structapp = NULL; int size_squared; int bin_len; + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback */ const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; const int eci_length_segs = zint_get_eci_length_segs(segs, seg_count); @@ -998,14 +999,8 @@ INTERNAL int zint_gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], /* If ZINT_FULL_MULTIBYTE set use Hanzi mode in DATA_MODE or for non-GB 2312 in UNICODE_MODE */ full_multibyte = (symbol->option_3 & 0xFF) == ZINT_FULL_MULTIBYTE; - if (raw_text && z_rt_init_segs(symbol, seg_count)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ - } - if ((symbol->input_mode & 0x07) == DATA_MODE) { - if (zint_gb2312_cpy_segs(symbol, local_segs, seg_count, ddata, full_multibyte)) { - return ZINT_ERROR_MEMORY; /* `zint_gb18030_cpy_segs()` only fails with OOM */ - } + zint_gb2312_cpy_segs(symbol, local_segs, seg_count, ddata, full_multibyte); } else { unsigned int *dd = ddata; for (i = 0; i < seg_count; i++) { @@ -1029,8 +1024,8 @@ INTERNAL int zint_gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], } eci = 29; } - if (raw_text && z_rt_cpy_seg_ddata(symbol, i, &local_segs[i], eci, dd)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg_ddata()` only fails with OOM */ + if (raw_text && eci) { + z_rt_set_seg_eci(symbol, i, eci); } dd += local_segs[i].length; } diff --git a/backend/hanxin.c b/backend/hanxin.c index 4e04fc87..a8c3dbba 100644 --- a/backend/hanxin.c +++ b/backend/hanxin.c @@ -82,7 +82,7 @@ static int hx_terminator_length(const char mode) { } /* Calculate the length of the binary string */ -static int hx_calc_binlen(const char mode[], const unsigned int ddata[], const int length, const int eci) { +static int hx_calc_binlen(const char modes[], const unsigned int ddata[], const int length, const int eci) { int i; char lastmode = '\0'; int est_binlen = 0; @@ -102,23 +102,23 @@ static int hx_calc_binlen(const char mode[], const unsigned int ddata[], const i i = 0; do { - if (mode[i] != lastmode) { + if (modes[i] != lastmode) { if (i > 0) { est_binlen += hx_terminator_length(lastmode); } /* GB 4-byte has indicator for each character (and no terminator) so not included here */ /* Region1/Region2 have special terminator to go directly into each other's mode so not included here */ - if (mode[i] != 'f' || (mode[i] == '1' && lastmode == '2') || (mode[i] == '2' && lastmode == '1')) { + if (modes[i] != 'f' || (modes[i] == '1' && lastmode == '2') || (modes[i] == '2' && lastmode == '1')) { est_binlen += 4; } - if (mode[i] == 'b') { /* Byte mode has byte count (and no terminator) */ + if (modes[i] == 'b') { /* Byte mode has byte count (and no terminator) */ est_binlen += 13; } - lastmode = mode[i]; + lastmode = modes[i]; submode = 1; numeric_run = 0; } - switch (mode[i]) { + switch (modes[i]) { case 'n': if (numeric_run % 3 == 0) { est_binlen += 10; @@ -156,16 +156,16 @@ static int hx_calc_binlen(const char mode[], const unsigned int ddata[], const i } /* Call `hx_calc_binlen()` for each segment */ -static int hx_calc_binlen_segs(const char mode[], const unsigned int ddata[], const struct zint_seg segs[], +static int hx_calc_binlen_segs(const char modes[], const unsigned int ddata[], const struct zint_seg segs[], const int seg_count) { int i; int count = 0; const unsigned int *dd = ddata; - const char *m = mode; + const char *mds = modes; for (i = 0; i < seg_count; i++) { - count += hx_calc_binlen(m, dd, segs[i].length, segs[i].eci); - m += segs[i].length; + count += hx_calc_binlen(mds, dd, segs[i].length, segs[i].eci); + mds += segs[i].length; dd += segs[i].length; } @@ -292,7 +292,7 @@ static int hx_lookup_text2(const unsigned int input) { return -1; } -/* hx_define_mode() stuff */ +/* hx_define_modes() stuff */ /* Bits multiplied by this for costs, so as to be whole integer divisible by 2 and 3 */ #define HX_MULT 6 @@ -353,7 +353,7 @@ static int hx_in_fourbyte(const unsigned int ddata[], const int length, const in /* Calculate optimized encoding modes. Adapted from Project Nayuki */ /* Copyright (c) Project Nayuki. (MIT License) See qr.c for detailed notice */ -static void hx_define_mode(char *mode, const unsigned int ddata[], const int length, const int debug_print) { +static void hx_define_modes(char *modes, const unsigned int ddata[], const int length, const int debug_print) { /* Must be in same order as HX_N etc */ static const char mode_types[] = { 'n', 't', 'b', '1', '2', 'd', 'f', '\0' }; @@ -484,30 +484,30 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len for (i = length - 1; i >= 0; i--) { j = z_posn(mode_types, cur_mode); cur_mode = char_modes[i][j]; - mode[i] = cur_mode; + modes[i] = cur_mode; } if (debug_print) { - printf(" Mode: %.*s\n", length, mode); + printf(" Modes: %.*s\n", length, modes); } } -/* Call `hx_define_mode()` for each segment */ -static void hx_define_mode_segs(char mode[], const unsigned int ddata[], const struct zint_seg segs[], +/* Call `hx_define_modes()` for each segment */ +static void hx_define_modes_segs(char modes[], const unsigned int ddata[], const struct zint_seg segs[], const int seg_count, const int debug_print) { int i; const unsigned int *dd = ddata; - char *m = mode; + char *mds = modes; for (i = 0; i < seg_count; i++) { - hx_define_mode(m, dd, segs[i].length, debug_print); - m += segs[i].length; + hx_define_modes(mds, dd, segs[i].length, debug_print); + mds += segs[i].length; dd += segs[i].length; } } /* Convert input data to binary stream */ -static void hx_calculate_binary(char binary[], const char mode[], const unsigned int ddata[], const int length, +static void hx_calculate_binary(char binary[], const char modes[], const unsigned int ddata[], const int length, const int eci, int *p_bp, const int debug_print) { int position = 0; int i, count, encoding_value; @@ -535,13 +535,13 @@ static void hx_calculate_binary(char binary[], const char mode[], const unsigned int block_length = 0; int double_byte = 0; do { - if (mode[position] == 'b' && ddata[position + block_length] > 0xFF) { + if (modes[position] == 'b' && ddata[position + block_length] > 0xFF) { double_byte++; } block_length++; - } while (position + block_length < length && mode[position + block_length] == mode[position]); + } while (position + block_length < length && modes[position + block_length] == modes[position]); - switch (mode[position]) { + switch (modes[position]) { case 'n': /* Numeric mode */ /* Mode indicator */ @@ -559,12 +559,12 @@ static void hx_calculate_binary(char binary[], const char mode[], const unsigned count = 1; encoding_value = first; - if (i + 1 < block_length && mode[position + i + 1] == 'n') { + if (i + 1 < block_length && modes[position + i + 1] == 'n') { const int second = z_ctoi((const char) ddata[position + i + 1]); count = 2; encoding_value = (encoding_value * 10) + second; - if (i + 2 < block_length && mode[position + i + 2] == 'n') { + if (i + 2 < block_length && modes[position + i + 2] == 'n') { const int third = z_ctoi((const char) ddata[position + i + 2]); count = 3; encoding_value = (encoding_value * 10) + third; @@ -676,13 +676,13 @@ static void hx_calculate_binary(char binary[], const char mode[], const unsigned case '1': /* Region One encoding */ /* Mode indicator */ - if (position == 0 || mode[position - 1] != '2') { /* Unless previous mode Region Two */ + if (position == 0 || modes[position - 1] != '2') { /* Unless previous mode Region Two */ bp = z_bin_append_posn(4, 4, binary, bp); } if (debug_print) { printf("Region One%s H(1)%d:", - position == 0 || mode[position - 1] != '2' ? "" : " (NO indicator)", block_length); + position == 0 || modes[position - 1] != '2' ? "" : " (NO indicator)", block_length); } i = 0; @@ -715,11 +715,11 @@ static void hx_calculate_binary(char binary[], const char mode[], const unsigned } /* Terminator */ - bp = z_bin_append_posn(position + block_length == length || mode[position + block_length] != '2' + bp = z_bin_append_posn(position + block_length == length || modes[position + block_length] != '2' ? 4095 : 4094, 12, binary, bp); if (debug_print) { - printf(" (TERM %x)\n", position + block_length == length || mode[position + block_length] != '2' + printf(" (TERM %x)\n", position + block_length == length || modes[position + block_length] != '2' ? 4095 : 4094); } @@ -727,13 +727,13 @@ static void hx_calculate_binary(char binary[], const char mode[], const unsigned case '2': /* Region Two encoding */ /* Mode indicator */ - if (position == 0 || mode[position - 1] != '1') { /* Unless previous mode Region One */ + if (position == 0 || modes[position - 1] != '1') { /* Unless previous mode Region One */ bp = z_bin_append_posn(5, 4, binary, bp); } if (debug_print) { printf("Region Two%s H(2)%d:", - position == 0 || mode[position - 1] != '1' ? "" : " (NO indicator)", block_length); + position == 0 || modes[position - 1] != '1' ? "" : " (NO indicator)", block_length); } i = 0; @@ -753,11 +753,11 @@ static void hx_calculate_binary(char binary[], const char mode[], const unsigned } /* Terminator */ - bp = z_bin_append_posn(position + block_length == length || mode[position + block_length] != '1' + bp = z_bin_append_posn(position + block_length == length || modes[position + block_length] != '1' ? 4095 : 4094, 12, binary, bp); if (debug_print) { - printf(" (TERM %x)\n", position + block_length == length || mode[position + block_length] != '1' + printf(" (TERM %x)\n", position + block_length == length || modes[position + block_length] != '1' ? 4095 : 4094); } @@ -847,16 +847,16 @@ static void hx_calculate_binary(char binary[], const char mode[], const unsigned } /* Call `hx_calculate_binary()` for each segment */ -static void hx_calculate_binary_segs(char binary[], const char mode[], const unsigned int ddata[], +static void hx_calculate_binary_segs(char binary[], const char modes[], const unsigned int ddata[], const struct zint_seg segs[], const int seg_count, int *p_bin_len, const int debug_print) { int i; const unsigned int *dd = ddata; - const char *m = mode; + const char *mds = modes; int bp = 0; for (i = 0; i < seg_count; i++) { - hx_calculate_binary(binary, m, dd, segs[i].length, segs[i].eci, &bp, debug_print); - m += segs[i].length; + hx_calculate_binary(binary, mds, dd, segs[i].length, segs[i].eci, &bp, debug_print); + mds += segs[i].length; dd += segs[i].length; } @@ -1488,12 +1488,13 @@ INTERNAL int zint_hanxin(struct zint_symbol *symbol, struct zint_seg segs[], con int size_squared; int codewords; int bin_len; + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback */ const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; const int eci_length_segs = zint_get_eci_length_segs(segs, seg_count); struct zint_seg *local_segs = (struct zint_seg *) z_alloca(sizeof(struct zint_seg) * seg_count); unsigned int *ddata = (unsigned int *) z_alloca(sizeof(unsigned int) * eci_length_segs); - char *mode = (char *) z_alloca(eci_length_segs); + char *modes = (char *) z_alloca(eci_length_segs); char *binary; unsigned char *datastream; unsigned char *fullstream; @@ -1509,14 +1510,8 @@ INTERNAL int zint_hanxin(struct zint_symbol *symbol, struct zint_seg segs[], con user_mask = 0; /* Ignore */ } - if (raw_text && z_rt_init_segs(symbol, seg_count)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ - } - if ((symbol->input_mode & 0x07) == DATA_MODE) { - if (zint_gb18030_cpy_segs(symbol, local_segs, seg_count, ddata, full_multibyte)) { - return ZINT_ERROR_MEMORY; /* `zint_gb18030_cpy_segs()` only fails with OOM */ - } + zint_gb18030_cpy_segs(local_segs, seg_count, ddata, full_multibyte); } else { unsigned int *dd = ddata; for (i = 0; i < seg_count; i++) { @@ -1544,16 +1539,16 @@ INTERNAL int zint_hanxin(struct zint_symbol *symbol, struct zint_seg segs[], con } eci = 32; } - if (raw_text && z_rt_cpy_seg_ddata(symbol, i, &local_segs[i], eci, dd)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg_ddata()` only fails with OOM */ + if (raw_text && eci) { + z_rt_set_seg_eci(symbol, i, eci); } dd += local_segs[i].length; } } - hx_define_mode_segs(mode, ddata, local_segs, seg_count, debug_print); + hx_define_modes_segs(modes, ddata, local_segs, seg_count, debug_print); - est_binlen = hx_calc_binlen_segs(mode, ddata, local_segs, seg_count); + est_binlen = hx_calc_binlen_segs(modes, ddata, local_segs, seg_count); if (debug_print) { printf("Estimated binary length: %d\n", est_binlen); } @@ -1564,7 +1559,7 @@ INTERNAL int zint_hanxin(struct zint_symbol *symbol, struct zint_seg segs[], con ecc_level = 1; } - hx_calculate_binary_segs(binary, mode, ddata, local_segs, seg_count, &bin_len, debug_print); + hx_calculate_binary_segs(binary, modes, ddata, local_segs, seg_count, &bin_len, debug_print); codewords = bin_len >> 3; if (bin_len & 0x07) { codewords++; diff --git a/backend/library.c b/backend/library.c index 2b68ed8b..d062cc67 100644 --- a/backend/library.c +++ b/backend/library.c @@ -84,7 +84,7 @@ static void set_symbol_defaults(struct zint_symbol *symbol) { struct zint_symbol *ZBarcode_Create(void) { struct zint_symbol *symbol; - symbol = (struct zint_symbol *) calloc(1, sizeof(*symbol)); + symbol = (struct zint_symbol *) calloc(1, sizeof(*symbol)); /* Zeroizes */ if (!symbol) return NULL; set_symbol_defaults(symbol); @@ -100,6 +100,7 @@ void ZBarcode_Clear(struct zint_symbol *symbol) { if (!symbol) return; + /* Zeroize output fields */ for (i = 0; i < symbol->rows; i++) { memset(symbol->encoded_data[i], 0, sizeof(symbol->encoded_data[0])); } @@ -285,142 +286,6 @@ INTERNAL int zint_test_error_tag(int error_number, struct zint_symbol *symbol, c } #endif -/* Output a hexadecimal representation of the rendered symbol (TXT files - includes frontend "--dump" option) */ -static int txt_hex_plot(struct zint_symbol *symbol) { - static const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - struct filemem fm; - struct filemem *const fmp = &fm; - int r; - - if (!zint_fm_open(fmp, symbol, "w")) { - return ZEXT z_errtxtf(ZINT_ERROR_FILE_ACCESS, symbol, 201, "Could not open TXT output file (%1$d: %2$s)", - fmp->err, strerror(fmp->err)); - } - - for (r = 0; r < symbol->rows; r++) { - int space = 0, byt = 0; - int i; - for (i = 0; i < symbol->width; i++) { - byt <<= 1; - if (symbol->symbology == BARCODE_ULTRA) { - if (z_module_colour_is_set(symbol, r, i)) { - byt++; - } - } else { - if (z_module_is_set(symbol, r, i)) { - byt++; - } - } - if (((i + 1) & 0x3) == 0) { - zint_fm_putc(hex[byt], fmp); - space++; - byt = 0; - } - if (space == 2 && i + 1 < symbol->width) { - zint_fm_putc(' ', fmp); - space = 0; - } - } - - if (symbol->width & 0x03) { - byt <<= 4 - (symbol->width & 0x03); - zint_fm_putc(hex[byt], fmp); - } - zint_fm_putc('\n', fmp); - } - - if (zint_fm_error(fmp)) { - ZEXT z_errtxtf(0, symbol, 795, "Incomplete write of TXT output (%1$d: %2$s)", fmp->err, strerror(fmp->err)); - (void) zint_fm_close(fmp, symbol); - return ZINT_ERROR_FILE_WRITE; - } - - if (!zint_fm_close(fmp, symbol)) { - return ZEXT z_errtxtf(ZINT_ERROR_FILE_WRITE, symbol, 792, "Failure on closing TXT output file (%1$d: %2$s)", - fmp->err, strerror(fmp->err)); - } - - return 0; -} - -/* Permitted HIBC characters */ -static const char TECHNETIUM[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; /* Same as SILVER (CODE39) */ - -/* Process health industry bar code data */ -static int hibc(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { - unsigned char *source = segs[0].source; - int length = segs[0].length; - - int i; - int counter, error_number = 0; - char to_process[110 + 2 + 1]; - int posns[110]; - - /* without "+" and check: max 110 characters in HIBC 2.6 */ - if (length > 110) { - return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 202, "Input length %d too long for HIBC LIC (maximum 110)", - length); - } - z_to_upper(source, length); - if ((i = z_not_sane_lookup(TECHNETIUM, sizeof(TECHNETIUM) - 1, source, length, posns))) { - return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 203, - "Invalid character at position %d in input (alphanumerics, space and \"-.$/+%%\" only)", i); - } - - counter = 41; - for (i = 0; i < length; i++) { - counter += posns[i]; - } - counter = counter % 43; - - to_process[0] = '+'; - memcpy(to_process + 1, source, length); - to_process[++length] = TECHNETIUM[counter]; - to_process[++length] = '\0'; - - segs[0].source = (unsigned char *) to_process; - segs[0].length = length; - - if (symbol->debug & ZINT_DEBUG_PRINT) printf("HIBC processed source: %s\n", to_process); - - /* HIBC uses same `raw_text` as base symbologies */ - switch (symbol->symbology) { - case BARCODE_HIBC_128: - error_number = zint_code128(symbol, segs[0].source, segs[0].length); - z_hrt_cpy_chr(symbol, '*'); - z_hrt_cat_nochk(symbol, segs[0].source, segs[0].length); - z_hrt_cat_chr_nochk(symbol, '*'); - break; - case BARCODE_HIBC_39: - symbol->option_2 = 0; - error_number = zint_code39(symbol, segs[0].source, segs[0].length); - z_hrt_cpy_chr(symbol, '*'); - z_hrt_cat_nochk(symbol, segs[0].source, segs[0].length); - z_hrt_cat_chr_nochk(symbol, '*'); - break; - case BARCODE_HIBC_DM: - error_number = zint_datamatrix(symbol, segs, seg_count); - break; - case BARCODE_HIBC_QR: - error_number = zint_qrcode(symbol, segs, seg_count); - break; - case BARCODE_HIBC_PDF: - error_number = zint_pdf417(symbol, segs, seg_count); - break; - case BARCODE_HIBC_MICPDF: - error_number = zint_micropdf417(symbol, segs, seg_count); - break; - case BARCODE_HIBC_AZTEC: - error_number = zint_aztec(symbol, segs, seg_count); - break; - case BARCODE_HIBC_BLOCKF: - error_number = zint_codablockf(symbol, segs[0].source, segs[0].length); - break; - } - - return error_number; -} - /* Returns 1 if symbology MUST have GS1 data */ static int check_force_gs1(const int symbology) { @@ -484,6 +349,23 @@ static int supports_eci(const int symbology) { return 0; } +/* Returns 1 if symbology can encode other than ISO/IEC 8869-1 (Latin-1) */ +static int supports_non_iso8859_1(const int symbology) { + + if (supports_eci(symbology)) { + return 1; + } + + switch (symbology) { + case BARCODE_MICROQR: + case BARCODE_UPNQR: + return 1; + break; + } + + return 0; +} + /* Returns 1 if symbology supports HRT */ static int has_hrt(const int symbology) { @@ -533,6 +415,94 @@ static int has_hrt(const int symbology) { return 1; } +/* Process health industry bar code data */ +static int hibc(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { + /* Permitted HIBC characters */ + static const char TECHNETIUM[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; /* Same as SILVER (CODE39) */ + unsigned char *source = segs[0].source; + int length = segs[0].length; + + int i; + int counter, error_number = 0; + char to_process[110 + 2 + 1]; + int posns[110]; + + const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; + + /* Without "+" and check: max 110 characters in HIBC 2.6 */ + if (length > 110) { + return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 202, "Input length %d too long for HIBC LIC (maximum 110)", + length); + } + z_to_upper(source, length); + if ((i = z_not_sane_lookup(TECHNETIUM, sizeof(TECHNETIUM) - 1, source, length, posns))) { + return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 203, + "Invalid character at position %d in input (alphanumerics, space and \"-.$/+%%\" only)", i); + } + + counter = 41; + for (i = 0; i < length; i++) { + counter += posns[i]; + } + counter = counter % 43; + + to_process[0] = '+'; + memcpy(to_process + 1, source, length); + to_process[++length] = TECHNETIUM[counter]; + to_process[++length] = '\0'; + + segs[0].source = (unsigned char *) to_process; + segs[0].length = length; + assert(seg_count == 1); + + if (symbol->debug & ZINT_DEBUG_PRINT) printf("HIBC processed source: %s\n", to_process); + + /* Code 128, Code 39 & Codablock-F set `raw_text` themselves, but the others don't, so do it now */ + assert(!symbol->raw_segs); /* HIBC symbologies don't satisfy `supports_non_iso8859_1()` */ + if (raw_text && symbol->symbology != BARCODE_HIBC_128 && symbol->symbology != BARCODE_HIBC_39 + && symbol->symbology != BARCODE_HIBC_BLOCKF) { + if (z_rt_cpy_segs(symbol, segs, seg_count)) { + return error_tag(ZINT_ERROR_MEMORY, symbol, -1, NULL); /* `z_rt_cpy_segs()` only fails with OOM */ + } + } + + switch (symbol->symbology) { + case BARCODE_HIBC_128: + error_number = zint_code128(symbol, segs[0].source, segs[0].length); + z_hrt_cpy_chr(symbol, '*'); + z_hrt_cat_nochk(symbol, segs[0].source, segs[0].length); + z_hrt_cat_chr_nochk(symbol, '*'); + break; + case BARCODE_HIBC_39: + symbol->option_2 = 0; + error_number = zint_code39(symbol, segs[0].source, segs[0].length); + z_hrt_cpy_chr(symbol, '*'); + z_hrt_cat_nochk(symbol, segs[0].source, segs[0].length); + z_hrt_cat_chr_nochk(symbol, '*'); + break; + case BARCODE_HIBC_DM: + error_number = zint_datamatrix(symbol, segs, seg_count); + break; + case BARCODE_HIBC_QR: + error_number = zint_qrcode(symbol, segs, seg_count); + break; + case BARCODE_HIBC_PDF: + error_number = zint_pdf417(symbol, segs, seg_count); + break; + case BARCODE_HIBC_MICPDF: + error_number = zint_micropdf417(symbol, segs, seg_count); + break; + case BARCODE_HIBC_AZTEC: + error_number = zint_aztec(symbol, segs, seg_count); + break; + case BARCODE_HIBC_BLOCKF: + error_number = zint_codablockf(symbol, segs[0].source, segs[0].length); + break; + } + + return error_number; +} + typedef int (*barcode_src_func_t)(struct zint_symbol *, unsigned char[], int); typedef int (*barcode_seg_func_t)(struct zint_symbol *, struct zint_seg[], const int); @@ -988,7 +958,7 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ int error_number, warn_number = 0; int total_len = 0; int have_zero_eci = 0; - int escape_mode; + int escape_mode, raw_text; int i; unsigned char *local_source; struct zint_seg *local_segs; @@ -1022,6 +992,7 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ escape_mode = (symbol->input_mode & ESCAPE_MODE) || ((symbol->input_mode & EXTRA_ESCAPE_MODE) && symbol->symbology == BARCODE_CODE128); + raw_text = symbol->output_options & BARCODE_RAW_TEXT; local_segs = (struct zint_seg *) z_alloca(sizeof(struct zint_seg) * (seg_count > 0 ? seg_count : 1)); @@ -1164,6 +1135,10 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ if (symbol->rows < 0) { /* Silently defend against out-of-bounds access */ symbol->rows = 0; } + if (raw_text && symbol->rows) { /* Would only give info on last stacked */ + return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 857, + "Cannot use BARCODE_RAW_TEXT output option if stacking symbols"); + } if ((symbol->input_mode & 0x07) == GS1_MODE && !gs1_compliant(symbol->symbology)) { return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 220, "Selected symbology does not support GS1 mode"); @@ -1218,8 +1193,18 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ /* Reduce input for composite and non-forced symbologies, others (GS1_128 and DBAR_EXP based) will handle it themselves */ const int have_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 */ + } + if (have_composite || !check_force_gs1(symbol->symbology)) { - const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; unsigned char *reduced = (unsigned char *) z_alloca(local_segs[0].length + 1); int source_len = local_segs[0].length; error_number = zint_gs1_verify(symbol, local_segs[0].source, &source_len, reduced, @@ -1243,6 +1228,11 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ } else { return error_tag(ZINT_ERROR_INVALID_OPTION, symbol, 210, "Selected symbology does not support GS1 mode"); } + } else if (raw_text && supports_non_iso8859_1(symbol->symbology)) { + /* Copy these as-is. The raw seg `eci` will need to be updated individually */ + if (z_rt_cpy_segs(symbol, local_segs, seg_count)) { + return error_tag(ZINT_ERROR_MEMORY, symbol, -1, NULL); /* `z_rt_cpy_segs()` only fails with OOM */ + } } error_number = extended_or_reduced_charset(symbol, local_segs, seg_count); @@ -1272,7 +1262,10 @@ int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[ if (symbol->height < 0.5f) { /* Absolute minimum */ (void) z_set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/); } - assert(!(symbol->output_options & BARCODE_RAW_TEXT) || (symbol->raw_segs && symbol->raw_seg_count)); + assert(!(symbol->output_options & BARCODE_RAW_TEXT) + || (symbol->raw_segs && symbol->raw_seg_count && symbol->raw_segs[0].source + && ((symbol->input_mode & 0x07) == DATA_MODE + || z_is_valid_utf8(symbol->raw_segs[0].source, symbol->raw_segs[0].length)))); } return error_number; @@ -1327,6 +1320,64 @@ static int filetype_idx(const char *extension) { return i == ARRAY_SIZE(filetypes) ? -1 : i; } +/* Output a hexadecimal representation of the rendered symbol (TXT files - includes frontend "--dump" option) */ +static int txt_hex_plot(struct zint_symbol *symbol) { + static const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + struct filemem fm; + struct filemem *const fmp = &fm; + int r; + + if (!zint_fm_open(fmp, symbol, "w")) { + return ZEXT z_errtxtf(ZINT_ERROR_FILE_ACCESS, symbol, 201, "Could not open TXT output file (%1$d: %2$s)", + fmp->err, strerror(fmp->err)); + } + + for (r = 0; r < symbol->rows; r++) { + int space = 0, byt = 0; + int i; + for (i = 0; i < symbol->width; i++) { + byt <<= 1; + if (symbol->symbology == BARCODE_ULTRA) { + if (z_module_colour_is_set(symbol, r, i)) { + byt++; + } + } else { + if (z_module_is_set(symbol, r, i)) { + byt++; + } + } + if (((i + 1) & 0x3) == 0) { + zint_fm_putc(hex[byt], fmp); + space++; + byt = 0; + } + if (space == 2 && i + 1 < symbol->width) { + zint_fm_putc(' ', fmp); + space = 0; + } + } + + if (symbol->width & 0x03) { + byt <<= 4 - (symbol->width & 0x03); + zint_fm_putc(hex[byt], fmp); + } + zint_fm_putc('\n', fmp); + } + + if (zint_fm_error(fmp)) { + ZEXT z_errtxtf(0, symbol, 795, "Incomplete write of TXT output (%1$d: %2$s)", fmp->err, strerror(fmp->err)); + (void) zint_fm_close(fmp, symbol); + return ZINT_ERROR_FILE_WRITE; + } + + if (!zint_fm_close(fmp, symbol)) { + return ZEXT z_errtxtf(ZINT_ERROR_FILE_WRITE, symbol, 792, "Failure on closing TXT output file (%1$d: %2$s)", + fmp->err, strerror(fmp->err)); + } + + return 0; +} + /* Output a previously encoded symbol to file `symbol->outfile` */ int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) { int error_number; diff --git a/backend/mailmark.c b/backend/mailmark.c index 6ddeb685..fea46869 100644 --- a/backend/mailmark.c +++ b/backend/mailmark.c @@ -518,6 +518,7 @@ INTERNAL int zint_mailmark_2d(struct zint_symbol *symbol, unsigned char source[] char postcode[10]; int i; struct zint_seg segs[1]; + const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; if (length > 90) { return z_errtxtf(ZINT_ERROR_TOO_LONG, symbol, 589, "Input length %d too long (maximum 90)", length); @@ -660,6 +661,16 @@ INTERNAL int zint_mailmark_2d(struct zint_symbol *symbol, unsigned char source[] segs[0].source = local_source; segs[0].length = length; + if (raw_text) { + if ((symbol->input_mode & 0x07) == DATA_MODE) { + if (z_rt_cpy(symbol, local_source, length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_cpy()` only fails with OOM */ + } + } else if (z_rt_cpy_iso8859_1(symbol, local_source, length)) { + return ZINT_ERROR_MEMORY; /* `z_rt_cpy_iso8859_1()` only fails with OOM */ + } + } + return zint_datamatrix(symbol, segs, 1); } diff --git a/backend/maxicode.c b/backend/maxicode.c index ade9d9e3..494946a1 100644 --- a/backend/maxicode.c +++ b/backend/maxicode.c @@ -555,6 +555,7 @@ INTERNAL int zint_maxicode(struct zint_symbol *symbol, struct zint_seg segs[], c unsigned char codewords[144]; int scm_vv = -1; int structapp_cw = 0; + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback */ const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; @@ -695,12 +696,9 @@ INTERNAL int zint_maxicode(struct zint_symbol *symbol, struct zint_seg segs[], c } if (raw_text) { - if (z_rt_init_segs(symbol, seg_count)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ - } for (i = 0; i < seg_count; i++) { - if (z_rt_cpy_seg(symbol, i, &segs[i])) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` only fails with OOM */ + if (segs[i].eci) { + z_rt_set_seg_eci(symbol, i, segs[i].eci); } } } diff --git a/backend/pdf417.c b/backend/pdf417.c index ceb11c60..33e17d4f 100644 --- a/backend/pdf417.c +++ b/backend/pdf417.c @@ -920,7 +920,7 @@ static void pdf_addEdges(const unsigned char source[], const int length, const i } /* Calculate optimized encoding modes */ -static int pdf_define_mode(short liste[3][PDF_MAX_LEN], int *p_indexliste, const unsigned char source[], +static int pdf_define_modes(short liste[3][PDF_MAX_LEN], int *p_indexliste, const unsigned char source[], const int length, const int lastmode, const int debug_print) { int i, j, v_i; @@ -1040,7 +1040,7 @@ static int pdf_initial(struct zint_symbol *symbol, const unsigned char chaine[], pdf_appendix_d_encode(chaine, liste, &indexliste); } else { - if (!pdf_define_mode(liste, &indexliste, chaine, length, *p_lastmode, debug_print)) { + if (!pdf_define_modes(liste, &indexliste, chaine, length, *p_lastmode, debug_print)) { return z_errtxt(ZINT_ERROR_MEMORY, symbol, 749, "Insufficient memory for mode buffers"); } } @@ -1134,6 +1134,7 @@ static int pdf_initial_segs(struct zint_symbol *symbol, struct zint_seg segs[], int lastmode; int curtable; int tex_padded; + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback */ const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; *p_mclength = 0; @@ -1196,18 +1197,14 @@ static int pdf_initial_segs(struct zint_symbol *symbol, struct zint_seg segs[], /* Start in upper alpha - tracked across calls to `pdf_textprocess()` to allow for interleaving byte shifts */ curtable = T_ALPHA; - if (raw_text && z_rt_init_segs(symbol, seg_count)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ - } - for (i = 0; i < seg_count; i++) { if ((error_number = pdf_initial(symbol, segs[i].source, segs[i].length, segs[i].eci, is_micro, i + 1 == seg_count, &lastmode, &curtable, &tex_padded, chainemc, p_mclength))) { assert(error_number >= ZINT_ERROR); return error_number; } - if (raw_text && z_rt_cpy_seg(symbol, i, &segs[i])) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` only fails with OOM */ + if (raw_text && segs[i].eci) { + z_rt_set_seg_eci(symbol, i, segs[i].eci); } } diff --git a/backend/qr.c b/backend/qr.c index ecd553e0..bb437b12 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -149,7 +149,7 @@ static int qr_in_alpha(const unsigned int ddata[], const int length, const int i } #if 0 -#define QR_DEBUG_DEFINE_MODE /* For debugging costings */ +#define QR_DEBUG_DEFINE_MODES /* For debugging costings */ #endif /* Indexes into qr_mode_types array (and state array) */ @@ -215,7 +215,7 @@ static unsigned int *qr_head_costs(unsigned int state[11]) { } /* Calculate optimized encoding modes. Adapted from Project Nayuki */ -static void qr_define_mode(char mode[], const unsigned int ddata[], const int length, const int gs1, +static void qr_define_modes(char modes[], const unsigned int ddata[], const int length, const int gs1, const int version, const int debug_print) { /* * Copyright (c) Project Nayuki. (MIT License) @@ -254,7 +254,7 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le * bits needed to encode the entire string prefix of length i, and end in qr_mode_types[j] */ memcpy(prev_costs, qr_head_costs(state), QR_NUM_MODES * sizeof(unsigned int)); - #ifdef QR_DEBUG_DEFINE_MODE + #ifdef QR_DEBUG_DEFINE_MODES printf(" head"); for (j = 0; j < QR_NUM_MODES; j++) { printf(" %c(%c)=%d", qr_mode_types[j], char_modes[0][j], prev_costs[j]); @@ -301,7 +301,7 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le } } - #ifdef QR_DEBUG_DEFINE_MODE + #ifdef QR_DEBUG_DEFINE_MODES { int min_j = 0; printf(" % 4d: curr", i); @@ -329,11 +329,11 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le for (i = length - 1; i >= 0; i--) { j = z_posn(qr_mode_types, cur_mode); cur_mode = char_modes[i][j]; - mode[i] = cur_mode; + modes[i] = cur_mode; } if (debug_print) { - printf(" Mode: %.*s\n", length, mode); + printf(" Modes: %.*s\n", length, modes); } } @@ -415,7 +415,7 @@ static int qr_terminator_bits(const int version) { } /* Convert input data to a binary stream and add padding */ -static int qr_binary(char binary[], int bp, const int version, const char mode[], +static int qr_binary(char binary[], int bp, const int version, const char modes[], const unsigned int ddata[], const int length, const int gs1, const int eci, const int debug_print) { int position = 0; @@ -438,7 +438,7 @@ static int qr_binary(char binary[], int bp, const int version, const char mode[] modebits = qr_mode_bits(version); do { - const char block_mode = mode[position]; + const char block_mode = modes[position]; int block_length = 0; int double_byte = 0; do { @@ -446,7 +446,7 @@ static int qr_binary(char binary[], int bp, const int version, const char mode[] double_byte++; } block_length++; - } while (position + block_length < length && mode[position + block_length] == block_mode); + } while (position + block_length < length && modes[position + block_length] == block_mode); /* Mode indicator */ if (modebits) { @@ -557,7 +557,7 @@ static int qr_binary(char binary[], int bp, const int version, const char mode[] i++; prod = first; - if (i < block_length && mode[position + i] == 'A') { + if (i < block_length && modes[position + i] == 'A') { if (gs1 && ddata[position + i] == '%') { second = QR_PERCENT; count = 2; @@ -582,7 +582,7 @@ static int qr_binary(char binary[], int bp, const int version, const char mode[] prod = first; percent = 0; - if (i < block_length && mode[position + i] == 'A') { + if (i < block_length && modes[position + i] == 'A') { if (gs1 && ddata[position + i] == '%') { second = QR_PERCENT; count = 2; @@ -633,12 +633,12 @@ static int qr_binary(char binary[], int bp, const int version, const char mode[] count = 1; prod = first; - if (i + 1 < block_length && mode[position + i + 1] == 'N') { + if (i + 1 < block_length && modes[position + i + 1] == 'N') { int second = z_ctoi((const char) ddata[position + i + 1]); count = 2; prod = (prod * 10) + second; - if (i + 2 < block_length && mode[position + i + 2] == 'N') { + if (i + 2 < block_length && modes[position + i + 2] == 'N') { int third = z_ctoi((const char) ddata[position + i + 2]); count = 3; prod = (prod * 10) + third; @@ -669,11 +669,11 @@ static int qr_binary(char binary[], int bp, const int version, const char mode[] /* Call `qr_binary()` for each segment, dealing with Structured Append and GS1 beforehand and padding afterwards */ static int qr_binary_segs(unsigned char datastream[], const int version, const int target_codewords, - const char mode[], const unsigned int ddata[], const struct zint_seg segs[], const int seg_count, + const char modes[], const unsigned int ddata[], const struct zint_seg segs[], const int seg_count, const struct zint_structapp *p_structapp, const int gs1, const int est_binlen, const int debug_print) { int i, j; const unsigned int *dd = ddata; - const char *m = mode; + const char *mds = modes; int bp = 0; int termbits, padbits; int current_bytes; @@ -701,8 +701,8 @@ static int qr_binary_segs(unsigned char datastream[], const int version, const i } for (i = 0; i < seg_count; i++) { - bp = qr_binary(binary, bp, version, m, dd, segs[i].length, gs1, segs[i].eci, debug_print); - m += segs[i].length; + bp = qr_binary(binary, bp, version, mds, dd, segs[i].length, gs1, segs[i].eci, debug_print); + mds += segs[i].length; dd += segs[i].length; } @@ -1439,22 +1439,22 @@ static void qr_add_version_info(unsigned char *grid, const int size, const int v } /* Find the length of the block starting from 'start' */ -static int qr_blockLength(const int start, const char mode[], const int length) { +static int qr_blockLength(const int start, const char modes[], const int length) { int i; int count = 0; - char start_mode = mode[start]; + char start_mode = modes[start]; i = start; do { count++; - } while (i + count < length && mode[i + count] == start_mode); + } while (i + count < length && modes[i + count] == start_mode); return count; } /* Calculate the actual bitlength of the proposed binary string */ -static int qr_calc_binlen(const int version, char mode[], const unsigned int ddata[], const int length, +static int qr_calc_binlen(const int version, char modes[], const unsigned int ddata[], const int length, const int mode_preset, const int gs1, const int eci, const int debug_print) { int i, j; char currentMode; @@ -1463,7 +1463,7 @@ static int qr_calc_binlen(const int version, char mode[], const unsigned int dda int blocklength; if (!mode_preset) { - qr_define_mode(mode, ddata, length, gs1, version, debug_print); + qr_define_modes(modes, ddata, length, gs1, version, debug_print); } currentMode = ' '; /* Null */ @@ -1480,10 +1480,10 @@ static int qr_calc_binlen(const int version, char mode[], const unsigned int dda } for (i = 0; i < length; i++) { - if (mode[i] != currentMode) { - count += qr_mode_bits(version) + qr_cci_bits(version, mode[i]); - blocklength = qr_blockLength(i, mode, length); - switch (mode[i]) { + if (modes[i] != currentMode) { + count += qr_mode_bits(version) + qr_cci_bits(version, modes[i]); + blocklength = qr_blockLength(i, modes, length); + switch (modes[i]) { case 'K': count += (blocklength * 13); break; @@ -1532,7 +1532,7 @@ static int qr_calc_binlen(const int version, char mode[], const unsigned int dda } break; } - currentMode = mode[i]; + currentMode = modes[i]; } } @@ -1540,13 +1540,13 @@ static int qr_calc_binlen(const int version, char mode[], const unsigned int dda } /* Call `qr_calc_binlen()` on each segment */ -static int qr_calc_binlen_segs(const int version, char mode[], const unsigned int ddata[], +static int qr_calc_binlen_segs(const int version, char modes[], const unsigned int ddata[], const struct zint_seg segs[], const int seg_count, const struct zint_structapp *p_structapp, const int mode_preset, const int gs1, const int debug_print) { int i; int count = 0; const unsigned int *dd = ddata; - char *m = mode; + char *mds = modes; if (p_structapp) { count += 4 + 8 + 8; @@ -1561,8 +1561,8 @@ static int qr_calc_binlen_segs(const int version, char mode[], const unsigned in } for (i = 0; i < seg_count; i++) { - count += qr_calc_binlen(version, m, dd, segs[i].length, mode_preset, gs1, segs[i].eci, debug_print); - m += segs[i].length; + count += qr_calc_binlen(version, mds, dd, segs[i].length, mode_preset, gs1, segs[i].eci, debug_print); + mds += segs[i].length; dd += segs[i].length; } @@ -1580,15 +1580,11 @@ static int qr_prep_data(struct zint_symbol *symbol, struct zint_seg segs[], cons int i; /* If ZINT_FULL_MULTIBYTE use Kanji mode in DATA_MODE or for non-Shift JIS in UNICODE_MODE */ const int full_multibyte = (symbol->option_3 & 0xFF) == ZINT_FULL_MULTIBYTE; - /* GS1 raw text dealt with by `ZBarcode_Encode_Segs()` */ - const int raw_text = (symbol->input_mode & 0x07) != GS1_MODE && (symbol->output_options & BARCODE_RAW_TEXT); - - if (raw_text && z_rt_init_segs(symbol, seg_count)) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` only fails with OOM */ - } + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback */ + const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; if ((symbol->input_mode & 0x07) == DATA_MODE) { - warn_number = zint_sjis_cpy_segs(symbol, segs, seg_count, ddata, full_multibyte); + zint_sjis_cpy_segs(segs, seg_count, ddata, full_multibyte); } else { unsigned int *dd = ddata; for (i = 0; i < seg_count; i++) { @@ -1616,8 +1612,8 @@ static int qr_prep_data(struct zint_symbol *symbol, struct zint_seg segs[], cons } eci = 20; } - if (raw_text && z_rt_cpy_seg_ddata(symbol, i, &segs[i], eci, dd)) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg_ddata()` only fails with OOM */ + if (raw_text && eci) { + z_rt_set_seg_eci(symbol, i, eci); } dd += segs[i].length; } @@ -1626,6 +1622,7 @@ static int qr_prep_data(struct zint_symbol *symbol, struct zint_seg segs[], cons return warn_number; } +/* QR Code ISO/IEC 18004:2024 */ INTERNAL int zint_qrcode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { int warn_number; int i, j, est_binlen, prev_est_binlen; @@ -1641,8 +1638,8 @@ INTERNAL int zint_qrcode(struct zint_symbol *symbol, struct zint_seg segs[], con const int eci_length_segs = zint_get_eci_length_segs(segs, seg_count); struct zint_seg *local_segs = (struct zint_seg *) z_alloca(sizeof(struct zint_seg) * seg_count); unsigned int *ddata = (unsigned int *) z_alloca(sizeof(unsigned int) * eci_length_segs); - char *mode = (char *) z_alloca(eci_length_segs); - char *prev_mode = (char *) z_alloca(eci_length_segs); + char *modes = (char *) z_alloca(eci_length_segs); + char *prev_modes = (char *) z_alloca(eci_length_segs); unsigned char *datastream; unsigned char *fullstream; unsigned char *grid; @@ -1707,7 +1704,7 @@ INTERNAL int zint_qrcode(struct zint_symbol *symbol, struct zint_seg segs[], con } } - est_binlen = qr_calc_binlen_segs(40, mode, ddata, local_segs, seg_count, p_structapp, 0 /*mode_preset*/, gs1, + est_binlen = qr_calc_binlen_segs(40, modes, ddata, local_segs, seg_count, p_structapp, 0 /*mode_preset*/, gs1, debug_print); if (symbol->option_1 >= 1 && symbol->option_1 <= 4) { @@ -1735,15 +1732,15 @@ INTERNAL int zint_qrcode(struct zint_symbol *symbol, struct zint_seg segs[], con } } if (autosize != 40) { - /* Save version 40 estimate in case incorrect costings in `qr_define_mode()` lead to its `mode` being better + /* Save version 40 estimate in case incorrect costings in `qr_define_modes()` lead to its `modes` being better than current lower version one */ prev_est_binlen = est_binlen; - est_binlen = qr_calc_binlen_segs(autosize, mode, ddata, local_segs, seg_count, p_structapp, 0 /*mode_preset*/, - gs1, debug_print); + est_binlen = qr_calc_binlen_segs(autosize, modes, ddata, local_segs, seg_count, p_structapp, + 0 /*mode_preset*/, gs1, debug_print); if (prev_est_binlen < est_binlen) { /* Shouldn't happen */ assert(0); /* Not reached (hopefully) */ - /* Defensively use version 40 `mode` to avoid crashes (ticket #300) */ - est_binlen = qr_calc_binlen_segs(40, mode, ddata, local_segs, seg_count, p_structapp, 0 /*mode_preset*/, + /* Defensively use version 40 `modes` to avoid crashes (ticket #300) */ + est_binlen = qr_calc_binlen_segs(40, modes, ddata, local_segs, seg_count, p_structapp, 0 /*mode_preset*/, gs1, debug_print); assert(est_binlen == prev_est_binlen); } @@ -1757,8 +1754,8 @@ INTERNAL int zint_qrcode(struct zint_symbol *symbol, struct zint_seg segs[], con canShrink = 0; } else { prev_est_binlen = est_binlen; - memcpy(prev_mode, mode, eci_length_segs); - est_binlen = qr_calc_binlen_segs(autosize - 1, mode, ddata, local_segs, seg_count, p_structapp, + memcpy(prev_modes, modes, eci_length_segs); + est_binlen = qr_calc_binlen_segs(autosize - 1, modes, ddata, local_segs, seg_count, p_structapp, 0 /*mode_preset*/, gs1, debug_print); if (8 * qr_data_codewords[ecc_level][autosize - 2] < est_binlen) { @@ -1771,7 +1768,7 @@ INTERNAL int zint_qrcode(struct zint_symbol *symbol, struct zint_seg segs[], con } else { /* Data did not fit in the smaller symbol, revert to original size */ est_binlen = prev_est_binlen; - memcpy(mode, prev_mode, eci_length_segs); + memcpy(modes, prev_modes, eci_length_segs); } } } while (canShrink == 1); @@ -1785,7 +1782,7 @@ INTERNAL int zint_qrcode(struct zint_symbol *symbol, struct zint_seg segs[], con */ if (symbol->option_2 > version) { version = symbol->option_2; - est_binlen = qr_calc_binlen_segs(symbol->option_2, mode, ddata, local_segs, seg_count, p_structapp, + est_binlen = qr_calc_binlen_segs(symbol->option_2, modes, ddata, local_segs, seg_count, p_structapp, 0 /*mode_preset*/, gs1, debug_print); } @@ -1822,8 +1819,8 @@ INTERNAL int zint_qrcode(struct zint_symbol *symbol, struct zint_seg segs[], con datastream = (unsigned char *) z_alloca(target_codewords + 1); fullstream = (unsigned char *) z_alloca(qr_total_codewords[version - 1] + 1); - (void) qr_binary_segs(datastream, version, target_codewords, mode, ddata, local_segs, seg_count, p_structapp, gs1, - est_binlen, debug_print); + (void) qr_binary_segs(datastream, version, target_codewords, modes, ddata, local_segs, seg_count, p_structapp, + gs1, est_binlen, debug_print); #ifdef ZINT_TEST if (symbol->debug & ZINT_DEBUG_TEST) z_debug_test_codeword_dump(symbol, datastream, target_codewords); #endif @@ -2139,6 +2136,7 @@ static int microqr_apply_bitmask(unsigned char *grid, const int size, const int return best_pattern; } +/* Micro QR Code ISO/IEC 18004:2024 */ INTERNAL int zint_microqr(struct zint_symbol *symbol, unsigned char source[], int length) { int i, size, j; char full_stream[200]; @@ -2147,7 +2145,7 @@ INTERNAL int zint_microqr(struct zint_symbol *symbol, unsigned char source[], in int user_mask; unsigned int ddata[40]; - char mode[40]; + char modes[40]; int alpha_used = 0, byte_or_kanji_used = 0; int eci = 0; int version_valid[4]; @@ -2158,6 +2156,7 @@ INTERNAL int zint_microqr(struct zint_symbol *symbol, unsigned char source[], in unsigned char *grid; struct zint_seg segs[1]; const int seg_count = 1; + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback */ const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; @@ -2240,16 +2239,16 @@ INTERNAL int zint_microqr(struct zint_symbol *symbol, unsigned char source[], in segs[0].source = source; segs[0].length = length; - segs[0].eci = 0; + segs[0].eci = 0; /* MicroQR doesn't support ECI */ - if (raw_text && (z_rt_init_segs(symbol, seg_count) || z_rt_cpy_seg_ddata(symbol, 0, &segs[0], eci, ddata))) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `z_rt_cpy_seg_ddata()` only fail with OOM */ + if (raw_text && eci) { /* For feedback set character set used (20 if non-zero) */ + z_rt_set_seg_eci(symbol, 0 /*seg_idx*/, eci); } /* Determine length of binary data */ for (i = 0; i < 4; i++) { if (version_valid[i]) { - binary_count[i] = qr_calc_binlen_segs(MICROQR_VERSION + i, mode, ddata, segs, seg_count, + binary_count[i] = qr_calc_binlen_segs(MICROQR_VERSION + i, modes, ddata, segs, seg_count, NULL /*p_structapp*/, 0 /*mode_preset*/, 0 /*gs1*/, debug_print); } else { binary_count[i] = 128 + 1; @@ -2309,10 +2308,10 @@ INTERNAL int zint_microqr(struct zint_symbol *symbol, unsigned char source[], in } } - qr_define_mode(mode, ddata, length, 0 /*gs1*/, MICROQR_VERSION + version, debug_print); + qr_define_modes(modes, ddata, length, 0 /*gs1*/, MICROQR_VERSION + version, debug_print); - bp = qr_binary_segs((unsigned char *) full_stream, MICROQR_VERSION + version, 0 /*target_codewords*/, mode, ddata, - segs, seg_count, NULL /*p_structapp*/, 0 /*gs1*/, binary_count[version], debug_print); + bp = qr_binary_segs(ZUCP(full_stream), MICROQR_VERSION + version, 0 /*target_codewords*/, modes, ddata, + segs, seg_count, NULL /*p_structapp*/, 0 /*gs1*/, binary_count[version], debug_print); if (debug_print) printf("Binary (%d): %.*s\n", bp, bp, full_stream); @@ -2367,6 +2366,7 @@ INTERNAL int zint_microqr(struct zint_symbol *symbol, unsigned char source[], in } /* For UPNQR the symbol size and error correction capacity is fixed */ +/* https://www.upn-qr.si/uploads/files/Tehnicni standard UPN QR.pdf */ INTERNAL int zint_upnqr(struct zint_symbol *symbol, unsigned char source[], int length) { int i, j, r, est_binlen; int ecc_level, version, target_codewords, blocks, size; @@ -2376,13 +2376,14 @@ INTERNAL int zint_upnqr(struct zint_symbol *symbol, unsigned char source[], int struct zint_seg segs[1]; const int seg_count = 1; const int fast_encode = symbol->input_mode & FAST_MODE; + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback */ const int raw_text = symbol->output_options & BARCODE_RAW_TEXT; const int debug_print = symbol->debug & ZINT_DEBUG_PRINT; unsigned char *datastream; unsigned char *fullstream; unsigned char *grid; unsigned int *ddata = (unsigned int *) z_alloca(sizeof(unsigned int) * length); - char *mode = (char *) z_alloca(length + 1); + char *modes = (char *) z_alloca(length + 1); unsigned char *preprocessed = (unsigned char *) z_alloca(length + 1); user_mask = (symbol->option_3 >> 8) & 0x0F; /* User mask is pattern + 1, so >= 1 and <= 8 */ @@ -2395,7 +2396,7 @@ INTERNAL int zint_upnqr(struct zint_symbol *symbol, unsigned char source[], int /* Input is already in ISO-8859-2 format */ for (i = 0; i < length; i++) { ddata[i] = source[i]; - mode[i] = 'B'; + modes[i] = 'B'; } break; case GS1_MODE: /* Should never happen as checked before being called */ @@ -2409,7 +2410,7 @@ INTERNAL int zint_upnqr(struct zint_symbol *symbol, unsigned char source[], int } for (i = 0; i < length; i++) { ddata[i] = preprocessed[i]; - mode[i] = 'B'; + modes[i] = 'B'; } break; } @@ -2418,12 +2419,11 @@ INTERNAL int zint_upnqr(struct zint_symbol *symbol, unsigned char source[], int segs[0].length = length; segs[0].eci = 4; - if (raw_text - && (z_rt_init_segs(symbol, seg_count) || z_rt_cpy_seg_ddata(symbol, 0, &segs[0], 0 /*eci*/, ddata))) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `z_rt_cpy_seg_ddata()` only fail with OOM */ + if (raw_text) { + z_rt_set_seg_eci(symbol, 0 /*seg_idx*/, segs[0].eci); } - est_binlen = qr_calc_binlen_segs(15, mode, ddata, segs, seg_count, NULL /*p_structapp*/, 1 /*mode_preset*/, + est_binlen = qr_calc_binlen_segs(15, modes, ddata, segs, seg_count, NULL /*p_structapp*/, 1 /*mode_preset*/, 0 /*gs1*/, debug_print); ecc_level = QR_LEVEL_M; @@ -2441,7 +2441,7 @@ INTERNAL int zint_upnqr(struct zint_symbol *symbol, unsigned char source[], int datastream = (unsigned char *) z_alloca(target_codewords + 1); fullstream = (unsigned char *) z_alloca(qr_total_codewords[version - 1] + 1); - (void) qr_binary_segs(datastream, version, target_codewords, mode, ddata, segs, seg_count, NULL /*p_structapp*/, + (void) qr_binary_segs(datastream, version, target_codewords, modes, ddata, segs, seg_count, NULL /*p_structapp*/, 0 /*gs1*/, est_binlen, debug_print); #ifdef ZINT_TEST if (symbol->debug & ZINT_DEBUG_TEST) z_debug_test_codeword_dump(symbol, datastream, target_codewords); @@ -2589,7 +2589,7 @@ static void rmqr_setup_grid(unsigned char *grid, const int h_size, const int v_s grid[(h_size * (v_size - 6)) + (h_size - 3)] = 0x20; } -/* rMQR according to 2018 draft standard */ +/* Rectangular Micro QR Code (rMQR) ISO/IEC 23941:2022 */ INTERNAL int zint_rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { int warn_number; int i, j, est_binlen; @@ -2601,7 +2601,7 @@ INTERNAL int zint_rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const const int eci_length_segs = zint_get_eci_length_segs(segs, seg_count); struct zint_seg *local_segs = (struct zint_seg *) z_alloca(sizeof(struct zint_seg) * seg_count); unsigned int *ddata = (unsigned int *) z_alloca(sizeof(unsigned int) * eci_length_segs); - char *mode = (char *) z_alloca(eci_length_segs); + char *modes = (char *) z_alloca(eci_length_segs); unsigned char *datastream; unsigned char *fullstream; unsigned char *grid; @@ -2637,7 +2637,7 @@ INTERNAL int zint_rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const } } - est_binlen = qr_calc_binlen_segs(RMQR_VERSION + 31, mode, ddata, local_segs, seg_count, NULL /*p_structapp*/, + est_binlen = qr_calc_binlen_segs(RMQR_VERSION + 31, modes, ddata, local_segs, seg_count, NULL /*p_structapp*/, 0 /*mode_preset*/, gs1, debug_print); ecc_level = symbol->option_1 == 4 ? QR_LEVEL_H : QR_LEVEL_M; @@ -2656,7 +2656,7 @@ INTERNAL int zint_rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const autosize = 31; best_footprint = rmqr_height[31] * rmqr_width[31]; for (version = 30; version >= 0; version--) { - est_binlen = qr_calc_binlen_segs(RMQR_VERSION + version, mode, ddata, local_segs, seg_count, + est_binlen = qr_calc_binlen_segs(RMQR_VERSION + version, modes, ddata, local_segs, seg_count, NULL /*p_structapp*/, 0 /*mode_preset*/, gs1, debug_print); footprint = rmqr_height[version] * rmqr_width[version]; if (8 * rmqr_data_codewords[ecc_level >> 1][version] >= est_binlen) { @@ -2667,14 +2667,14 @@ INTERNAL int zint_rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const } } version = autosize; - est_binlen = qr_calc_binlen_segs(RMQR_VERSION + version, mode, ddata, local_segs, seg_count, + est_binlen = qr_calc_binlen_segs(RMQR_VERSION + version, modes, ddata, local_segs, seg_count, NULL /*p_structapp*/, 0 /*mode_preset*/, gs1, debug_print); } if (symbol->option_2 >= 1 && symbol->option_2 <= 32) { /* User specified symbol size */ version = symbol->option_2 - 1; - est_binlen = qr_calc_binlen_segs(RMQR_VERSION + version, mode, ddata, local_segs, seg_count, + est_binlen = qr_calc_binlen_segs(RMQR_VERSION + version, modes, ddata, local_segs, seg_count, NULL /*p_structapp*/, 0 /*mode_preset*/, gs1, debug_print); } @@ -2682,13 +2682,13 @@ INTERNAL int zint_rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const /* User has specified symbol height only */ version = rmqr_fixed_height_upper_bound[symbol->option_2 - 32]; for (i = version - 1; i > rmqr_fixed_height_upper_bound[symbol->option_2 - 33]; i--) { - est_binlen = qr_calc_binlen_segs(RMQR_VERSION + i, mode, ddata, local_segs, seg_count, + est_binlen = qr_calc_binlen_segs(RMQR_VERSION + i, modes, ddata, local_segs, seg_count, NULL /*p_structapp*/, 0 /*mode_preset*/, gs1, debug_print); if (8 * rmqr_data_codewords[ecc_level >> 1][i] >= est_binlen) { version = i; } } - est_binlen = qr_calc_binlen_segs(RMQR_VERSION + version, mode, ddata, local_segs, seg_count, + est_binlen = qr_calc_binlen_segs(RMQR_VERSION + version, modes, ddata, local_segs, seg_count, NULL /*p_structapp*/, 0 /*mode_preset*/, gs1, debug_print); } @@ -2726,7 +2726,7 @@ INTERNAL int zint_rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const datastream = (unsigned char *) z_alloca(target_codewords + 1); fullstream = (unsigned char *) z_alloca(rmqr_total_codewords[version] + 1); - (void) qr_binary_segs(datastream, RMQR_VERSION + version, target_codewords, mode, ddata, local_segs, seg_count, + (void) qr_binary_segs(datastream, RMQR_VERSION + version, target_codewords, modes, ddata, local_segs, seg_count, NULL /*p_structapp*/, gs1, est_binlen, debug_print); #ifdef ZINT_TEST if (symbol->debug & ZINT_DEBUG_TEST) z_debug_test_codeword_dump(symbol, datastream, target_codewords); diff --git a/backend/telepen.c b/backend/telepen.c index 5a7b4f13..66db7386 100644 --- a/backend/telepen.c +++ b/backend/telepen.c @@ -105,7 +105,7 @@ INTERNAL int zint_telepen(struct zint_symbol *symbol, unsigned char source[], in d += 12; for (i = 0; i < length; i++) { - if (source[i] > 127) { + if (!z_isascii(source[i])) { /* Cannot encode extended ASCII */ return z_errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 391, "Invalid character at position %d in input, extended ASCII not allowed", i + 1); diff --git a/backend/tests/test_aztec.c b/backend/tests/test_aztec.c index f4fef011..d494594f 100644 --- a/backend/tests/test_aztec.c +++ b/backend/tests/test_aztec.c @@ -3199,9 +3199,9 @@ static void test_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { BARCODE_AZTEC, UNICODE_MODE, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { BARCODE_AZTEC, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { BARCODE_AZTEC, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { BARCODE_AZTEC, UNICODE_MODE, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { BARCODE_AZTEC, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { BARCODE_AZTEC, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { BARCODE_AZTEC, DATA_MODE, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 5*/ { BARCODE_AZTEC, DATA_MODE, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 6*/ { BARCODE_AZTEC, UNICODE_MODE, 26, -1, "é", -1, 0, 26, "", -1, 0 }, @@ -3211,8 +3211,10 @@ static void test_rt(const testCtx *const p_ctx) { /* 10*/ { BARCODE_AZTEC, GS1_MODE, -1, -1, "[01]04912345123459[15]970331[30]128[10](BC123", -1, 0, 0, "", -1, 0 }, /* 11*/ { BARCODE_AZTEC, GS1_MODE, -1, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10](BC123", -1, 0, 0, "01049123451234591597033130128\03510(BC123", -1, 3 }, /* 12*/ { BARCODE_AZTEC, GS1_MODE | ESCAPE_MODE | GS1PARENS_MODE, -1, BARCODE_RAW_TEXT, "(01)04912345123459(15)970331(30)128(10)\\(BC123", -1, 0, 0, "01049123451234591597033130128\03510(BC123", -1, 3 }, - /* 13*/ { BARCODE_HIBC_AZTEC, UNICODE_MODE, -1, -1, "H123ABC01234567890", -1, 0, 0, "", -1, 0 }, - /* 14*/ { BARCODE_HIBC_AZTEC, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "H123ABC01234567890", -1, 0, 0, "+H123ABC01234567890D", -1, 3 }, + /* 13*/ { BARCODE_AZTEC, GS1_MODE, 26, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10](BC123", -1, 0, 26, "01049123451234591597033130128\03510(BC123", -1, 3 }, /* Note: raw text ECI remains at default 3 */ + /* 14*/ { BARCODE_AZTEC, GS1_MODE, 24, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10](BC123", -1, 0, 24, "01049123451234591597033130128\03510(BC123", -1, 3 }, + /* 15*/ { BARCODE_HIBC_AZTEC, UNICODE_MODE, -1, -1, "H123ABC01234567890", -1, 0, 0, "", -1, 0 }, + /* 16*/ { BARCODE_HIBC_AZTEC, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "H123ABC01234567890", -1, 0, 0, "+H123ABC01234567890D", -1, 3 }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -3287,9 +3289,9 @@ static void test_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 15, 15, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 15, 15, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 15, 15, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 19, 19, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 19, 19, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 19, 19, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 4*/ { DATA_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 19, 19, {{0}}, 0 }, /* 5*/ { DATA_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 19, 19, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, }; diff --git a/backend/tests/test_codablock.c b/backend/tests/test_codablock.c index 7a445112..9587e4ff 100644 --- a/backend/tests/test_codablock.c +++ b/backend/tests/test_codablock.c @@ -305,11 +305,11 @@ static void test_hrt(const testCtx *const p_ctx) { /* 2*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 1, -1, -1, "12345623456", -1, "", "", -1 }, /* None (CODE128) */ /* 3*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 1, -1, BARCODE_RAW_TEXT, "12345623456", -1, "", "12345623456", -1 }, /* 4*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 1, -1, -1, "12345623456\012é", -1, "", "", -1 }, /* None (CODE128) */ - /* 5*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 1, -1, BARCODE_RAW_TEXT, "12345623456\012é", -1, "", "12345623456\012\351", -1 }, + /* 5*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 1, -1, BARCODE_RAW_TEXT, "12345623456\012é", -1, "", "12345623456\012é", -1 }, /* Now UTF-8, not converted */ /* 6*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, -1, -1, "12345623456\012é", -1, "", "", -1 }, /* None */ - /* 7*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "12345623456\012é", -1, "", "12345623456\012\351", -1 }, + /* 7*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "12345623456\012é", -1, "", "12345623456\012é", -1 }, /* 8*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, -1, -1, "12345623456\000\012é", -1, "", "", -1 }, /* None */ - /* 9*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "12345623456\000\012é", 15, "", "12345623456\000\012\351", 14 }, + /* 9*/ { BARCODE_CODABLOCKF, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "12345623456\000\012é", 15, "", "12345623456\000\012é", 15 }, /* 10*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, -1, -1, "12345623456\000\012é", 15, "", "", -1 }, /* None */ /* 11*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, -1, BARCODE_RAW_TEXT, "12345623456\000\012é", 15, "", "12345623456\000\012é", 15 }, /* 12*/ { BARCODE_CODABLOCKF, DATA_MODE, -1, -1, -1, "12345623456\000\012\351", 14, "", "", -1 }, /* None */ diff --git a/backend/tests/test_code1.c b/backend/tests/test_code1.c index 29ad5c5d..e250cab0 100644 --- a/backend/tests/test_code1.c +++ b/backend/tests/test_code1.c @@ -3383,9 +3383,9 @@ static void test_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { DATA_MODE, -1, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 5*/ { DATA_MODE, -1, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 6*/ { UNICODE_MODE, 26, -1, -1, "é", -1, 0, 26, "", -1, 0 }, @@ -3394,9 +3394,12 @@ static void test_rt(const testCtx *const p_ctx) { /* 9*/ { UNICODE_MODE, 899, -1, BARCODE_RAW_TEXT, "é", -1, 0, 899, "é", -1, 899 }, /* 10*/ { GS1_MODE, -1, -1, -1, "[01]04912345123459[15]970331[30]128[10]ABC12(", -1, 0, 0, "", -1, 0 }, /* 11*/ { GS1_MODE, -1, -1, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC12(", -1, 0, 0, "01049123451234591597033130128\03510ABC12(", -1, 3 }, - /* 12*/ { GS1_MODE | ESCAPE_MODE | GS1PARENS_MODE, -1, -1, BARCODE_RAW_TEXT, "(01)04912345123459(15)970331(30)128(10)ABC12\\(", -1, 0, 0, "01049123451234591597033130128\03510ABC12(", -1, 3 }, - /* 13*/ { UNICODE_MODE, -1, 9, -1, "12345", -1, 0, 0, "", -1, 0 }, /* Version S */ - /* 14*/ { UNICODE_MODE, -1, 9, BARCODE_RAW_TEXT, "12345", -1, 0, 0, "12345", -1, 3 }, + /* 12*/ { GS1_MODE, 4, -1, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC12(", -1, ZINT_WARN_INVALID_OPTION, 4, "01049123451234591597033130128\03510ABC12(", -1, 3 }, /* Note raw text ECI remains at default 3 */ + /* 13*/ { GS1_MODE, 4, 10, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC12(", -1, ZINT_WARN_INVALID_OPTION, 4, "01049123451234591597033130128\03510ABC12(", -1, 3 }, /* Version T, ECI ignored */ + /* 14*/ { GS1_MODE | ESCAPE_MODE | GS1PARENS_MODE, -1, -1, BARCODE_RAW_TEXT, "(01)04912345123459(15)970331(30)128(10)ABC12\\(", -1, 0, 0, "01049123451234591597033130128\03510ABC12(", -1, 3 }, + /* 15*/ { UNICODE_MODE, -1, 9, -1, "12345", -1, 0, 0, "", -1, 0 }, /* Version S */ + /* 16*/ { UNICODE_MODE, -1, 9, BARCODE_RAW_TEXT, "12345", -1, 0, 0, "12345", -1, 3 }, + /* 17*/ { UNICODE_MODE, 4, 9, BARCODE_RAW_TEXT, "12345", -1, ZINT_WARN_INVALID_OPTION, 4, "12345", -1, 4 }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -3459,6 +3462,7 @@ static void test_rt_segs(const testCtx *const p_ctx) { struct item { int input_mode; + int option_2; int output_options; struct zint_seg segs[3]; int ret; @@ -3470,12 +3474,16 @@ static void test_rt_segs(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 16, 18, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 16, 18, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, - /* 2*/ { UNICODE_MODE, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 28, 32, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 28, 32, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, - /* 4*/ { DATA_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 28, 32, {{0}}, 0 }, - /* 5*/ { DATA_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 28, 32, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, + /* 0*/ { UNICODE_MODE, -1, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 16, 18, {{0}}, 0 }, + /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 16, 18, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ + /* 2*/ { UNICODE_MODE, -1, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 28, 32, {{0}}, 0 }, + /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 28, 32, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, + /* 4*/ { DATA_MODE, -1, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 28, 32, {{0}}, 0 }, + /* 5*/ { DATA_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 28, 32, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, + /* 6*/ { UNICODE_MODE, 9, -1, { { TU("12"), -1, 0 }, {0}, {0} }, 0, 8, 11, {{0}}, 0 }, /* Version S */ + /* 7*/ { UNICODE_MODE, 9, BARCODE_RAW_TEXT, { { TU("12"), -1, 0 }, {0}, {0} }, 0, 8, 11, { { TU("12"), 2, 3 }, {0}, {0} }, 1 }, + /* 8*/ { UNICODE_MODE, 9, -1, { { TU("12"), -1, 20 }, {0}, {0} }, ZINT_WARN_INVALID_OPTION, 8, 11, {{0}}, 0 }, /* Version S */ + /* 9*/ { UNICODE_MODE, 9, BARCODE_RAW_TEXT, { { TU("12"), -1, 20 }, {0}, {0} }, ZINT_WARN_INVALID_OPTION, 8, 11, { { TU("12"), 2, 20 }, {0}, {0} }, 1 }, }; const int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; @@ -3496,7 +3504,7 @@ static void test_rt_segs(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); testUtilSetSymbol(symbol, BARCODE_CODEONE, data[i].input_mode, -1 /*eci*/, - -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, + -1 /*option_1*/, data[i].option_2, -1 /*option_3*/, data[i].output_options, NULL, 0, debug); for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++); diff --git a/backend/tests/test_code128.c b/backend/tests/test_code128.c index fd7b4ae7..0a456107 100644 --- a/backend/tests/test_code128.c +++ b/backend/tests/test_code128.c @@ -220,9 +220,9 @@ static void test_hrt(const testCtx *const p_ctx) { /* 6*/ { BARCODE_CODE128, UNICODE_MODE, -1, -1, "12345\01167890\037\177", -1, "12345 67890 ", -1, "", -1, 1 }, /* 7*/ { BARCODE_CODE128, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "12345\01167890\037\177", -1, "12345 67890 ", -1, "12345\01167890\037\177", -1, 1 }, /* 8*/ { BARCODE_CODE128, UNICODE_MODE, -1, -1, "abcdé", -1, "abcdé", -1, "", -1, 1 }, - /* 9*/ { BARCODE_CODE128, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "abcdé", -1, "abcdé", -1, "abcd\351", -1, 1 }, + /* 9*/ { BARCODE_CODE128, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "abcdé", -1, "abcdé", -1, "abcdé", -1, 1 }, /* Now UTF-8, not converted */ /* 10*/ { BARCODE_CODE128, UNICODE_MODE, -1, -1, "abcdé\302\240", -1, "abcdé\302\240", -1, "", -1, 1 }, /* \302\240 (U+A0) NBSP */ - /* 11*/ { BARCODE_CODE128, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "abcdé\302\240", -1, "abcdé\302\240", -1, "abcd\351\240", -1, 1 }, + /* 11*/ { BARCODE_CODE128, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "abcdé\302\240", -1, "abcdé\302\240", -1, "abcdé\302\240", -1, 1 }, /* 12*/ { BARCODE_CODE128, DATA_MODE, -1, -1, "abcd\351", -1, "abcdé", -1, "", -1, 899 }, /* 13*/ { BARCODE_CODE128, DATA_MODE, -1, BARCODE_RAW_TEXT, "abcd\351", -1, "abcdé", -1, "abcd\351", -1, 899 }, /* 14*/ { BARCODE_CODE128, DATA_MODE, -1, -1, "ab\240cd\351", -1, "ab\302\240cdé", -1, "", -1, 899 }, /* \240 (U+A0) NBSP */ @@ -232,7 +232,7 @@ static void test_hrt(const testCtx *const p_ctx) { /* 18*/ { BARCODE_CODE128, EXTRA_ESCAPE_MODE, -1, -1, "\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C123456789012345678", -1, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", -1, "", -1, 1 }, /* Max length 198 + 19 special escapes = 99 + 19*3 = 255 */ /* 19*/ { BARCODE_CODE128, EXTRA_ESCAPE_MODE, -1, BARCODE_RAW_TEXT, "\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C1234567890\\^C123456789012345678", -1, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", -1, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", -1, 1 }, /* 20*/ { BARCODE_CODE128AB, UNICODE_MODE, -1, -1, "abcdé", -1, "abcdé", -1, "", -1, 1 }, - /* 21*/ { BARCODE_CODE128AB, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "abcdé", -1, "abcdé", -1, "abcd\351", -1, 1 }, + /* 21*/ { BARCODE_CODE128AB, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "abcdé", -1, "abcdé", -1, "abcdé", -1, 1 }, /* 22*/ { BARCODE_CODE128AB, DATA_MODE, -1, -1, "abcd\351", -1, "abcdé", -1, "", -1, 899 }, /* 23*/ { BARCODE_CODE128AB, DATA_MODE, -1, BARCODE_RAW_TEXT, "abcd\351", -1, "abcdé", -1, "abcd\351", -1, 899 }, /* 24*/ { BARCODE_HIBC_128, UNICODE_MODE, -1, -1, "1234567890", -1, "*+12345678900*", -1, "", -1, 1 }, diff --git a/backend/tests/test_code16k.c b/backend/tests/test_code16k.c index 881f4f9c..56acb5bb 100644 --- a/backend/tests/test_code16k.c +++ b/backend/tests/test_code16k.c @@ -470,7 +470,7 @@ static void test_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { DATA_MODE, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 3*/ { DATA_MODE, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 4*/ { GS1_MODE, -1, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "", -1, 0 }, diff --git a/backend/tests/test_common.c b/backend/tests/test_common.c index 63eb4701..b4439fa7 100644 --- a/backend/tests/test_common.c +++ b/backend/tests/test_common.c @@ -1053,34 +1053,28 @@ static void test_hrt_conv_gs1_brackets_nochk(const testCtx *const p_ctx) { testFinish(); } -static void test_rt_cpy_seg(const testCtx *const p_ctx) { +static void test_rt_cpy_segs(const testCtx *const p_ctx) { int debug = p_ctx->debug; struct item { int seg_count; - int seg_idx; - struct zint_seg seg; - unsigned int ddata[8]; - int ddata_size; - int ddata_eci; + struct zint_seg segs[3]; - const char *expected; - int expected_length; - int expected_eci; + struct zint_seg expected_raw_segs[3]; + int expected_raw_seg_count; }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { 1, 0, { TU("A"), 1, 0 }, {0}, 0, 0, "A", -1, 3 }, - /* 1*/ { 1, 0, { TU("A"), 1, 900 }, {0}, 0, 0, "A", -1, 900 }, - /* 2*/ { 2, 1, { TU("A"), 1, 0 }, {0}, 0, 0, "A", -1, 3 }, - /* 3*/ { 1, 0, { TU("ABCDE"), 5, 0 }, { 'B', 0xFF, 'C', 0xFF00, 'D' }, 5, 0, "B\377C\377\000D", 6, 3 }, + /* 0*/ { 1, { { TU("A"), 0, 0 } }, { { TU("A"), 1, 3 } }, 1 }, + /* 1*/ { 1, { { TU("B\377C\377\000D"), 6, 0 } }, { { TU("B\377C\377\000D"), 6, 3 } }, 1 }, + /* 2*/ { 2, { { TU("A"), 0, 5 }, { TU("\000\355"), 2, 899 } }, { { TU("A"), 1, 5 }, { TU("\000\355"), 2, 899 } }, 2 }, + /* 3*/ { 3, { { TU("A"), 1, 5 }, { TU("ABCD"), 0, 900 }, { TU("\000\355"), 2, 899 } }, { { TU("A"), 1, 5 }, { TU("ABCD"), 4, 900 }, { TU("\000\355"), 2, 899 } }, 3 }, }; const int data_size = ARRAY_SIZE(data); int i, ret; struct zint_symbol s_symbol = {0}; struct zint_symbol *symbol = &s_symbol; - int expected_length; char escaped[4096]; char escaped2[4096]; @@ -1090,46 +1084,41 @@ static void test_rt_cpy_seg(const testCtx *const p_ctx) { symbol->debug = debug; for (i = 0; i < data_size; i++) { + int expected_length; + unsigned char *expected_source; + int expected_eci; int seg_idx; if (testContinue(p_ctx, i)) continue; - expected_length = data[i].expected_length == -1 ? (int) strlen(data[i].expected) : data[i].expected_length; - assert_nonzero(data[i].seg_count, "i:%d seg_count zero\n", i); - ret = z_rt_init_segs(symbol, data[i].seg_count); - assert_zero(ret, "i:%d z_rt_init_segs(%d) %d != 0\n", i, data[i].seg_count, ret); - - seg_idx = data[i].seg_idx; - assert_nonzero(seg_idx >= 0, "i:%d seg_idx %d < 0\n", i, seg_idx); - assert_nonzero(seg_idx < data[i].seg_count, "i:%d seg_idx %d >= seg_count 0%d\n", - i, seg_idx, data[i].seg_count); - - if (data[i].ddata_size > 0) { - assert_equal(data[i].seg.length, data[i].ddata_size, "i:%d seg_length %d != ddata_size %d\n", - i, data[i].seg.length, data[i].ddata_size); - ret = z_rt_cpy_seg_ddata(symbol, seg_idx, &data[i].seg, data[i].ddata_eci, data[i].ddata); - assert_zero(ret, "i:%d rt_cpy_seg_ddata %d != 0\n", i, ret); - } else { - ret = z_rt_cpy_seg(symbol, seg_idx, &data[i].seg); - assert_zero(ret, "i:%d rt_cpy_segs %d != 0\n", i, ret); - } + ret = z_rt_cpy_segs(symbol, data[i].segs, data[i].seg_count); + assert_zero(ret, "i:%d rt_cpy_segs %d != 0\n", i, ret); assert_nonnull(symbol->raw_segs, "i:%d raw_segs NULL\n", i); - assert_nonnull(symbol->raw_segs[seg_idx].source, "i:%d raw_segs[%d].source NULL\n", i, seg_idx); - assert_equal(symbol->raw_segs[seg_idx].length, expected_length, - "i:%d raw_segs[%d].length %d != expected_length %d\n", - i, seg_idx, symbol->raw_segs[seg_idx].length, expected_length); - assert_zero(memcmp(symbol->raw_segs[seg_idx].source, data[i].expected, expected_length), - "i:%d raw_segs[%d].source memcmp(%s, %s, %d) != 0\n", i, seg_idx, - testUtilEscape((const char *) symbol->raw_segs[seg_idx].source, symbol->raw_segs[seg_idx].length, - escaped, sizeof(escaped)), - testUtilEscape(data[i].expected, expected_length, escaped2, sizeof(escaped2)), - expected_length); - assert_equal(symbol->raw_segs[seg_idx].eci, data[i].expected_eci, - "i:%d raw_segs[%d].eci %d != expected_eci %d\n", - i, seg_idx, symbol->raw_segs[seg_idx].eci, data[i].expected_eci); + assert_equal(symbol->raw_seg_count, data[i].seg_count, "i:%d raw_seg_count %d != %d\n", + i, symbol->raw_seg_count, data[i].seg_count); + for (seg_idx = 0; seg_idx < data[i].seg_count; seg_idx++) { + assert_nonnull(&symbol->raw_segs[seg_idx], "i:%d raw_segs[%d] NULL\n", i, seg_idx); + assert_nonnull(symbol->raw_segs[seg_idx].source, "i:%d raw_segs[%d].source NULL\n", i, seg_idx); + + expected_length = data[i].expected_raw_segs[seg_idx].length; + expected_source = data[i].expected_raw_segs[seg_idx].source; + expected_eci = data[i].expected_raw_segs[seg_idx].eci; + + assert_equal(symbol->raw_segs[seg_idx].length, expected_length, + "i:%d raw_segs[%d].length %d != expected_length %d\n", + i, seg_idx, symbol->raw_segs[seg_idx].length, expected_length); + assert_zero(memcmp(symbol->raw_segs[seg_idx].source, expected_source, expected_length), + "i:%d raw_segs[%d].source memcmp(%s, %s, %d) != 0\n", i, seg_idx, + testUtilEscape(ZCCP(symbol->raw_segs[seg_idx].source), symbol->raw_segs[seg_idx].length, + escaped, sizeof(escaped)), + testUtilEscape(ZCCP(expected_source), expected_length, escaped2, sizeof(escaped2)), + expected_length); + assert_equal(symbol->raw_segs[seg_idx].eci, expected_eci, "i:%d raw_segs[%d].eci %d != expected_eci %d\n", + i, seg_idx, symbol->raw_segs[seg_idx].eci, expected_eci); + } ZBarcode_Clear(symbol); } @@ -1141,9 +1130,6 @@ static void test_rt_cpy(const testCtx *const p_ctx) { int debug = p_ctx->debug; struct item { - int seg_count; - int seg_idx; - const char *source; int length; char separator; @@ -1156,10 +1142,10 @@ static void test_rt_cpy(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { 1, 0, "A", -1, '\0', "", -1, "A", -1, 3 }, - /* 1*/ { 1, 0, "A", -1, ':', "B", -1, "A:B", -1, 3 }, - /* 2*/ { 1, 0, "A", -1, '\xFF', "B", -1, "AB", -1, 3 }, - /* 3*/ { 1, 0, "A", -1, '\0', "B", -1, "A\000B", 3, 3 }, + /* 0*/ { "A", -1, '\0', "", -1, "A", -1, 3 }, + /* 1*/ { "A", -1, ':', "B", -1, "A:B", -1, 3 }, + /* 2*/ { "A", -1, '\xFF', "B", -1, "AB", -1, 3 }, + /* 3*/ { "A", -1, '\0', "B", -1, "A\000B", 3, 3 }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1182,9 +1168,6 @@ static void test_rt_cpy(const testCtx *const p_ctx) { expected_length = data[i].expected_length == -1 ? (int) strlen(data[i].expected) : data[i].expected_length; - ret = z_rt_init_segs(symbol, 1); - assert_zero(ret, "i:%d rt_init_segs %d != 0\n", i, ret); - length = data[i].length == -1 ? (int) strlen(data[i].source) : data[i].length; if ((cat_length = data[i].cat_length == -1 ? (int) strlen(data[i].cat) : data[i].cat_length)) { @@ -1216,6 +1199,70 @@ static void test_rt_cpy(const testCtx *const p_ctx) { testFinish(); } +static void test_rt_cpy_iso8859_1(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + const char *source; + int length; + + const char *expected; + int expected_length; + int expected_eci; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { "A", -1, "A", -1, 3 }, + /* 1*/ { "\000AB\177", 4, "\000AB\177", 4, 3 }, + /* 2*/ { "A\200", -1, "A\302\200", -1, 3 }, + /* 3*/ { "A\237\240\277\300B\377C", -1, "A\302\237\302\240\302\277\303\200B\303\277C", -1, 3 }, + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + + struct zint_symbol s_symbol = {0}; + struct zint_symbol *symbol = &s_symbol; + int expected_length; + + char escaped[4096]; + char escaped2[4096]; + + testStart(p_ctx->func_name); + + symbol->debug = debug; + + for (i = 0; i < data_size; i++) { + + if (testContinue(p_ctx, i)) continue; + + expected_length = data[i].expected_length == -1 ? (int) strlen(data[i].expected) : data[i].expected_length; + + length = data[i].length == -1 ? (int) strlen(data[i].source) : data[i].length; + + ret = z_rt_cpy_iso8859_1(symbol, TCU(data[i].source), length); + assert_zero(ret, "i:%d z_rt_cpy_iso8859_1 %d != 0\n", i, ret); + + assert_nonnull(symbol->raw_segs, "i:%d raw_segs NULL\n", i); + assert_nonnull(symbol->raw_segs[0].source, "i:%d raw_segs[0].source NULL\n", i); + assert_equal(symbol->raw_segs[0].length, expected_length, + "i:%d raw_segs[0].length %d != expected_length %d\n", + i, symbol->raw_segs[0].length, expected_length); + assert_zero(memcmp(symbol->raw_segs[0].source, data[i].expected, expected_length), + "i:%d raw_segs[0].source memcmp(%s, %s, %d) != 0\n", i, + testUtilEscape((const char *) symbol->raw_segs[0].source, symbol->raw_segs[0].length, + escaped, sizeof(escaped)), + testUtilEscape(data[i].expected, expected_length, escaped2, sizeof(escaped2)), + expected_length); + assert_equal(symbol->raw_segs[0].eci, data[i].expected_eci, + "i:%d raw_segs[0].eci %d != expected_eci %d\n", + i, symbol->raw_segs[0].eci, data[i].expected_eci); + + ZBarcode_Clear(symbol); + } + + testFinish(); +} + static void test_rt_printf_256(const testCtx *const p_ctx) { int debug = p_ctx->debug; @@ -1253,9 +1300,6 @@ static void test_rt_printf_256(const testCtx *const p_ctx) { expected_length = (int) strlen(data[i].expected); - ret = z_rt_init_segs(symbol, 1); - assert_zero(ret, "i:%d rt_init_segs %d != 0\n", i, ret); - if (data[i].num_args == 1) { ret = z_rt_printf_256(symbol, data[i].fmt, data[i].data1); assert_zero(ret, "i:%d rt_printf_256 1 arg ret %d != 0\n", i, ret); @@ -1411,8 +1455,9 @@ 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_rt_cpy_seg", test_rt_cpy_seg }, + { "test_rt_cpy_segs", test_rt_cpy_segs }, { "test_rt_cpy", test_rt_cpy }, + { "test_rt_cpy_iso8859_1", test_rt_cpy_iso8859_1 }, { "test_rt_printf_256", test_rt_printf_256 }, { "test_set_height", test_set_height }, { "test_debug_test_codeword_dump_int", test_debug_test_codeword_dump_int }, diff --git a/backend/tests/test_dmatrix.c b/backend/tests/test_dmatrix.c index 13d191f7..9003727f 100644 --- a/backend/tests/test_dmatrix.c +++ b/backend/tests/test_dmatrix.c @@ -6415,9 +6415,9 @@ static void test_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { BARCODE_DATAMATRIX, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { BARCODE_DATAMATRIX, UNICODE_MODE | ESCAPE_MODE, -1, -1, "[)>\\R05\\GA\\R\\E", -1, 0, 0, "", -1, 0 }, /* 5*/ { BARCODE_DATAMATRIX, UNICODE_MODE | ESCAPE_MODE, -1, BARCODE_RAW_TEXT, "[)>\\R05\\GA\\R\\E", -1, 0, 0, "[)>\03605\035A\036\004", -1, 3 }, /* Full content including Macro05 */ /* 6*/ { BARCODE_DATAMATRIX, DATA_MODE, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, @@ -6428,8 +6428,9 @@ static void test_rt(const testCtx *const p_ctx) { /* 11*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 899, BARCODE_RAW_TEXT, "é", -1, 0, 899, "é", -1, 899 }, /* 12*/ { BARCODE_DATAMATRIX, GS1_MODE, -1, -1, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "", -1, 0 }, /* 13*/ { BARCODE_DATAMATRIX, GS1_MODE, -1, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "01049123451234591597033130128\03510ABC123", -1, 3 }, - /* 14*/ { BARCODE_HIBC_DM, UNICODE_MODE, -1, -1, "H123ABC01234567890", -1, 0, 0, "", -1, 0 }, - /* 15*/ { BARCODE_HIBC_DM, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "H123ABC01234567890", -1, 0, 0, "+H123ABC01234567890D", -1, 3 }, + /* 14*/ { BARCODE_DATAMATRIX, GS1_MODE, 28, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 28, "01049123451234591597033130128\03510ABC123", -1, 3 }, /* Note: raw text ECI rremains at default 3 */ + /* 15*/ { BARCODE_HIBC_DM, UNICODE_MODE, -1, -1, "H123ABC01234567890", -1, 0, 0, "", -1, 0 }, + /* 16*/ { BARCODE_HIBC_DM, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "H123ABC01234567890", -1, 0, 0, "+H123ABC01234567890D", -1, 3 }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -6504,9 +6505,9 @@ static void test_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 14, 14, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 14, 14, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 14, 14, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 18, 18, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 18, 18, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 18, 18, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 4*/ { DATA_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 18, 18, {{0}}, 0 }, /* 5*/ { DATA_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 18, 18, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, }; diff --git a/backend/tests/test_dotcode.c b/backend/tests/test_dotcode.c index 2d7aa4ae..f27b28c1 100644 --- a/backend/tests/test_dotcode.c +++ b/backend/tests/test_dotcode.c @@ -1619,9 +1619,9 @@ static void test_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { UNICODE_MODE | ESCAPE_MODE, -1, -1, "[)>\\R05\\GA\\R\\E", -1, 0, 0, "", -1, 0 }, /* 5*/ { UNICODE_MODE | ESCAPE_MODE, -1, BARCODE_RAW_TEXT, "[)>\\R05\\GA\\R\\E", -1, 0, 0, "[)>\03605\035A\036\004", -1, 3 }, /* 6*/ { DATA_MODE, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, @@ -1632,6 +1632,7 @@ static void test_rt(const testCtx *const p_ctx) { /* 11*/ { UNICODE_MODE, 899, BARCODE_RAW_TEXT, "é", -1, 0, 899, "é", -1, 899 }, /* 12*/ { GS1_MODE, -1, -1, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "", -1, 0 }, /* 13*/ { GS1_MODE, -1, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "01049123451234591597033130128\03510ABC123", -1, 3 }, + /* 14*/ { GS1_MODE, 20, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, ZINT_WARN_NONCOMPLIANT, 20, "01049123451234591597033130128\03510ABC123", -1, 3 }, /* Note: raw text ECI remains at default 3 */ }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1705,9 +1706,9 @@ static void test_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 12, 19, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 12, 19, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 12, 19, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 19, 28, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 19, 28, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 19, 28, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 4*/ { DATA_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 19, 28, {{0}}, 0 }, /* 5*/ { DATA_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 19, 28, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, }; diff --git a/backend/tests/test_gridmtx.c b/backend/tests/test_gridmtx.c index 4ce771d0..da19f260 100644 --- a/backend/tests/test_gridmtx.c +++ b/backend/tests/test_gridmtx.c @@ -926,11 +926,11 @@ static void test_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\250\246", -1, 29 }, + /* 1*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 29 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { UNICODE_MODE, -1, -1, -1, "电", -1, 0, 0, "", -1, 0 }, - /* 5*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "电", -1, 0, 0, "\265\347", -1, 29 }, + /* 5*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "电", -1, 0, 0, "电", -1, 29 }, /* 6*/ { DATA_MODE, -1, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 7*/ { DATA_MODE, -1, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 29 }, /* 8*/ { DATA_MODE, -1, ZINT_FULL_MULTIBYTE, -1, "\351", -1, 0, 0, "", -1, 0 }, @@ -1014,15 +1014,15 @@ static void test_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, ZINT_WARN_USES_ECI, 30, 30, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 30, 30, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 30, 30, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, { { TU("ก"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, ZINT_WARN_USES_ECI, 30, 30, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("ก"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 30, 30, { { TU("\241"), 1, 13 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("ก"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 30, 30, { { TU("ก"), 3, 13 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* 4*/ { UNICODE_MODE, -1, { { TU("电"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 30, 30, {{0}}, 0 }, - /* 5*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("电"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 30, 30, { { TU("\265\347"), 2, 29 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 5*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("电"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 30, 30, { { TU("电"), 3, 29 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* 6*/ { UNICODE_MODE, -1, { { TU("电电"), -1, 0 }, { TU("กขฯ"), -1, 13 }, { TU("βββ"), -1, 9 } }, 0, 30, 30, {{0}}, 0 }, - /* 7*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("电电"), -1, 0 }, { TU("กขฯ"), -1, 13 }, { TU("βββ"), -1, 9 } }, 0, 30, 30, { { TU("\265\347\265\347"), 4, 29 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 7*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("电电"), -1, 0 }, { TU("กขฯ"), -1, 13 }, { TU("βββ"), -1, 9 } }, 0, 30, 30, { { TU("电电"), 6, 29 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 8*/ { UNICODE_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("点"), -1, 20 } }, 0, 30, 30, {{0}}, 0 }, - /* 9*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("点"), -1, 20 } }, 0, 30, 30, { { TU("¶"), 2, 26 }, { TU("\247\250"), 2, 29 }, { TU("\223\137"), 2, 20 } }, 3 }, + /* 9*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("点"), -1, 20 } }, 0, 30, 30, { { TU("¶"), 2, 26 }, { TU("Ж"), 2, 29 }, { TU("点"), 3, 20 } }, 3 }, /* 10*/ { DATA_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 30, 30, {{0}}, 0 }, /* 11*/ { DATA_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 30, 30, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 29 }, { TU("\223\137"), 2, 20 } }, 3 }, }; diff --git a/backend/tests/test_hanxin.c b/backend/tests/test_hanxin.c index ac9a0da1..0ea1b036 100644 --- a/backend/tests/test_hanxin.c +++ b/backend/tests/test_hanxin.c @@ -3627,13 +3627,13 @@ static void test_rt(const testCtx *const p_ctx) { }; static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, -1, "ก", -1, ZINT_WARN_NONCOMPLIANT, 0, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_NONCOMPLIANT, 0, "\2012\3169", -1, 32 }, /* When single segment will try ECI 32 as secondary default */ + /* 3*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_NONCOMPLIANT, 0, "ก", -1, 32 }, /* When single segment will try ECI 32 as secondary default */ /* 4*/ { UNICODE_MODE, -1, -1, -1, "啊", -1, ZINT_WARN_NONCOMPLIANT, 0, "", -1, 0 }, - /* 5*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "啊", -1, ZINT_WARN_NONCOMPLIANT, 0, "\260\241", -1, 32 }, + /* 5*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "啊", -1, ZINT_WARN_NONCOMPLIANT, 0, "啊", -1, 32 }, /* 6*/ { UNICODE_MODE, -1, -1, -1, "\302\200", -1, ZINT_WARN_NONCOMPLIANT, 0, "", -1, 0 }, - /* 7*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "\302\200", -1, ZINT_WARN_NONCOMPLIANT, 0, "\201\060\201\060", -1, 32 }, + /* 7*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "\302\200", -1, ZINT_WARN_NONCOMPLIANT, 0, "\302\200", -1, 32 }, /* 8*/ { DATA_MODE, -1, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 9*/ { DATA_MODE, -1, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 10*/ { DATA_MODE, -1, ZINT_FULL_MULTIBYTE, -1, "\223\137", -1, 0, 0, "", -1, 0 }, @@ -3717,13 +3717,13 @@ static void test_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 23, 23, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 23, 23, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 23, 23, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, { { TU("ก"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, ZINT_WARN_USES_ECI, 23, 23, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("ก"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 23, 23, { { TU("\241"), 1, 13 }, { TU("\266"), 1, 7 }, {0} }, 2 }, /* When multiple segments, ECI 32 is not used as secondary default, so fails and retries with `get_best_eci()` */ + /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("ก"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 23, 23, { { TU("ก"), 3, 13 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* When multiple segments, ECI 32 is not used as secondary default, so fails and retries with `get_best_eci()` */ /* 4*/ { UNICODE_MODE, -1, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 23, 23, {{0}}, 0 }, - /* 5*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 23, 23, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 5*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 23, 23, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 6*/ { UNICODE_MODE, -1, -1, { { TU("啊啊"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 25, 25, {{0}}, 0 }, - /* 7*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("啊啊"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 25, 25, { { TU("啊啊"), 6, 26 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, /* Note chooses 26 (UTF-8) for 啊 as multiple segments */ + /* 7*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("啊啊"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 25, 25, { { TU("啊啊"), 6, 26 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* Note chooses 26 (UTF-8) for 啊 as multiple segments */ /* 8*/ { DATA_MODE, -1, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\260\241"), -1, 32 } }, 0, 23, 23, {{0}}, 0 }, /* 9*/ { DATA_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\260\241"), -1, 32 } }, 0, 23, 23, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\260\241"), 2, 32 } }, 3 }, /* 10*/ { DATA_MODE, ZINT_FULL_MULTIBYTE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\260\241"), -1, 32 } }, 0, 23, 23, {{0}}, 0 }, diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c index f9210a1d..b8021635 100644 --- a/backend/tests/test_library.c +++ b/backend/tests/test_library.c @@ -603,8 +603,9 @@ static void test_input_mode(const testCtx *const p_ctx) { int debug = p_ctx->debug; struct item { - const char *data; int input_mode; + int eci; + const char *data; int ret; int expected_input_mode; @@ -612,21 +613,32 @@ static void test_input_mode(const testCtx *const p_ctx) { }; /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { - /* 0*/ { "1234", DATA_MODE, 0, DATA_MODE, "" }, - /* 1*/ { "1234", DATA_MODE | ESCAPE_MODE, 0, DATA_MODE | ESCAPE_MODE, "" }, - /* 2*/ { "1234", UNICODE_MODE, 0, UNICODE_MODE, "" }, - /* 3*/ { "1234", UNICODE_MODE | ESCAPE_MODE, 0, UNICODE_MODE | ESCAPE_MODE, "" }, - /* 4*/ { "[01]12345678901231", GS1_MODE, 0, GS1_MODE, "" }, - /* 5*/ { "[01]12345678901231", GS1_MODE | ESCAPE_MODE, 0, GS1_MODE | ESCAPE_MODE, "" }, - /* 6*/ { "1234", 4 | ESCAPE_MODE, 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*/ { "1234", -1, 0, DATA_MODE, "" }, - /* 8*/ { "1234", DATA_MODE | 0x10, 0, DATA_MODE | 0x10, "" }, /* Unknown flags kept (but ignored) */ - /* 9*/ { "1234", UNICODE_MODE | 0x10, 0, UNICODE_MODE | 0x10, "" }, - /* 10*/ { "[01]12345678901231", GS1_MODE | 0x20, 0, GS1_MODE | 0x20, "" }, + /* 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 */ }; const int data_size = ARRAY_SIZE(data); int i, length, ret; struct zint_symbol *symbol = NULL; + int symbology; testStartSymbol(p_ctx->func_name, &symbol); @@ -637,7 +649,8 @@ static void test_input_mode(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, BARCODE_CODE49 /*Supports GS1*/, data[i].input_mode, -1 /*eci*/, + symbology = data[i].eci != -1 ? BARCODE_AZTEC : BARCODE_CODE49; /* Both support GS1 */ + 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); @@ -1848,6 +1861,7 @@ static void test_stacking(const testCtx *const p_ctx) { struct zint_symbol *symbol = NULL; const char *data = "1"; const char *expected_error = "Error 770: Too many stacked symbols"; + const char *expected_error_raw = "Error 857: Cannot use BARCODE_RAW_TEXT output option if stacking symbols"; int i; (void)p_ctx; @@ -1867,6 +1881,18 @@ static void test_stacking(const testCtx *const p_ctx) { assert_zero(strcmp(symbol->errtxt, expected_error), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, expected_error); + ZBarcode_Clear(symbol); + + ret = ZBarcode_Encode(symbol, TCU(data), 0); + assert_zero(ret, "i:%d ZBarcode_Encode(%s) ret %d != 0 (%s)\n", i, data, ret, symbol->errtxt); + + symbol->output_options |= BARCODE_RAW_TEXT; + ret = ZBarcode_Encode(symbol, TCU(data), 0); + assert_equal(ret, ZINT_ERROR_INVALID_OPTION, "i:%d ZBarcode_Encode ret %d != ZINT_ERROR_INVALID_OPTION (%s)\n", + i, ret, symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, expected_error_raw), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, expected_error_raw); + ZBarcode_Delete(symbol); testFinish(); diff --git a/backend/tests/test_maxicode.c b/backend/tests/test_maxicode.c index 77cec798..264edecf 100644 --- a/backend/tests/test_maxicode.c +++ b/backend/tests/test_maxicode.c @@ -1929,9 +1929,9 @@ static void test_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { DATA_MODE, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 5*/ { DATA_MODE, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 6*/ { UNICODE_MODE, 26, -1, "é", -1, 0, 26, "", -1, 0 }, @@ -2012,9 +2012,9 @@ static void test_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 33, 30, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 33, 30, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 33, 30, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 33, 30, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 33, 30, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 33, 30, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 4*/ { DATA_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 33, 30, {{0}}, 0 }, /* 5*/ { DATA_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 33, 30, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, }; diff --git a/backend/tests/test_pdf417.c b/backend/tests/test_pdf417.c index 5d5439f0..8de10ca2 100644 --- a/backend/tests/test_pdf417.c +++ b/backend/tests/test_pdf417.c @@ -4910,9 +4910,9 @@ static void test_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { BARCODE_PDF417, UNICODE_MODE, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { BARCODE_PDF417, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { BARCODE_PDF417, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { BARCODE_PDF417, UNICODE_MODE, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { BARCODE_PDF417, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { BARCODE_PDF417, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { BARCODE_PDF417, DATA_MODE, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 5*/ { BARCODE_PDF417, DATA_MODE, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 6*/ { BARCODE_PDF417, UNICODE_MODE, 26, -1, "é", -1, 0, 26, "", -1, 0 }, @@ -4922,11 +4922,11 @@ static void test_rt(const testCtx *const p_ctx) { /* 10*/ { BARCODE_HIBC_PDF, UNICODE_MODE, -1, -1, "H123ABC01234567890", -1, 0, 0, "", -1, 0 }, /* 11*/ { BARCODE_HIBC_PDF, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "H123ABC01234567890", -1, 0, 0, "+H123ABC01234567890D", -1, 3 }, /* 12*/ { BARCODE_PDF417COMP, UNICODE_MODE, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 13*/ { BARCODE_PDF417COMP, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 13*/ { BARCODE_PDF417COMP, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* 14*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 15*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 15*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* 16*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 17*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 17*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 18*/ { BARCODE_MICROPDF417, DATA_MODE, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 19*/ { BARCODE_MICROPDF417, DATA_MODE, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 20*/ { BARCODE_MICROPDF417, UNICODE_MODE, 26, -1, "é", -1, 0, 26, "", -1, 0 }, @@ -5010,17 +5010,17 @@ static void test_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { BARCODE_PDF417, UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 8, 103, {{0}}, 0 }, - /* 1*/ { BARCODE_PDF417, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 8, 103, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { BARCODE_PDF417, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 8, 103, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { BARCODE_PDF417, UNICODE_MODE, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 8, 120, {{0}}, 0 }, - /* 3*/ { BARCODE_PDF417, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 8, 120, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 3*/ { BARCODE_PDF417, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 8, 120, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 4*/ { BARCODE_PDF417, DATA_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 8, 120, {{0}}, 0 }, /* 5*/ { BARCODE_PDF417, DATA_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 8, 120, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, /* 6*/ { BARCODE_PDF417COMP, UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 8, 69, {{0}}, 0 }, - /* 7*/ { BARCODE_PDF417COMP, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 8, 69, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 7*/ { BARCODE_PDF417COMP, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 8, 69, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* 8*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 6, 82, {{0}}, 0 }, - /* 9*/ { BARCODE_MICROPDF417, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 6, 82, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 9*/ { BARCODE_MICROPDF417, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 6, 82, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* 10*/ { BARCODE_MICROPDF417, UNICODE_MODE, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 24, 38, {{0}}, 0 }, - /* 11*/ { BARCODE_MICROPDF417, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 24, 38, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 11*/ { BARCODE_MICROPDF417, UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 24, 38, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 12*/ { BARCODE_MICROPDF417, DATA_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 24, 38, {{0}}, 0 }, /* 13*/ { BARCODE_MICROPDF417, DATA_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 24, 38, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, }; diff --git a/backend/tests/test_qr.c b/backend/tests/test_qr.c index 1b659487..4b331e59 100644 --- a/backend/tests/test_qr.c +++ b/backend/tests/test_qr.c @@ -4873,11 +4873,11 @@ static void test_qr_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, -1, "点", -1, ZINT_WARN_NONCOMPLIANT, 0, "", -1, 0 }, - /* 5*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "点", -1, ZINT_WARN_NONCOMPLIANT, 0, "\223\137", -1, 20 }, /* When single segment will try ECI 20 as secondary default */ + /* 5*/ { BARCODE_QRCODE, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "点", -1, ZINT_WARN_NONCOMPLIANT, 0, "点", -1, 20 }, /* When single segment will try ECI 20 as secondary default */ /* 6*/ { BARCODE_QRCODE, DATA_MODE, -1, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 7*/ { BARCODE_QRCODE, DATA_MODE, -1, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 8*/ { BARCODE_QRCODE, DATA_MODE, -1, ZINT_FULL_MULTIBYTE, -1, "\223\137", -1, 0, 0, "", -1, 0 }, @@ -4889,9 +4889,10 @@ static void test_qr_rt(const testCtx *const p_ctx) { /* 14*/ { BARCODE_QRCODE, UNICODE_MODE, 899, -1, -1, "é", -1, 0, 899, "", -1, 0 }, /* 15*/ { BARCODE_QRCODE, UNICODE_MODE, 899, -1, BARCODE_RAW_TEXT, "é", -1, 0, 899, "é", -1, 899 }, /* 16*/ { BARCODE_QRCODE, GS1_MODE, -1, -1, -1, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "", -1, 0 }, - /* 17*/ { BARCODE_QRCODE, GS1_MODE, -1, -1, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "01049123451234591597033130128\03510ABC123", -1, 3 }, - /* 18*/ { BARCODE_HIBC_QR, UNICODE_MODE, -1, -1, -1, "H123ABC01234567890", -1, 0, 0, "", -1, 0 }, - /* 19*/ { BARCODE_HIBC_QR, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "H123ABC01234567890", -1, 0, 0, "+H123ABC01234567890D", -1, 3 }, + /* 17*/ { BARCODE_QRCODE, GS1_MODE, -1, -1, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "01049123451234591597033130128\03510ABC123", -1, 3 }, /* Note raw text ECI set as is converted */ + /* 18*/ { BARCODE_QRCODE, GS1_MODE, 170, -1, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, ZINT_WARN_NONCOMPLIANT, 170, "01049123451234591597033130128\03510ABC123", -1, 170 }, + /* 19*/ { BARCODE_HIBC_QR, UNICODE_MODE, -1, -1, -1, "H123ABC01234567890", -1, 0, 0, "", -1, 0 }, + /* 20*/ { BARCODE_HIBC_QR, UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "H123ABC01234567890", -1, 0, 0, "+H123ABC01234567890D", -1, 3 }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -4967,11 +4968,11 @@ static void test_qr_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 21, 21, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 21, 21, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 21, 21, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, { { TU("点"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, ZINT_WARN_USES_ECI, 21, 21, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("点"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 21, 21, { { TU("点"), 3, 26 }, { TU("\266"), 1, 7 }, {0} }, 2 }, /* When multiple segments, ECI 20 is not used as secondary default, so fails and retries with `get_best_eci()` */ + /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("点"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 21, 21, { { TU("点"), 3, 26 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* When multiple segments, ECI 20 is not used as secondary default, so fails and retries with `get_best_eci()` */ /* 4*/ { UNICODE_MODE, -1, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 21, 21, {{0}}, 0 }, - /* 5*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 21, 21, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 5*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 21, 21, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 6*/ { DATA_MODE, -1, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 21, 21, {{0}}, 0 }, /* 7*/ { DATA_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 21, 21, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, /* 8*/ { DATA_MODE, ZINT_FULL_MULTIBYTE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 21, 21, {{0}}, 0 }, @@ -6687,9 +6688,9 @@ static void test_microqr_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, "点", -1, 0, 0, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "点", -1, 0, 0, "\223\137", -1, 20 }, + /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "点", -1, 0, 0, "点", -1, 20 }, /* 4*/ { DATA_MODE, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 5*/ { DATA_MODE, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 6*/ { DATA_MODE, ZINT_FULL_MULTIBYTE, -1, "\223\137", -1, 0, 0, "", -1, 0 }, @@ -7477,9 +7478,9 @@ static void test_upnqr_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 4 }, + /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 4 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, "Ŕ", -1, 0, 0, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 4 }, + /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, "Ŕ", -1, 0, 0, "Ŕ", -1, 4 }, /* 4*/ { DATA_MODE, -1, "\300", -1, 0, 0, "", -1, 0 }, /* 5*/ { DATA_MODE, BARCODE_RAW_TEXT, "\300", -1, 0, 0, "\300", -1, 4 }, }; @@ -9524,11 +9525,11 @@ static void test_rmqr_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { UNICODE_MODE, -1, -1, -1, "点", -1, ZINT_WARN_NONCOMPLIANT, 0, "", -1, 0 }, - /* 5*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "点", -1, ZINT_WARN_NONCOMPLIANT, 0, "\223\137", -1, 20 }, + /* 5*/ { UNICODE_MODE, -1, -1, BARCODE_RAW_TEXT, "点", -1, ZINT_WARN_NONCOMPLIANT, 0, "点", -1, 20 }, /* 6*/ { DATA_MODE, -1, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 7*/ { DATA_MODE, -1, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 8*/ { DATA_MODE, -1, ZINT_FULL_MULTIBYTE, -1, "\223\137", -1, 0, 0, "", -1, 0 }, @@ -9539,6 +9540,10 @@ static void test_rmqr_rt(const testCtx *const p_ctx) { /* 13*/ { UNICODE_MODE, 26, -1, BARCODE_RAW_TEXT, "é", -1, 0, 26, "é", -1, 26 }, /* 14*/ { UNICODE_MODE, 899, -1, -1, "é", -1, 0, 899, "", -1, 0 }, /* 15*/ { UNICODE_MODE, 899, -1, BARCODE_RAW_TEXT, "é", -1, 0, 899, "é", -1, 899 }, + /* 16*/ { GS1_MODE, -1, -1, -1, "[20]12", -1, 0, 0, "", -1, 0 }, + /* 17*/ { GS1_MODE, -1, -1, BARCODE_RAW_TEXT, "[20]12", -1, 0, 0, "2012", -1, 3 }, + /* 18*/ { GS1_MODE, 32, -1, -1, "[20]12", -1, ZINT_WARN_NONCOMPLIANT, 32, "", -1, 0 }, + /* 19*/ { GS1_MODE, 32, -1, BARCODE_RAW_TEXT, "[20]12", -1, ZINT_WARN_NONCOMPLIANT, 32, "2012", -1, 32 }, /* Note raw text ECI set as is converted */ }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -9614,9 +9619,9 @@ static void test_rmqr_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 11, 27, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 11, 27, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 11, 27, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 11, 43, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 11, 43, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 11, 43, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 4*/ { DATA_MODE, -1, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 11, 43, {{0}}, 0 }, /* 5*/ { DATA_MODE, -1, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 11, 43, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, /* 6*/ { DATA_MODE, ZINT_FULL_MULTIBYTE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 11, 43, {{0}}, 0 }, diff --git a/backend/tests/test_ultra.c b/backend/tests/test_ultra.c index 56f865d8..6b461968 100644 --- a/backend/tests/test_ultra.c +++ b/backend/tests/test_ultra.c @@ -1140,9 +1140,9 @@ static void test_rt(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, -1, "é", -1, 0, 0, "", -1, 0 }, - /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "\351", -1, 3 }, + /* 1*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "é", -1, 0, 0, "é", -1, 3 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, -1, "ก", -1, ZINT_WARN_USES_ECI, 13, "", -1, 0 }, - /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "\241", -1, 13 }, + /* 3*/ { UNICODE_MODE, -1, BARCODE_RAW_TEXT, "ก", -1, ZINT_WARN_USES_ECI, 13, "ก", -1, 13 }, /* 4*/ { DATA_MODE, -1, -1, "\351", -1, 0, 0, "", -1, 0 }, /* 5*/ { DATA_MODE, -1, BARCODE_RAW_TEXT, "\351", -1, 0, 0, "\351", -1, 3 }, /* 6*/ { UNICODE_MODE, 26, -1, "é", -1, 0, 26, "", -1, 0 }, @@ -1151,6 +1151,7 @@ static void test_rt(const testCtx *const p_ctx) { /* 9*/ { UNICODE_MODE, 899, BARCODE_RAW_TEXT, "é", -1, 0, 899, "é", -1, 899 }, /* 10*/ { GS1_MODE, -1, -1, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "", -1, 0 }, /* 11*/ { GS1_MODE, -1, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 0, "01049123451234591597033130128\03510ABC123", -1, 3 }, + /* 12*/ { GS1_MODE, 27, BARCODE_RAW_TEXT, "[01]04912345123459[15]970331[30]128[10]ABC123", -1, 0, 27, "01049123451234591597033130128\03510ABC123", -1, 3 }, /* Note: raw text ECI remains at default 3 */ }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1225,9 +1226,9 @@ static void test_rt_segs(const testCtx *const p_ctx) { /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ static const struct item data[] = { /* 0*/ { UNICODE_MODE, -1, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, {0} }, 0, 13, 15, {{0}}, 0 }, - /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 13, 15, { { TU("\266"), 1, 3 }, { TU("\266"), 1, 7 }, {0} }, 2 }, + /* 1*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 13, 15, { { TU("¶"), 2, 3 }, { TU("Ж"), 2, 7 }, {0} }, 2 }, /* Now UTF-8, not converted */ /* 2*/ { UNICODE_MODE, -1, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 13, 20, {{0}}, 0 }, - /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 13, 20, { { TU("\351\351"), 2, 3 }, { TU("\241\242\317"), 3, 13 }, { TU("\342\342\342"), 3, 9 } }, 3 }, + /* 3*/ { UNICODE_MODE, BARCODE_RAW_TEXT, { { TU("éé"), -1, 0 }, { TU("กขฯ"), -1, 0 }, { TU("βββ"), -1, 0 } }, ZINT_WARN_USES_ECI, 13, 20, { { TU("éé"), 4, 3 }, { TU("กขฯ"), 9, 13 }, { TU("βββ"), 6, 9 } }, 3 }, /* 4*/ { DATA_MODE, -1, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 13, 19, {{0}}, 0 }, /* 5*/ { DATA_MODE, BARCODE_RAW_TEXT, { { TU("¶"), -1, 26 }, { TU("Ж"), -1, 0 }, { TU("\223\137"), -1, 20 } }, 0, 13, 19, { { TU("¶"), 2, 26 }, { TU("\320\226"), 2, 3 }, { TU("\223\137"), 2, 20 } }, 3 }, }; diff --git a/backend/ultra.c b/backend/ultra.c index 922f9489..72c4d30d 100644 --- a/backend/ultra.c +++ b/backend/ultra.c @@ -344,7 +344,7 @@ static float ult_look_ahead_ascii(unsigned char source[], const int length, cons } } - if (!done && source[i] < 0x80) { + if (!done && z_isascii(source[i])) { if (gs1 && source[i] == '\x1D') { cw[codeword_count] = 272; /* FNC1 */ } else { @@ -353,7 +353,7 @@ static float ult_look_ahead_ascii(unsigned char source[], const int length, cons codeword_count++; i++; } - } while (i < length && i < end_char && source[i] < 0x80); + } while (i < length && i < end_char && z_isascii(source[i])); letters_encoded = i - in_locn; if (encoded != NULL) { @@ -802,7 +802,8 @@ static int ult_generate_codewords_segs(struct zint_symbol *symbol, struct zint_s int length = segs[0].length; const int eci = segs[0].eci; const int gs1 = (symbol->input_mode & 0x07) == GS1_MODE; - /* GS1 raw text dealt with by `ZBarcode_Encode_Segs()` */ + /* Raw text dealt with by `ZBarcode_Encode_Segs()`, except for `eci` feedback. + Note not updating `eci` for GS1 mode as not converted */ const int raw_text = !gs1 && (symbol->output_options & BARCODE_RAW_TEXT); for (i = 0; i < seg_count; i++) { @@ -819,7 +820,7 @@ static int ult_generate_codewords_segs(struct zint_symbol *symbol, struct zint_s /* Decide start character codeword (from Table 5) */ symbol_mode = ULT_ASCII_MODE; for (i = 0; i < length; i++) { - if (source[i] >= 0x80) { + if (!z_isascii(source[i])) { symbol_mode = ULT_EIGHTBIT_MODE; break; } @@ -905,16 +906,15 @@ static int ult_generate_codewords_segs(struct zint_symbol *symbol, struct zint_s current_mode = symbol_mode; codeword_count = ult_generate_codewords(symbol, source, length, 0 /*eci*/, gs1, symbol_mode, ¤t_mode, codewords, codeword_count); - - if (raw_text && (z_rt_init_segs(symbol, seg_count) || z_rt_cpy_seg(symbol, 0, &segs[0]))) { - return ZINT_ERROR_MEMORY; /* `z_rt_init_segs()` & `z_rt_cpy_seg()` only fail with OOM */ + if (raw_text && segs[0].eci) { + z_rt_set_seg_eci(symbol, 0, segs[0].eci); } for (i = 1; i < seg_count; i++) { codeword_count = ult_generate_codewords(symbol, segs[i].source, segs[i].length, segs[i].eci, gs1, symbol_mode, ¤t_mode, codewords, codeword_count); - if (raw_text && z_rt_cpy_seg(symbol, i, &segs[i])) { - return ZINT_ERROR_MEMORY; /* `z_rt_cpy_seg()` only fails with OOM */ + if (raw_text && segs[i].eci) { + z_rt_set_seg_eci(symbol, i, segs[i].eci); } } diff --git a/docs/manual.html b/docs/manual.html index f818243e..1afda211 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -333,7 +333,7 @@

Zint Barcode Generator and Zint Barcode Studio User Manual

Version 2.15.0.9

-

August 2025

+

September 2025