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
@@ -4369,9 +4369,9 @@ Segments for the format), one for each segment specified, the size
of the array being set in raw_seg_count - which will always
be at least one.
The source, length and eci
-members of zint_seg will be set accordingly - the data in
-source, the data length in length, and the
-character set the data is in (UTF-8 data will be converted) in
+members of zint_seg will be set accordingly - the
+unconverted data in source, the data length in
+length, and the character set the data was converted to in
eci. Any check characters encoded will be included, and for GS1 data any
@@ -4382,6 +4382,11 @@ as will EAN-8 but only if it has an add-on (otherwise it will remain at
separator). GS1 Composite data if any will be separated from the primary
data (including any EAN/UPC add-ons) by a pipe (|)
character.
+The source member is not NUL-terminated, and is not
+converted: if input_mode is DATA_MODE, it
+remains in binary; otherwise it will be in UTF-8. The UTF-8 source may
+be converted to the character set of the corresponding eci
+member using the two helper functions discussed next.
5.17 UTF-8 to ECI
convenience functions
As a convenience the conversion done by Zint from UTF-8 to ECIs is
@@ -8359,7 +8364,7 @@ bcsample source code
PNG: The Definitive Guide and wpng source code by Greg Reolofs
PDF417 specification and pdf417 source code by Grand Zebu
Barcode Reference, TBarCode/X User Documentation and TBarCode/X
-demonstration program from Tec-It
+demonstration program from TEC-IT
IEC16022 source code by Stefan Schmidt et al
United States Postal Service Specification USPS-B-3200
Adobe Systems Incorporated Encapsulated PostScript File Format
@@ -9737,7 +9742,7 @@ class="footnote-back" role="doc-backlink">↩︎
characters undefined: #, $, @,
[, \, ], ^,
`, {, |, },
-~.
BARCODE_MEMORY_FILE textual formats EPS and SVG will
have Unix newlines (LF) on both Windows and Unix, i.e. not CR+LF on
diff --git a/docs/manual.pmd b/docs/manual.pmd
index 32a5f3a4..2e595d0d 100644
--- a/docs/manual.pmd
+++ b/docs/manual.pmd
@@ -1,6 +1,6 @@
% Zint Barcode Generator and Zint Barcode Studio User Manual
% Version 2.15.0.9
-% August 2025
+% September 2025
# 1. Introduction
@@ -1364,7 +1364,7 @@ ECI Code Character Encoding Scheme (ISO/IEC 8859 schemes include ASCII)
Table: {#tbl:eci_codes tag=": ECI Codes"}
[^7]: ISO/IEC 646 Invariant is a subset of ASCII with 12 characters undefined:
-`#`, `$`, `@`, `[`, `\`, `]`, `^`, `` ` ``, `{`, `|`, `}`, `~`.
+`#`, `$`, `@`, `[`, `\`, `]`, `^`, `` ` ``, `{`, `|`, `}`, `~` (tilde).
An ECI value of 0 does not encode any ECI information in the code symbol (unless
the data contains non-default character set characters). In this case, the
@@ -2696,14 +2696,19 @@ Segments] for the format), one for each segment specified, the size of the array
being set in `raw_seg_count` - which will always be at least one.
The `source`, `length` and `eci` members of `zint_seg` will be set accordingly -
-the data in `source`, the data length in `length`, and the character set the
-data is in (UTF-8 data will be converted) in `eci`. Any check characters encoded
-will be included,[^16] and for GS1 data any `FNC1` separators will be
-represented as `GS` (ASCII 29) characters. UPC-A and UPC-E data will be expanded
-to EAN-13, as will EAN-8 but only if it has an add-on (otherwise it will remain
-at 8 digits), and any add-ons will follow the 13 digits directly (no separator).
-GS1 Composite data if any will be separated from the primary data (including any
-EAN/UPC add-ons) by a pipe (`|`) character.
+the unconverted data in `source`, the data length in `length`, and the character
+set the data was converted to in `eci`. Any check characters encoded will be
+included,[^16] and for GS1 data any `FNC1` separators will be represented as
+`GS` (ASCII 29) characters. UPC-A and UPC-E data will be expanded to EAN-13, as
+will EAN-8 but only if it has an add-on (otherwise it will remain at 8 digits),
+and any add-ons will follow the 13 digits directly (no separator). GS1 Composite
+data if any will be separated from the primary data (including any EAN/UPC
+add-ons) by a pipe (`|`) character.
+
+The `source` member is not NUL-terminated, and is not converted: if `input_mode`
+is `DATA_MODE`, it remains in binary; otherwise it will be in UTF-8. The UTF-8
+source may be converted to the character set of the corresponding `eci` member
+using the two helper functions discussed next.
[^15]: DotCode, Han Xin, Micro QR Code, QR Code and UPNQR have variable masks.
Rectangular Micro QR Code has a fixed mask (4).
@@ -4992,7 +4997,7 @@ Below is a list of some of the sources used in rough chronological order:
- PNG: The Definitive Guide and wpng source code by Greg Reolofs
- PDF417 specification and pdf417 source code by Grand Zebu
- Barcode Reference, TBarCode/X User Documentation and TBarCode/X demonstration
- program from Tec-It
+ program from TEC-IT
- IEC16022 source code by Stefan Schmidt et al
- United States Postal Service Specification USPS-B-3200
- Adobe Systems Incorporated Encapsulated PostScript File Format Specification
diff --git a/docs/manual.txt b/docs/manual.txt
index 86d758d5..38cb9583 100644
--- a/docs/manual.txt
+++ b/docs/manual.txt
@@ -1,6 +1,6 @@
Zint Barcode Generator and Zint Barcode Studio User Manual
Version 2.15.0.9
-August 2025
+September 2025
*******************************************************************************
* For reference the following is a text-only version of the Zint manual, *
@@ -2643,14 +2643,19 @@ for the format), one for each segment specified, the size of the array being set
in raw_seg_count - which will always be at least one.
The source, length and eci members of zint_seg will be set accordingly - the
-data in source, the data length in length, and the character set the data is in
-(UTF-8 data will be converted) in eci. Any check characters encoded will be
-included,[16] and for GS1 data any FNC1 separators will be represented as GS
-(ASCII 29) characters. UPC-A and UPC-E data will be expanded to EAN-13, as will
-EAN-8 but only if it has an add-on (otherwise it will remain at 8 digits), and
-any add-ons will follow the 13 digits directly (no separator). GS1 Composite
-data if any will be separated from the primary data (including any EAN/UPC
-add-ons) by a pipe (|) character.
+unconverted data in source, the data length in length, and the character set the
+data was converted to in eci. Any check characters encoded will be included,[16]
+and for GS1 data any FNC1 separators will be represented as GS (ASCII 29)
+characters. UPC-A and UPC-E data will be expanded to EAN-13, as will EAN-8 but
+only if it has an add-on (otherwise it will remain at 8 digits), and any add-ons
+will follow the 13 digits directly (no separator). GS1 Composite data if any
+will be separated from the primary data (including any EAN/UPC add-ons) by a
+pipe (|) character.
+
+The source member is not NUL-terminated, and is not converted: if input_mode is
+DATA_MODE, it remains in binary; otherwise it will be in UTF-8. The UTF-8 source
+may be converted to the character set of the corresponding eci member using the
+two helper functions discussed next.
5.17 UTF-8 to ECI convenience functions
@@ -4784,7 +4789,7 @@ Below is a list of some of the sources used in rough chronological order:
- PNG: The Definitive Guide and wpng source code by Greg Reolofs
- PDF417 specification and pdf417 source code by Grand Zebu
- Barcode Reference, TBarCode/X User Documentation and TBarCode/X demonstration
- program from Tec-It
+ program from TEC-IT
- IEC16022 source code by Stefan Schmidt et al
- United States Postal Service Specification USPS-B-3200
- Adobe Systems Incorporated Encapsulated PostScript File Format Specification
@@ -5755,7 +5760,7 @@ matrix barcodes.
the yen sign (¥), and tilde (~) to overline (U+203E).
[7] ISO/IEC 646 Invariant is a subset of ASCII with 12 characters undefined: #,
-$, @, [, \, ], ^, `, {, |, }, ~.
+$, @, [, \, ], ^, `, {, |, }, ~ (tilde).
[8] BARCODE_MEMORY_FILE textual formats EPS and SVG will have Unix newlines (LF)
on both Windows and Unix, i.e. not CR+LF on Windows.