comparison mupdf-source/thirdparty/zint/backend/tests/test_big5.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /*
2 libzint - the open source barcode library
3 Copyright (C) 2021-2022 Robin Stuart <rstuart114@gmail.com>
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. Neither the name of the project nor the names of its contributors
15 may be used to endorse or promote products derived from this software
16 without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 SUCH DAMAGE.
29 */
30 /* SPDX-License-Identifier: BSD-3-Clause */
31
32 #include "testcommon.h"
33 #include "test_big5_tab.h"
34 /* For local "private" testing using previous libiconv adaptation, not included for licensing reasons */
35 #if 0
36 #define TEST_JUST_SAY_GNO
37 #endif
38 #ifdef TEST_JUST_SAY_GNO
39 #include "../just_say_gno/big5_gnu.h"
40 #endif
41
42 INTERNAL int u_big5_test(const unsigned int u, unsigned char *dest);
43
44 /* Version of `u_big5()` taking unsigned int destination for backward-compatible testing */
45 static int u_big5_int(unsigned int u, unsigned int *d) {
46 unsigned char dest[2];
47 int ret = u_big5_test(u, dest);
48 if (ret) {
49 *d = ret == 1 ? dest[0] : ((dest[0] << 8) | dest[1]);
50 }
51 return ret;
52 }
53
54 /* As control convert to Big5 using simple table generated from
55 https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT plus simple processing */
56 static int u_big5_int2(unsigned int u, unsigned int *dest) {
57 int tab_length = ARRAY_SIZE(test_big5_tab);
58 int start_i = test_big5_tab_ind[u >> 10];
59 int end_i = start_i + 0x800 > tab_length ? tab_length : start_i + 0x800;
60 int i;
61 if (u < 0x80) {
62 *dest = u;
63 return 1;
64 }
65 for (i = start_i; i < end_i; i += 2) {
66 if (test_big5_tab[i + 1] == u) {
67 *dest = test_big5_tab[i];
68 return *dest > 0xFF ? 2 : 1;
69 }
70 }
71 return 0;
72 }
73
74 #include <time.h>
75
76 #define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC)
77 #define TEST_PERF_RATIO(a1, a2) (a2 ? TEST_PERF_TIME(a1) / TEST_PERF_TIME(a2) : 0)
78
79 #ifdef TEST_JUST_SAY_GNO
80 #define TEST_INT_PERF_ITERATIONS 100
81 #endif
82
83 static void test_u_big5_int(const testCtx *const p_ctx) {
84 int debug = p_ctx->debug;
85
86 unsigned int i;
87 int ret, ret2;
88 unsigned int val, val2;
89
90 #ifdef TEST_JUST_SAY_GNO
91 int j;
92 clock_t start;
93 clock_t total = 0, total_gno = 0;
94 #else
95 (void)debug;
96 #endif
97
98 testStart("test_u_big5_int");
99
100 #ifdef TEST_JUST_SAY_GNO
101 if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
102 printf("test_u_big5_int perf iterations: %d\n", TEST_INT_PERF_ITERATIONS);
103 }
104 #endif
105
106 for (i = 0; i < 0xFFFE; i++) {
107 if (i >= 0xD800 && i < 0xE000) { /* UTF-16 surrogates */
108 continue;
109 }
110 if (testContinue(p_ctx, i)) continue;
111 val = val2 = 0;
112 ret = u_big5_int(i, &val);
113 ret2 = u_big5_int2(i, &val2);
114 assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
115 if (ret2) {
116 assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
117 }
118 #ifdef TEST_JUST_SAY_GNO
119 if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
120 val2 = 0;
121 ret2 = big5_wctomb_zint(&val2, i);
122 } else {
123 for (j = 0; j < TEST_INT_PERF_ITERATIONS; j++) {
124 val = val2 = 0;
125
126 start = clock();
127 ret = u_big5_int(i, &val);
128 total += clock() - start;
129
130 start = clock();
131 ret2 = big5_wctomb_zint(&val2, i);
132 total_gno += clock() - start;
133 }
134 }
135
136 assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
137 if (ret2) {
138 assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
139 }
140 #endif
141 }
142
143 #ifdef TEST_JUST_SAY_GNO
144 if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
145 printf("test_u_big5_int perf totals: new % 8gms, gno % 8gms ratio %g\n",
146 TEST_PERF_TIME(total), TEST_PERF_TIME(total_gno), TEST_PERF_RATIO(total, total_gno));
147 }
148 #endif
149
150 testFinish();
151 }
152
153 /* Convert UTF-8 string to Big5 and place in array of ints */
154 static int big5_utf8(struct zint_symbol *symbol, const unsigned char source[], int *p_length,
155 unsigned int *b5data) {
156 int error_number;
157 unsigned int i, length;
158 unsigned int *utfdata = (unsigned int *) z_alloca(sizeof(unsigned int) * (*p_length + 1));
159
160 error_number = utf8_to_unicode(symbol, source, utfdata, p_length, 0 /*disallow_4byte*/);
161 if (error_number != 0) {
162 return error_number;
163 }
164
165 for (i = 0, length = *p_length; i < length; i++) {
166 if (!u_big5_int(utfdata[i], b5data + i)) {
167 strcpy(symbol->errtxt, "800: Invalid character in input data");
168 return ZINT_ERROR_INVALID_DATA;
169 }
170 }
171
172 return 0;
173 }
174
175 static void test_big5_utf8(const testCtx *const p_ctx) {
176
177 struct item {
178 char *data;
179 int length;
180 int ret;
181 int ret_length;
182 unsigned int expected_b5data[20];
183 char *comment;
184 };
185 /*
186 _ U+FF3F fullwidth low line, not in ISO/Win, in Big5 0xA1C4, UTF-8 EFBCBF
187 ╴ U+2574 drawings box light left, not in ISO/Win, not in original Big5 but in "Big5-2003" as 0xA15A, UTF-8 E295B4
188 */
189 /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */
190 struct item data[] = {
191 /* 0*/ { "_", -1, 0, 1, { 0xA1C4 }, "" },
192 /* 1*/ { "╴", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "" },
193 };
194 int data_size = ARRAY_SIZE(data);
195 int i, length, ret;
196
197 struct zint_symbol symbol = {0};
198 unsigned int b5data[20];
199
200 testStart("test_big5_utf8");
201
202 for (i = 0; i < data_size; i++) {
203 int ret_length;
204
205 if (testContinue(p_ctx, i)) continue;
206
207 length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length;
208 ret_length = length;
209
210 ret = big5_utf8(&symbol, (unsigned char *) data[i].data, &ret_length, b5data);
211 assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol.errtxt);
212 if (ret == 0) {
213 int j;
214 assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %d != %d\n", i, ret_length, data[i].ret_length);
215 for (j = 0; j < ret_length; j++) {
216 assert_equal(b5data[j], data[i].expected_b5data[j], "i:%d b5data[%d] %04X != %04X\n", i, j, b5data[j], data[i].expected_b5data[j]);
217 }
218 }
219 }
220
221 testFinish();
222 }
223
224 int main(int argc, char *argv[]) {
225
226 testFunction funcs[] = { /* name, func */
227 { "test_u_big5_int", test_u_big5_int },
228 { "test_big5_utf8", test_big5_utf8 },
229 };
230
231 testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
232
233 testReport();
234
235 return 0;
236 }
237
238 /* vim: set ts=4 sw=4 et : */