Add convenience API funcs ZBarcode_UTF8_To_ECI() and

`ZBarcode_Dest_Len_ECI()`, primarily for ZXingC++ but also useful
  in general
This commit is contained in:
gitlost 2025-03-02 20:50:55 +00:00
parent 99f94b1027
commit d0465375bb
12 changed files with 647 additions and 167 deletions

View file

@ -647,6 +647,19 @@ static const unsigned short int windows_1256[] = {
0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2
};
/* Taken from https://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT */
static const unsigned short int cp437[] = {
0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
};
static void test_utf8_to_eci_sb(const testCtx *const p_ctx) {
struct item {
@ -674,6 +687,7 @@ static void test_utf8_to_eci_sb(const testCtx *const p_ctx) {
/* 16*/ { 22, windows_1251 },
/* 17*/ { 23, windows_1252 },
/* 18*/ { 24, windows_1256 },
/* 19*/ { 2, cp437 },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
@ -749,8 +763,8 @@ static void test_utf8_to_eci_ascii(const testCtx *const p_ctx) {
/* 16*/ { 170, "~", -1, ZINT_ERROR_INVALID_DATA },
/* 17*/ { 170, "\302\200", -1, ZINT_ERROR_INVALID_DATA },
/* 18*/ { 170, "~", -1, ZINT_ERROR_INVALID_DATA },
/* 19*/ { 1, "A", -1, ZINT_ERROR_INVALID_DATA },
/* 20*/ { 2, "A", -1, ZINT_ERROR_INVALID_DATA },
/* 19*/ { 1, "A", -1, 0 }, /* Now succeeds (maps to ISO/ECI 8859-1 for libzueci compatibility) */
/* 20*/ { 2, "A", -1, 0 }, /* Now succeeds (maps to CP437 for libzueci compatibility) */
/* 21*/ { 14, "A", -1, ZINT_ERROR_INVALID_DATA },
/* 22*/ { 19, "A", -1, ZINT_ERROR_INVALID_DATA },
/* 23*/ { 26, "A", -1, ZINT_ERROR_INVALID_DATA },

View file

@ -1,3 +1,34 @@
/*
libzint - the open source barcode library
Copyright (C) 2021-2025 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* SPDX-License-Identifier: BSD-3-Clause */
/* Generated by gen_test_tab.php from KSX1001.TXT */
static const unsigned int test_ksx1001_tab[] = {
0x222E, 0x00A1,
@ -8292,3 +8323,5 @@ static const unsigned int test_ksx1001_tab_ind[] = {
15712,
16248,
};
/* vim: set ts=4 sw=4 et : */

View file

@ -2177,6 +2177,116 @@ static void test_xdimdp_from_scale(const testCtx *const p_ctx) {
testFinish();
}
static void test_utf8_to_eci(const testCtx *const p_ctx) {
struct item {
int eci;
const char *data;
int length;
int ret_dest;
int expected_dest_length;
int ret;
const char *expected;
int expected_length;
};
/* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */
static const struct item data[] = {
/* 0*/ { 3, "1234", -1, 0, 4, 0, "1234", -1 },
/* 1*/ { 3, "1234", 0, 0, 4, 0, "1234", -1 }, /* Zero length allowed */
/* 2*/ { 3, "1234", -2, 0, 4, 0, "1234", -1 }, /* Negative length allowed */
/* 3*/ { 3, "", -1, 0, 0, 0, "", 0 }, /* Empty allowed */
/* 4*/ { 3, NULL, -1, ZINT_ERROR_INVALID_OPTION, 0, -1, "", -1 },
/* 5*/ { -1, "1234", -1, ZINT_ERROR_INVALID_OPTION, 0, -1, "", -1 },
/* 6*/ { 0, "1234", -1, 0, 4, 0, "1234", -1 },
/* 7*/ { 1, "1234", -1, 0, 4, 0, "1234", -1 },
/* 8*/ { 2, "1234", -1, 0, 4, 0, "1234", -1 },
/* 9*/ { 0, "1234é", -1, 0, 6, 0, "1234\202", 5 }, /* CP437 */
/* 10*/ { 1, "1234é", -1, 0, 6, 0, "1234\351", 5 }, /* Same as ISO/IEC 8859-1 */
/* 11*/ { 2, "1234é", -1, 0, 6, 0, "1234\202", 5 }, /* CP437 */
/* 12*/ { 3, "1234é", -1, 0, 6, 0, "1234\351", 5 },
/* 13*/ { 4, "1234˘", -1, 0, 6, 0, "1234\242", 5 }, /* ISO/IEC 8859-2 */
/* 14*/ { 5, "1234Ħ", -1, 0, 6, 0, "1234\241", 5 }, /* ISO/IEC 8859-3 */
/* 15*/ { 6, "1234ĸ", -1, 0, 6, 0, "1234\242", 5 }, /* ISO/IEC 8859-4 */
/* 16*/ { 7, "1234Ё", -1, 0, 6, 0, "1234\241", 5 }, /* ISO/IEC 8859-5 */
/* 17*/ { 8, "1234ء", -1, 0, 6, 0, "1234\301", 5 }, /* ISO/IEC 8859-6 */
/* 18*/ { 9, "1234π", -1, 0, 6, 0, "1234\360", 5 }, /* ISO/IEC 8859-7 */
/* 19*/ { 11, "1234ğ", -1, 0, 6, 0, "1234\360", 5 }, /* ISO/IEC 8859-9 */
/* 20*/ { 12, "1234Ŋ", -1, 0, 6, 0, "1234\257", 5 }, /* ISO/IEC 8859-10 */
/* 21*/ { 13, "1234", -1, 0, 7, 0, "1234\360", 5 }, /* ISO/IEC 8859-11 */
/* 22*/ { 14, "1234", -1, ZINT_ERROR_INVALID_OPTION, 0, -1, "", -1 },
/* 23*/ { 15, "1234š", -1, 0, 6, 0, "1234\360", 5 }, /* ISO/IEC 8859-13 */
/* 24*/ { 16, "1234ŵ", -1, 0, 6, 0, "1234\360", 5 }, /* ISO/IEC 8859-14 */
/* 25*/ { 17, "1234œ", -1, 0, 6, 0, "1234\275", 5 }, /* ISO/IEC 8859-15 */
/* 26*/ { 18, "1234Ł", -1, 0, 6, 0, "1234\243", 5 }, /* ISO/IEC 8859-16 */
/* 27*/ { 19, "1234", -1, ZINT_ERROR_INVALID_OPTION, 0, -1, "", -1 },
/* 28*/ { 20, "1234点", -1, 0, 7, 0, "1234\223\137", 6 }, /* Shift JIS */
/* 29*/ { 20, "1234¥", -1, 0, 6, 0, "1234\\", 5 }, /* Shift JIS - Yen sign -> backslash */
/* 30*/ { 20, "1234~", -1, 0, 5, ZINT_ERROR_INVALID_DATA, "", -1 }, /* Shift JIS - no mapping for tilde */
/* 31*/ { 20, "1234\\", -1, 0, 6, 0, "1234\201\137", -1 }, /* Shift JIS - backslash -> full-width reverse solidus */
/* 32*/ { 21, "1234Ą", -1, 0, 6, 0, "1234\245", 5 }, /* Windows-1250 */
/* 33*/ { 22, "1234ѓ", -1, 0, 6, 0, "1234\203", 5 }, /* Windows-1251 */
/* 34*/ { 23, "1234ƒ", -1, 0, 6, 0, "1234\203", 5 }, /* Windows-1252 */
/* 35*/ { 24, "1234پ", -1, 0, 6, 0, "1234\201", 5 }, /* Windows-1256 */
/* 36*/ { 25, "1234é", -1, 0, 10, 0, "\0001\0002\0003\0004\000\351", 10 }, /* UTF-16BE */
/* 37*/ { 26, "1234é", -1, 0, 6, 0, "1234é", 6 }, /* UTF-8 */
/* 38*/ { 27, "1234é", -1, 0, 6, ZINT_ERROR_INVALID_DATA, "", -1 }, /* ASCII */
/* 39*/ { 27, "1234", -1, 0, 4, 0, "1234", -1 }, /* ASCII */
/* 40*/ { 28, "1234_", -1, 0, 7, 0, "1234\241\304", 6 }, /* Big5 */
/* 41*/ { 29, "1234崂", -1, 0, 7, 0, "1234\341\300", 6 }, /* GB 2312 */
/* 42*/ { 30, "1234가", -1, 0, 7, 0, "1234\260\241", 6 }, /* EUC-KR */
/* 43*/ { 31, "1234郎", -1, 0, 7, 0, "1234\375\234", 6 }, /* GBK */
/* 44*/ { 32, "1234崂", -1, 0, 14, 0, "1234\341\300", 6 }, /* GB 18030 */
/* 45*/ { 33, "1234é", -1, 0, 10, 0, "1\0002\0003\0004\000\351\000", 10 }, /* UTF-16LE */
/* 46*/ { 34, "1234é", -1, 0, 20, 0, "\000\000\0001\000\000\0002\000\000\0003\000\000\0004\000\000\000\351", 20 }, /* UTF-16BE */
/* 47*/ { 35, "1234é", -1, 0, 20, 0, "1\000\000\0002\000\000\0003\000\000\0004\000\000\000\351\000\000\000", 20 }, /* UTF-16LE */
/* 48*/ { 170, "1234", -1, 0, 4, 0, "1234", 4 }, /* ISO 646 Invariant */
/* 49*/ { 170, "1234#", -1, 0, 5, ZINT_ERROR_INVALID_DATA, "", -1 }, /* ISO 646 Invariant */
/* 50*/ { 899, "1234\000\127\302\200ÿ", 10, 0, 10, 0, "1234\000\127\200\377", 8 }, /* Binary */
};
const int data_size = ARRAY_SIZE(data);
int i, length, ret;
int expected_length;
testStart("test_utf8_to_eci");
for (i = 0; i < data_size; i++) {
int ret_dest;
unsigned char dest[1024];
int dest_length;
if (testContinue(p_ctx, i)) continue;
length = data[i].length == -1 && data[i].data ? (int) strlen(data[i].data) : data[i].length;
ret_dest = ZBarcode_Dest_Len_ECI(data[i].eci, TCU(data[i].data), length, &dest_length);
assert_equal(ret_dest, data[i].ret_dest, "i:%d ZBarcode_Dest_Len_ECI(%d, %s) ret_dest %d != %d\n",
i, data[i].eci, data[i].data, ret_dest, data[i].ret_dest);
if (ret_dest < ZINT_ERROR) {
assert_equal(dest_length, data[i].expected_dest_length,
"i:%d ZBarcode_Dest_Len_ECI dest_length %d != expected_dest_length %d\n",
i, dest_length, data[i].expected_dest_length);
expected_length = data[i].expected_length == -1 ? (int) strlen(data[i].expected) : data[i].expected_length;
ret = ZBarcode_UTF8_To_ECI(data[i].eci, TCU(data[i].data), length, dest, &dest_length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_UTF8_To_ECI(%d, %s) ret %d != %d\n",
i, data[i].eci, data[i].data, ret, data[i].ret);
if (ret < ZINT_ERROR) {
assert_equal(dest_length, expected_length,
"i:%d ZBarcode_UTF8_To_ECI dest_length %d != expected_length %d\n",
i, dest_length, expected_length);
#if 0
printf("dest_length %d\n", dest_length); debug_print_escape(TCU(dest), dest_length, NULL); printf("\n");
#endif
assert_zero(memcmp(dest, data[i].expected, expected_length), "i:%d memcmp(\"%s\", \"%s\", %d) != 0\n",
i, dest, data[i].expected, expected_length);
}
}
}
testFinish();
}
int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func */
@ -2205,6 +2315,7 @@ int main(int argc, char *argv[]) {
{ "test_reset", test_reset },
{ "test_scale_from_xdimdp", test_scale_from_xdimdp },
{ "test_xdimdp_from_scale", test_xdimdp_from_scale },
{ "test_utf8_to_eci", test_utf8_to_eci },
};
testRun(argc, argv, funcs, ARRAY_SIZE(funcs));