comparison mupdf-source/thirdparty/zint/backend/code1.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 /* code1.c - USS Code One */
2 /*
3 libzint - the open source barcode library
4 Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3. Neither the name of the project nor the names of its contributors
16 may be used to endorse or promote products derived from this software
17 without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 SUCH DAMAGE.
30 */
31 /* SPDX-License-Identifier: BSD-3-Clause */
32
33 #include <assert.h>
34 #include <math.h>
35 #include <stdio.h>
36 #include "common.h"
37 #include "code1.h"
38 #include "reedsol.h"
39 #include "large.h"
40
41 #define C1_MAX_CWS 1480 /* Max data codewords for Version H */
42 #define C1_MAX_CWS_S "1480" /* String version of above */
43 #define C1_MAX_ECCS 560 /* Max ECC codewords for Version H */
44
45 #define C1_ASCII 1
46 #define C1_C40 2
47 #define C1_DECIMAL 3
48 #define C1_TEXT 4
49 #define C1_EDI 5
50 #define C1_BYTE 6
51
52 /* Add solid bar */
53 static void c1_horiz(struct zint_symbol *symbol, const int row_no, const int full) {
54 int i;
55
56 if (full) {
57 for (i = 0; i < symbol->width; i++) {
58 set_module(symbol, row_no, i);
59 }
60 } else {
61 for (i = 1; i < symbol->width - 1; i++) {
62 set_module(symbol, row_no, i);
63 }
64 }
65 }
66
67 /* Central recognition pattern for Versions A-H */
68 static void c1_central_finder(struct zint_symbol *symbol, const int start_row, const int row_count,
69 const int full_rows) {
70 int i;
71
72 for (i = 0; i < row_count; i++) {
73 if (i < full_rows) {
74 c1_horiz(symbol, start_row + (i * 2), 1);
75 } else {
76 c1_horiz(symbol, start_row + (i * 2), 0);
77 if (i != row_count - 1) {
78 set_module(symbol, start_row + (i * 2) + 1, 1);
79 set_module(symbol, start_row + (i * 2) + 1, symbol->width - 2);
80 }
81 }
82 }
83 }
84
85 /* Add solid column */
86 static void c1_vert(struct zint_symbol *symbol, const int column, const int height, const int top) {
87 int i;
88
89 if (top) {
90 for (i = 0; i < height; i++) {
91 set_module(symbol, i, column);
92 }
93 } else {
94 for (i = 0; i < height; i++) {
95 set_module(symbol, symbol->rows - i - 1, column);
96 }
97 }
98 }
99
100 /* Add bump to the right of the vertical recognition pattern column (Versions A-H) */
101 static void c1_spigot(struct zint_symbol *symbol, const int row_no) {
102 int i;
103
104 for (i = symbol->width - 1; i > 0; i--) {
105 if (module_is_set(symbol, row_no, i - 1)) {
106 set_module(symbol, row_no, i);
107 }
108 }
109 }
110
111 /* Is basic (non-shifted) C40? */
112 static int c1_isc40(const unsigned char input) {
113 if (z_isdigit(input) || z_isupper(input) || input == ' ') {
114 return 1;
115 }
116 return 0;
117 }
118
119 /* Is basic (non-shifted) TEXT? */
120 static int c1_istext(const unsigned char input) {
121 if (z_isdigit(input) || z_islower(input) || input == ' ') {
122 return 1;
123 }
124 return 0;
125 }
126
127 /* Is basic (non-shifted) C40/TEXT? */
128 static int c1_isc40text(const int current_mode, const unsigned char input) {
129 return current_mode == C1_C40 ? c1_isc40(input) : c1_istext(input);
130 }
131
132 /* EDI characters are uppercase alphanumerics plus space plus EDI terminator (CR) plus 2 EDI separator chars */
133 static int c1_isedi(const unsigned char input) {
134
135 if (c1_isc40(input)) {
136 return 1;
137 }
138 if (input == 13 || input == '*' || input == '>') {
139 return 1;
140 }
141
142 return 0;
143 }
144
145 /* Whether Step Q4bi applies, i.e. if one of the 3 EDI terminator/separator chars appears before a non-EDI char */
146 static int c1_is_step_Q4bi_applicable(const unsigned char source[], const int length, const int position) {
147 int i;
148
149 for (i = position; i < length && c1_isedi(source[i]); i++) {
150 if (source[i] == 13 || source[i] == '*' || source[i] == '>') {
151 return 1;
152 }
153 }
154
155 return 0;
156 }
157
158 /* Character counts are multiplied by this, so as to be whole integer divisible by 2 and 3 */
159 #define C1_MULT 6
160
161 #define C1_MULT_1_DIV_2 3
162 #define C1_MULT_2_DIV_3 4
163 #define C1_MULT_1 6
164 #define C1_MULT_4_DIV_3 8
165 #define C1_MULT_2 12
166 #define C1_MULT_8_DIV_3 16
167 #define C1_MULT_3 18
168 #define C1_MULT_10_DIV_3 20
169 #define C1_MULT_13_DIV_3 26
170
171 #define C1_MULT_MINUS_1 5
172 #define C1_MULT_CEIL(n) ((((n) + C1_MULT_MINUS_1) / C1_MULT) * C1_MULT)
173
174 /* AIM USS Code One Annex D Steps J-R */
175 static int c1_look_ahead_test(const unsigned char source[], const int length, const int position,
176 const int current_mode, const int gs1) {
177 int ascii_count, c40_count, text_count, edi_count, byte_count;
178 int ascii_rnded, c40_rnded, text_rnded, edi_rnded, byte_rnded;
179 int cnt_1;
180 int sp;
181
182 /* Step J1 */
183 if (current_mode == C1_ASCII) {
184 ascii_count = 0;
185 c40_count = C1_MULT_1;
186 text_count = C1_MULT_1;
187 edi_count = C1_MULT_1;
188 byte_count = C1_MULT_2;
189 } else {
190 ascii_count = C1_MULT_1;
191 c40_count = C1_MULT_2;
192 text_count = C1_MULT_2;
193 edi_count = C1_MULT_2;
194 byte_count = C1_MULT_3;
195 }
196
197 switch (current_mode) {
198 case C1_C40: c40_count = 0; /* Step J2 */
199 break;
200 case C1_TEXT: text_count = 0; /* Step J3 */
201 break;
202 case C1_EDI: edi_count = 0; /* Missing in spec */
203 break;
204 case C1_BYTE: byte_count = 0; /* Step J4 */
205 break;
206 }
207
208 for (sp = position; sp < length; sp++) {
209 const unsigned char c = source[sp];
210 const int is_extended = c & 0x80;
211
212 /* Step L */
213 if (z_isdigit(c)) {
214 ascii_count += C1_MULT_1_DIV_2; /* Step L1 */
215 } else {
216 if (is_extended) {
217 ascii_count = ceilf(ascii_count) + C1_MULT_2; /* Step L2 */
218 } else {
219 ascii_count = ceilf(ascii_count) + C1_MULT_1; /* Step L3 */
220 }
221 }
222
223 /* Step M */
224 if (c1_isc40(c)) {
225 c40_count += C1_MULT_2_DIV_3; /* Step M1 */
226 } else if (is_extended) {
227 c40_count += C1_MULT_8_DIV_3; /* Step M2 */
228 } else {
229 c40_count += C1_MULT_4_DIV_3; /* Step M3 */
230 }
231
232 /* Step N */
233 if (c1_istext(c)) {
234 text_count += C1_MULT_2_DIV_3; /* Step N1 */
235 } else if (is_extended) {
236 text_count += C1_MULT_8_DIV_3; /* Step N2 */
237 } else {
238 text_count += C1_MULT_4_DIV_3; /* Step N3 */
239 }
240
241 /* Step O */
242 if (c1_isedi(c)) {
243 edi_count += C1_MULT_2_DIV_3; /* Step O1 */
244 } else if (is_extended) {
245 edi_count += C1_MULT_13_DIV_3; /* Step O2 */
246 } else {
247 edi_count += C1_MULT_10_DIV_3; /* Step O3 */
248 }
249
250 /* Step P */
251 if (gs1 && c == '\x1D') {
252 byte_count += C1_MULT_3; /* Step P1 */
253 } else {
254 byte_count += C1_MULT_1; /* Step P2 */
255 }
256
257 /* If at least 4 characters processed */
258 /* NOTE: different than spec, where it's at least 3, but that ends up suppressing C40/TEXT/EDI.
259 BWIPP also uses 4 (cf very similar Data Matrix ISO/IEC 16022:2006 Annex P algorithm) */
260 if (sp >= position + 3) {
261 /* Step Q */
262 ascii_rnded = C1_MULT_CEIL(ascii_count);
263 c40_rnded = C1_MULT_CEIL(c40_count);
264 text_rnded = C1_MULT_CEIL(text_count);
265 edi_rnded = C1_MULT_CEIL(edi_count);
266 byte_rnded = C1_MULT_CEIL(byte_count);
267
268 cnt_1 = byte_count + C1_MULT_1;
269 if (cnt_1 <= ascii_rnded && cnt_1 <= c40_rnded && cnt_1 <= text_rnded && cnt_1 <= edi_rnded) {
270 return C1_BYTE; /* Step Q1 */
271 }
272 cnt_1 = ascii_count + C1_MULT_1;
273 if (cnt_1 <= c40_rnded && cnt_1 <= text_rnded && cnt_1 <= edi_rnded && cnt_1 <= byte_rnded) {
274 return C1_ASCII; /* Step Q2 */
275 }
276 cnt_1 = text_rnded + C1_MULT_1;
277 if (cnt_1 <= ascii_rnded && cnt_1 <= c40_rnded && cnt_1 <= edi_rnded && cnt_1 <= byte_rnded) {
278 return C1_TEXT; /* Step Q3 */
279 }
280 cnt_1 = c40_rnded + C1_MULT_1;
281 if (cnt_1 <= ascii_rnded && cnt_1 <= text_rnded) {
282 /* Step Q4 */
283 if (c40_rnded < edi_rnded) {
284 return C1_C40; /* Step Q4a */
285 }
286 if (c40_rnded == edi_rnded) {
287 /* Step Q4b */
288 if (c1_is_step_Q4bi_applicable(source, length, sp + 1)) {
289 return C1_EDI; /* Step Q4bi */
290 }
291 return C1_C40; /* Step Q4bii */
292 }
293 }
294 cnt_1 = edi_rnded + C1_MULT_1;
295 if (cnt_1 <= ascii_rnded && cnt_1 <= c40_rnded && cnt_1 <= text_rnded && cnt_1 <= byte_rnded) {
296 return C1_EDI; /* Step Q5 */
297 }
298 }
299 }
300
301 /* Step K */
302 ascii_rnded = C1_MULT_CEIL(ascii_count);
303 c40_rnded = C1_MULT_CEIL(c40_count);
304 text_rnded = C1_MULT_CEIL(text_count);
305 edi_rnded = C1_MULT_CEIL(edi_count);
306 byte_rnded = C1_MULT_CEIL(byte_count);
307
308 if (byte_count <= ascii_rnded && byte_count <= c40_rnded && byte_count <= text_rnded && byte_count <= edi_rnded) {
309 return C1_BYTE; /* Step K1 */
310 }
311 if (ascii_count <= c40_rnded && ascii_count <= text_rnded && ascii_count <= edi_rnded
312 && ascii_count <= byte_rnded) {
313 return C1_ASCII; /* Step K2 */
314 }
315 if (c40_rnded <= text_rnded && c40_rnded <= edi_rnded) {
316 return C1_C40; /* Step K3 */
317 }
318 if (text_rnded <= edi_rnded) {
319 return C1_TEXT; /* Step K4 */
320 }
321
322 return C1_EDI; /* Step K5 */
323 }
324
325 /* Whether can fit last character or characters in a single ASCII codeword */
326 static int c1_is_last_single_ascii(const unsigned char source[], const int length, const int sp) {
327 if (length - sp == 1 && source[sp] <= 127) {
328 return 1;
329 }
330 if (length - sp == 2 && is_twodigits(source, length, sp)) {
331 return 1;
332 }
333 return 0;
334 }
335
336 /* Initialize number of digits array (taken from BWIPP) */
337 static void c1_set_num_digits(const unsigned char source[], const int length, int num_digits[]) {
338 int i;
339 for (i = length - 1; i >= 0; i--) {
340 if (z_isdigit(source[i])) {
341 num_digits[i] = num_digits[i + 1] + 1;
342 }
343 }
344 }
345
346 /* Copy C40/TEXT/EDI triplets from buffer to `target`. Returns elements left in buffer (< 3) */
347 static int c1_cte_buffer_transfer(int cte_buffer[6], int cte_p, unsigned target[], int *p_tp) {
348 int cte_i, cte_e;
349 int tp = *p_tp;
350
351 cte_e = (cte_p / 3) * 3;
352
353 for (cte_i = 0; cte_i < cte_e; cte_i += 3) {
354 int iv = (1600 * cte_buffer[cte_i]) + (40 * cte_buffer[cte_i + 1]) + (cte_buffer[cte_i + 2]) + 1;
355 target[tp++] = iv >> 8;
356 target[tp++] = iv & 0xFF;
357 }
358
359 cte_p -= cte_e;
360
361 if (cte_p) {
362 memmove(cte_buffer, cte_buffer + cte_e, sizeof(int) * cte_p);
363 }
364
365 *p_tp = tp;
366
367 return cte_p;
368 }
369
370 /* Copy DECIMAL bytes to `target`. Returns bits left in buffer (< 8) */
371 static int c1_decimal_binary_transfer(char decimal_binary[24], int db_p, unsigned int target[], int *p_tp) {
372 int b_i, b_e, p;
373 int tp = *p_tp;
374
375 /* Transfer full bytes to target */
376 b_e = db_p & 0xF8;
377
378 for (b_i = 0; b_i < b_e; b_i += 8) {
379 int value = 0;
380 for (p = 0; p < 8; p++) {
381 value <<= 1;
382 value += decimal_binary[b_i + p] == '1';
383 }
384 target[tp++] = value;
385 }
386
387 db_p &= 0x07; /* Bits remaining */
388
389 if (db_p) {
390 memmove(decimal_binary, decimal_binary + b_e, db_p);
391 }
392
393 *p_tp = tp;
394
395 return db_p;
396 }
397
398 /* Unlatch to ASCII from DECIMAL mode using 6 ones flag. DECIMAL binary buffer will be empty */
399 static int c1_decimal_unlatch(char decimal_binary[24], int db_p, unsigned int target[], int *p_tp,
400 const int decimal_count, const unsigned char source[], int *p_sp) {
401 int sp = *p_sp;
402 int bits_left;
403
404 db_p = bin_append_posn(63, 6, decimal_binary, db_p); /* Unlatch */
405 if (db_p >= 8) {
406 db_p = c1_decimal_binary_transfer(decimal_binary, db_p, target, p_tp);
407 }
408 bits_left = (8 - db_p) & 0x07;
409 if (decimal_count >= 1 && bits_left >= 4) {
410 db_p = bin_append_posn(ctoi(source[sp]) + 1, 4, decimal_binary, db_p);
411 sp++;
412 if (bits_left == 6) {
413 db_p = bin_append_posn(1, 2, decimal_binary, db_p);
414 }
415 (void) c1_decimal_binary_transfer(decimal_binary, db_p, target, p_tp);
416
417 } else if (bits_left) {
418 if (bits_left >= 4) {
419 db_p = bin_append_posn(15, 4, decimal_binary, db_p);
420 }
421 if (bits_left == 2 || bits_left == 6) {
422 db_p = bin_append_posn(1, 2, decimal_binary, db_p);
423 }
424 (void) c1_decimal_binary_transfer(decimal_binary, db_p, target, p_tp);
425 }
426
427 *p_sp = sp;
428
429 return 0;
430 }
431
432 /* Number of codewords remaining in a particular version (may be negative) */
433 static int c1_codewords_remaining(struct zint_symbol *symbol, const int tp) {
434 int i;
435
436 if (symbol->option_2 == 10) { /* Version T */
437 if (tp > 24) {
438 return 38 - tp;
439 }
440 if (tp > 10) {
441 return 24 - tp;
442 }
443 return 10 - tp;
444 }
445 /* Versions A to H */
446 for (i = 6; i >= 0; i--) {
447 if (tp > c1_data_length[i]) {
448 return c1_data_length[i + 1] - tp;
449 }
450 }
451 return c1_data_length[0] - tp;
452 }
453
454 /* Number of C40/TEXT elements needed to encode `input` */
455 static int c1_c40text_cnt(const int current_mode, const int gs1, unsigned char input) {
456 int cnt;
457
458 if (gs1 && input == '\x1D') {
459 return 2;
460 }
461 cnt = 1;
462 if (input & 0x80) {
463 cnt += 2;
464 input -= 128;
465 }
466 if ((current_mode == C1_C40 && c1_c40_shift[input]) || (current_mode == C1_TEXT && c1_text_shift[input])) {
467 cnt += 1;
468 }
469
470 return cnt;
471 }
472
473 /* Copy `source` to `eci_buf` with "\NNNNNN" ECI indicator at start and backslashes escaped */
474 static void c1_eci_escape(const int eci, unsigned char source[], const int length, unsigned char eci_buf[],
475 const int eci_length) {
476 int i, j;
477
478 j = sprintf((char *) eci_buf, "\\%06d", eci);
479
480 for (i = 0; i < length && j < eci_length; i++) {
481 if (source[i] == '\\') {
482 eci_buf[j++] = '\\';
483 }
484 eci_buf[j++] = source[i];
485 }
486 eci_buf[j] = '\0';
487 }
488
489 /* Convert to codewords */
490 static int c1_encode(struct zint_symbol *symbol, unsigned char source[], int length, const int eci,
491 const int seg_count, const int gs1, unsigned int target[], int *p_tp, int *p_last_mode) {
492 int current_mode, next_mode, last_mode;
493 int sp = 0;
494 int tp = *p_tp;
495 int i;
496 int cte_buffer[6], cte_p = 0; /* C1_C40/TEXT/EDI buffer and index */
497 char decimal_binary[24]; /* C1_DECIMAL buffer */
498 int db_p = 0;
499 int byte_start = 0;
500 const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
501 const int eci_length = length + 7 + chr_cnt(source, length, '\\');
502 unsigned char *eci_buf = (unsigned char *) z_alloca(eci_length + 1);
503 int *num_digits = (int *) z_alloca(sizeof(int) * (eci_length + 1));
504
505 memset(num_digits, 0, sizeof(int) * (eci_length + 1));
506
507 /* Step A */
508 current_mode = C1_ASCII;
509 next_mode = C1_ASCII;
510
511 if (gs1 && tp == 0) {
512 c1_set_num_digits(source, length, num_digits);
513 if (length >= 15 && num_digits[0] >= 15) {
514 target[tp++] = 236; /* FNC1 and change to Decimal */
515 next_mode = C1_DECIMAL;
516 if (debug_print) fputs("FNC1Dec ", stdout);
517 } else if (length >= 7 && num_digits[0] == length) {
518 target[tp++] = 236; /* FNC1 and change to Decimal */
519 next_mode = C1_DECIMAL;
520 if (debug_print) fputs("FNC1Dec ", stdout);
521 } else {
522 target[tp++] = 232; /* FNC1 */
523 if (debug_print) fputs("FNC1 ", stdout);
524 }
525 /* Note ignoring Structured Append and ECI if GS1 mode (up to caller to warn/error) */
526 } else {
527 if (symbol->structapp.count && tp == 0) {
528 if (symbol->structapp.count < 16) { /* Group mode */
529 if ((eci || seg_count > 1) && symbol->structapp.index == 1) {
530 /* Initial pad indicator for 1st symbol only */
531 target[tp++] = 129; /* Pad */
532 target[tp++] = 233; /* FNC2 */
533 target[tp++] = (symbol->structapp.index - 1) * 15 + (symbol->structapp.count - 1);
534 target[tp++] = '\\' + 1; /* Escape char */
535 if (debug_print) fputs("SAGrp ", stdout);
536 } else {
537 target[tp++] = (symbol->structapp.index - 1) * 15 + (symbol->structapp.count - 1);
538 target[tp++] = 233; /* FNC2 */
539 if (debug_print) fputs("FNC2 ", stdout);
540 }
541 } else { /* Extended Group mode */
542 if ((eci || seg_count > 1) && symbol->structapp.index == 1) {
543 /* Initial pad indicator for 1st symbol only */
544 target[tp++] = 129; /* Pad */
545 target[tp++] = '\\' + 1; /* Escape char */
546 target[tp++] = 233; /* FNC2 */
547 target[tp++] = symbol->structapp.index;
548 target[tp++] = symbol->structapp.count;
549 if (debug_print) fputs("SAExGrp ", stdout);
550 } else {
551 target[tp++] = symbol->structapp.index;
552 target[tp++] = symbol->structapp.count;
553 target[tp++] = 233; /* FNC2 */
554 if (debug_print) fputs("FNC2 ", stdout);
555 }
556 }
557 if (eci) {
558 c1_eci_escape(eci, source, length, eci_buf, eci_length);
559 source = eci_buf;
560 length = eci_length;
561 }
562 } else if (eci || seg_count > 1) {
563 if (tp == 0) {
564 target[tp++] = 129; /* Pad */
565 target[tp++] = '\\' + 1; /* Escape char */
566 if (debug_print) fputs("PADEsc ", stdout);
567 }
568 if (eci) {
569 c1_eci_escape(eci, source, length, eci_buf, eci_length);
570 source = eci_buf;
571 length = eci_length;
572 }
573 }
574 c1_set_num_digits(source, length, num_digits);
575 }
576
577 do {
578 last_mode = current_mode;
579 if (current_mode != next_mode) {
580 /* Change mode */
581 switch (next_mode) {
582 case C1_C40: target[tp++] = 230;
583 if (debug_print) fputs("->C40 ", stdout);
584 break;
585 case C1_TEXT: target[tp++] = 239;
586 if (debug_print) fputs("->Text ", stdout);
587 break;
588 case C1_EDI: target[tp++] = 238;
589 if (debug_print) fputs("->EDI ", stdout);
590 break;
591 case C1_BYTE: target[tp++] = 231;
592 if (debug_print) fputs("->Byte ", stdout);
593 byte_start = tp;
594 target[tp++] = 0; /* Byte count holder (may be expanded to 2 codewords) */
595 break;
596 }
597 current_mode = next_mode;
598 }
599
600 if (current_mode == C1_ASCII) {
601 /* Step B - ASCII encodation */
602 next_mode = C1_ASCII;
603
604 if ((length - sp) >= 21 && num_digits[sp] >= 21) {
605 /* Step B1 */
606 next_mode = C1_DECIMAL;
607 db_p = bin_append_posn(15, 4, decimal_binary, db_p);
608 } else if ((length - sp) >= 13 && num_digits[sp] == (length - sp)) {
609 /* Step B2 */
610 next_mode = C1_DECIMAL;
611 db_p = bin_append_posn(15, 4, decimal_binary, db_p);
612 }
613
614 if (next_mode == C1_ASCII) {
615 if (is_twodigits(source, length, sp)) {
616 /* Step B3 */
617 target[tp++] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130;
618 if (debug_print) printf("ASCDD(%.2s) ", source + sp);
619 sp += 2;
620 } else {
621 if (gs1 && source[sp] == '\x1D') {
622 if (length - (sp + 1) >= 15 && num_digits[sp + 1] >= 15) {
623 /* Step B4 */
624 target[tp++] = 236; /* FNC1 and change to Decimal */
625 if (debug_print) fputs("FNC1 ", stdout);
626 sp++;
627 next_mode = C1_DECIMAL;
628 } else if (length - (sp + 1) >= 7 && num_digits[sp + 1] == length - (sp + 1)) {
629 /* Step B5 */
630 target[tp++] = 236; /* FNC1 and change to Decimal */
631 if (debug_print) fputs("FNC1 ", stdout);
632 sp++;
633 next_mode = C1_DECIMAL;
634 }
635 }
636
637 if (next_mode == C1_ASCII) {
638
639 /* Step B6 */
640 next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1);
641 if (next_mode == last_mode) { /* Avoid looping on latch (ticket #300 (#8) Andre Maute) */
642 next_mode = C1_ASCII;
643 }
644
645 if (next_mode == C1_ASCII) {
646 if (debug_print) printf("ASC(%d) ", source[sp]);
647
648 if (source[sp] & 0x80) {
649 /* Step B7 */
650 target[tp++] = 235; /* FNC4 (Upper Shift) */
651 target[tp++] = (source[sp] - 128) + 1;
652 if (debug_print) printf("UpSh(%d) ", source[sp]);
653 } else if (gs1 && source[sp] == '\x1D') {
654 /* Step B8 */
655 target[tp++] = 232; /* FNC1 */
656 if (debug_print) fputs("FNC1 ", stdout);
657 } else {
658 /* Step B8 */
659 target[tp++] = source[sp] + 1;
660 if (debug_print) printf("ASC(%d) ", source[sp]);
661 }
662 sp++;
663 }
664 }
665 }
666 }
667
668 } else if (current_mode == C1_C40 || current_mode == C1_TEXT) {
669 /* Step C/D - C40/TEXT encodation */
670
671 next_mode = current_mode;
672 if (cte_p == 0) {
673 /* Step C/D1 */
674 if ((length - sp) >= 12 && num_digits[sp] >= 12) {
675 /* Step C/D1a */
676 next_mode = C1_ASCII;
677 } else if ((length - sp) >= 8 && num_digits[sp] == (length - sp)) {
678 /* Step C/D1b */
679 next_mode = C1_ASCII;
680 } else {
681 next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1);
682 }
683 }
684
685 if (next_mode != current_mode) {
686 /* Step C/D1c */
687 target[tp++] = 255; /* Unlatch */
688 if (debug_print) fputs("Unlatch ", stdout);
689 } else {
690 /* Step C/D2 */
691 const char *ct_shift, *ct_value;
692
693 if (current_mode == C1_C40) {
694 ct_shift = c1_c40_shift;
695 ct_value = c1_c40_value;
696 } else {
697 ct_shift = c1_text_shift;
698 ct_value = c1_text_value;
699 }
700 if (debug_print) fputs(current_mode == C1_C40 ? "C40 " : "TEXT ", stdout);
701
702 if (source[sp] & 0x80) {
703 cte_buffer[cte_p++] = 1; /* Shift 2 */
704 cte_buffer[cte_p++] = 30; /* FNC4 (Upper Shift) */
705 if (ct_shift[source[sp] - 128]) {
706 cte_buffer[cte_p++] = ct_shift[source[sp] - 128] - 1;
707 }
708 cte_buffer[cte_p++] = ct_value[source[sp] - 128];
709 } else if (gs1 && source[sp] == '\x1D') {
710 cte_buffer[cte_p++] = 1; /* Shift 2 */
711 cte_buffer[cte_p++] = 27; /* FNC1 */
712 } else {
713 if (ct_shift[source[sp]]) {
714 cte_buffer[cte_p++] = ct_shift[source[sp]] - 1;
715 }
716 cte_buffer[cte_p++] = ct_value[source[sp]];
717 }
718
719 if (cte_p >= 3) {
720 cte_p = c1_cte_buffer_transfer(cte_buffer, cte_p, target, &tp);
721 }
722 sp++;
723 }
724
725 } else if (current_mode == C1_EDI) {
726 /* Step E - EDI Encodation */
727
728 next_mode = C1_EDI;
729 if (cte_p == 0) {
730 /* Step E1 */
731 if ((length - sp) >= 12 && num_digits[sp] >= 12) {
732 /* Step E1a */
733 next_mode = C1_ASCII;
734 } else if ((length - sp) >= 8 && num_digits[sp] == (length - sp)) {
735 /* Step E1b */
736 next_mode = C1_ASCII;
737 } else if ((length - sp) < 3 || !c1_isedi(source[sp]) || !c1_isedi(source[sp + 1])
738 || !c1_isedi(source[sp + 2])) {
739 /* Step E1c */
740 /* This ensures ASCII switch if don't have EDI triplet, so cte_p will be zero on loop exit */
741 next_mode = C1_ASCII;
742 }
743 }
744
745 if (next_mode != C1_EDI) {
746 if (c1_is_last_single_ascii(source, length, sp) && c1_codewords_remaining(symbol, tp) == 1) {
747 /* No unlatch needed if data fits as ASCII in last data codeword */
748 } else {
749 target[tp++] = 255; /* Unlatch */
750 if (debug_print) fputs("Unlatch ", stdout);
751 }
752 } else {
753 /* Step E2 */
754 static const char edi_nonalphanum_chars[] = "\015*> ";
755
756 if (debug_print) fputs("EDI ", stdout);
757
758 if (z_isdigit(source[sp])) {
759 cte_buffer[cte_p++] = source[sp] - '0' + 4;
760 } else if (z_isupper(source[sp])) {
761 cte_buffer[cte_p++] = source[sp] - 'A' + 14;
762 } else {
763 cte_buffer[cte_p++] = posn(edi_nonalphanum_chars, source[sp]);
764 }
765
766 if (cte_p >= 3) {
767 cte_p = c1_cte_buffer_transfer(cte_buffer, cte_p, target, &tp);
768 }
769 sp++;
770 }
771
772 } else if (current_mode == C1_DECIMAL) {
773 /* Step F - Decimal encodation */
774
775 if (debug_print) fputs("DEC ", stdout);
776
777 next_mode = C1_DECIMAL;
778
779 if (length - sp < 3) {
780 /* Step F1 */
781 const int bits_left = 8 - db_p;
782 const int can_ascii = bits_left == 8 && c1_is_last_single_ascii(source, length, sp);
783 if (c1_codewords_remaining(symbol, tp) == 1
784 && (can_ascii || (num_digits[sp] == 1 && bits_left >= 4))) {
785 if (can_ascii) {
786 /* Encode last character or last 2 digits as ASCII */
787 if (is_twodigits(source, length, sp)) {
788 target[tp++] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130;
789 if (debug_print) printf("ASCDD(%.2s) ", source + sp);
790 sp += 2;
791 } else {
792 target[tp++] = source[sp] + 1;
793 if (debug_print) printf("ASC(%d) ", source[sp]);
794 sp++;
795 }
796 } else {
797 /* Encode last digit in 4 bits */
798 db_p = bin_append_posn(ctoi(source[sp]) + 1, 4, decimal_binary, db_p);
799 sp++;
800 if (bits_left == 6) {
801 db_p = bin_append_posn(1, 2, decimal_binary, db_p);
802 }
803 db_p = c1_decimal_binary_transfer(decimal_binary, db_p, target, &tp);
804 }
805 } else {
806 db_p = c1_decimal_unlatch(decimal_binary, db_p, target, &tp, num_digits[sp], source, &sp);
807 current_mode = C1_ASCII; /* Note need to set current_mode also in case exit loop */
808 }
809 next_mode = C1_ASCII;
810
811 } else {
812 if (num_digits[sp] < 3) {
813 /* Step F2 */
814 db_p = c1_decimal_unlatch(decimal_binary, db_p, target, &tp, num_digits[sp], source, &sp);
815 current_mode = next_mode = C1_ASCII; /* Note need to set current_mode also in case exit loop */
816 } else {
817 /* Step F3 */
818 /* There are three digits - convert the value to binary */
819 int value = (100 * ctoi(source[sp])) + (10 * ctoi(source[sp + 1])) + ctoi(source[sp + 2]) + 1;
820 db_p = bin_append_posn(value, 10, decimal_binary, db_p);
821 if (db_p >= 8) {
822 db_p = c1_decimal_binary_transfer(decimal_binary, db_p, target, &tp);
823 }
824 sp += 3;
825 }
826 }
827
828 } else if (current_mode == C1_BYTE) {
829 next_mode = C1_BYTE;
830
831 if (gs1 && source[sp] == '\x1D') {
832 next_mode = C1_ASCII;
833 } else {
834 if (source[sp] <= 127) {
835 next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1);
836 }
837 }
838
839 if (next_mode != C1_BYTE) {
840 /* Update byte field length */
841 int byte_count = tp - (byte_start + 1);
842 if (byte_count <= 249) {
843 target[byte_start] = byte_count;
844 } else {
845 /* Insert extra codeword */
846 memmove(target + byte_start + 2, target + byte_start + 1, sizeof(unsigned int) * byte_count);
847 target[byte_start] = 249 + (byte_count / 250);
848 target[byte_start + 1] = (byte_count % 250);
849 tp++;
850 }
851 } else {
852 if (debug_print) printf("BYTE(%d) ", source[sp]);
853
854 target[tp++] = source[sp];
855 sp++;
856 }
857 }
858
859 if (tp > C1_MAX_CWS) {
860 if (debug_print) fputc('\n', stdout);
861 /* Data is too large for symbol */
862 return 0;
863 }
864 } while (sp < length);
865
866 if (debug_print) {
867 printf("\nEnd Current Mode: %d, tp %d, cte_p %d, db_p %d\n", current_mode, tp, cte_p, db_p);
868 }
869
870 /* Empty buffers (note cte_buffer will be empty if current_mode C1_EDI) */
871 if (current_mode == C1_C40 || current_mode == C1_TEXT) {
872 if (cte_p >= 1) {
873 const int cws_remaining = c1_codewords_remaining(symbol, tp);
874
875 /* Note doing strict interpretation of spec here (same as BWIPP), as now also done in Data Matrix case */
876 if (cws_remaining == 1 && cte_p == 1 && c1_isc40text(current_mode, source[sp - 1])) {
877 /* 2.2.2.2 "...except when a single symbol character is left at the end before the first
878 error correction character. This single character is encoded in the ASCII code set." */
879 target[tp++] = source[sp - 1] + 1; /* As ASCII */
880 cte_p = 0;
881 } else if (cws_remaining == 2 && cte_p == 2) {
882 /* 2.2.2.2 "Two characters may be encoded in C40 mode in the last two data symbol characters of the
883 symbol as two C40 values followed by one of the C40 shift characters." */
884 cte_buffer[cte_p++] = 0; /* Shift 0 */
885 cte_p = c1_cte_buffer_transfer(cte_buffer, cte_p, target, &tp);
886 }
887 if (cte_p >= 1) {
888 int cnt, total_cnt = 0;
889 /* Backtrack to last complete triplet (same technique as BWIPP) */
890 while (sp > 0 && cte_p % 3) {
891 sp--;
892 cnt = c1_c40text_cnt(current_mode, gs1, source[sp]);
893 total_cnt += cnt;
894 cte_p -= cnt;
895 }
896 tp -= (total_cnt / 3) * 2;
897
898 target[tp++] = 255; /* Unlatch */
899 for (; sp < length; sp++) {
900 if (is_twodigits(source, length, sp)) {
901 target[tp++] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130;
902 sp++;
903 } else if (source[sp] & 0x80) {
904 target[tp++] = 235; /* FNC4 (Upper Shift) */
905 target[tp++] = (source[sp] - 128) + 1;
906 } else if (gs1 && source[sp] == '\x1D') {
907 target[tp++] = 232; /* FNC1 */
908 } else {
909 target[tp++] = source[sp] + 1;
910 }
911 }
912 current_mode = C1_ASCII;
913 }
914 }
915
916 } else if (current_mode == C1_DECIMAL) {
917 int bits_left;
918
919 /* Finish Decimal mode and go back to ASCII unless only one codeword remaining */
920 if (c1_codewords_remaining(symbol, tp) > 1) {
921 db_p = bin_append_posn(63, 6, decimal_binary, db_p); /* Unlatch */
922 }
923
924 if (db_p >= 8) {
925 db_p = c1_decimal_binary_transfer(decimal_binary, db_p, target, &tp);
926 }
927
928 bits_left = (8 - db_p) & 0x07;
929
930 if (bits_left) {
931
932 if ((bits_left == 4) || (bits_left == 6)) {
933 db_p = bin_append_posn(15, 4, decimal_binary, db_p);
934 }
935
936 if (bits_left == 2 || bits_left == 6) {
937 db_p = bin_append_posn(1, 2, decimal_binary, db_p);
938 }
939
940 (void) c1_decimal_binary_transfer(decimal_binary, db_p, target, &tp);
941 }
942 current_mode = C1_ASCII;
943
944 } else if (current_mode == C1_BYTE) {
945 /* Update byte field length unless no codewords remaining */
946 if (c1_codewords_remaining(symbol, tp) > 0) {
947 int byte_count = tp - (byte_start + 1);
948 if (byte_count <= 249) {
949 target[byte_start] = byte_count;
950 } else {
951 /* Insert extra byte field byte */
952 memmove(target + byte_start + 2, target + byte_start + 1, sizeof(unsigned int) * byte_count);
953 target[byte_start] = 249 + (byte_count / 250);
954 target[byte_start + 1] = (byte_count % 250);
955 tp++;
956 }
957 }
958 }
959
960 /* Re-check length of data */
961 if (tp > C1_MAX_CWS) {
962 /* Data is too large for symbol */
963 return 0;
964 }
965
966 *p_last_mode = current_mode;
967
968 if (debug_print) {
969 printf("Target (%d):", tp);
970 for (i = 0; i < tp; i++) {
971 printf(" [%d]", (int) target[i]);
972 }
973 printf("\nLast Mode: %d\n", *p_last_mode);
974 }
975
976 return tp;
977 }
978
979 /* Call `c1_encode()` for each segment */
980 static int c1_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count, const int gs1,
981 unsigned int target[], int *p_last_mode) {
982 int i;
983 int tp = 0;
984
985 for (i = 0; i < seg_count; i++) {
986 tp = c1_encode(symbol, segs[i].source, segs[i].length, segs[i].eci, seg_count, gs1, target, &tp, p_last_mode);
987 }
988
989 return tp;
990 }
991
992 /* Set symbol from datagrid */
993 static void c1_block_copy(struct zint_symbol *symbol, char datagrid[136][120], const int start_row,
994 const int start_col, const int height, const int width, const int row_offset, const int col_offset) {
995 int i, j;
996
997 for (i = start_row; i < (start_row + height); i++) {
998 for (j = start_col; j < (start_col + width); j++) {
999 if (datagrid[i][j]) {
1000 set_module(symbol, i + row_offset, j + col_offset);
1001 }
1002 }
1003 }
1004 }
1005
1006 /* Get total length allowing for ECIs and escaping backslashes */
1007 static int c1_total_length_segs(struct zint_seg segs[], const int seg_count) {
1008 int total_len = 0;
1009 int i;
1010
1011 if (segs[0].eci || seg_count > 1) {
1012 for (i = 0; i < seg_count; i++) {
1013 total_len += segs[i].length + 7 + chr_cnt(segs[i].source, segs[i].length, '\\');
1014 }
1015 } else {
1016 total_len = segs[0].length;
1017 }
1018
1019 return total_len;
1020 }
1021
1022 INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
1023 int size = 1, i, j;
1024 char datagrid[136][120];
1025 int row, col;
1026 int sub_version = 0;
1027 rs_t rs;
1028 const int gs1 = (symbol->input_mode & 0x07) == GS1_MODE;
1029 const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
1030
1031 if ((symbol->option_2 < 0) || (symbol->option_2 > 10)) {
1032 return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 513, "Version '%d' out of range (1 to 10)",
1033 symbol->option_2);
1034 }
1035
1036 if (symbol->structapp.count) {
1037 if (symbol->option_2 == 9) { /* Version S */
1038 return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 714, "Structured Append not available for Version S");
1039 }
1040 if (gs1) {
1041 return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 710,
1042 "Cannot have Structured Append and GS1 mode at the same time");
1043 }
1044 if (symbol->structapp.count < 2 || symbol->structapp.count > 128) {
1045 return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 711,
1046 "Structured Append count '%d' out of range (2 to 128)", symbol->structapp.count);
1047 }
1048 if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
1049 return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 712,
1050 "Structured Append index '%1$d' out of range (1 to count %2$d)",
1051 symbol->structapp.index, symbol->structapp.count);
1052 }
1053 if (symbol->structapp.id[0]) {
1054 return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 713, "Structured Append ID not available for Code One");
1055 }
1056 }
1057
1058 if (symbol->option_2 == 9) {
1059 /* Version S */
1060 int codewords;
1061 large_uint elreg;
1062 unsigned int target[30], ecc[15];
1063 int block_width;
1064
1065 if (seg_count > 1) {
1066 return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 715, "Multiple segments not supported for Version S");
1067 }
1068 if (segs[0].length > 18) {
1069 return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 514, "Input length %d too long for Version S (maximum 18)",
1070 segs[0].length);
1071 }
1072 if ((i = not_sane(NEON_F, segs[0].source, segs[0].length))) {
1073 return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 515,
1074 "Invalid character at position %d in input (Version S encodes digits only)", i);
1075 }
1076
1077 size = 9;
1078 if (segs[0].length <= 6) {
1079 /* Version S-10 */
1080 sub_version = 1;
1081 codewords = 4;
1082 block_width = 2;
1083 } else if (segs[0].length <= 12) {
1084 /* Version S-20 */
1085 sub_version = 2;
1086 codewords = 8;
1087 block_width = 4;
1088 } else {
1089 /* Version S-30 */
1090 sub_version = 3;
1091 codewords = 12;
1092 block_width = 6;
1093 }
1094
1095 if (debug_print) {
1096 printf("Subversion: %d\n", sub_version);
1097 }
1098
1099 /* Convert value plus one to binary */
1100 large_load_str_u64(&elreg, segs[0].source, segs[0].length);
1101 large_add_u64(&elreg, 1);
1102 large_uint_array(&elreg, target, codewords, 5 /*bits*/);
1103
1104 rs_init_gf(&rs, 0x25);
1105 rs_init_code(&rs, codewords, 0);
1106 rs_encode_uint(&rs, codewords, target, ecc);
1107
1108 for (i = 0; i < codewords; i++) {
1109 target[i + codewords] = ecc[i];
1110 }
1111
1112 if (debug_print) {
1113 printf("Codewords (%d): ", codewords);
1114 for (i = 0; i < codewords * 2; i++) printf(" %d", (int) target[i]);
1115 fputc('\n', stdout);
1116 }
1117
1118 i = 0;
1119 for (row = 0; row < 2; row++) {
1120 for (col = 0; col < block_width; col++) {
1121 datagrid[row * 2][col * 5] = target[i] & 0x10;
1122 datagrid[row * 2][(col * 5) + 1] = target[i] & 0x08;
1123 datagrid[row * 2][(col * 5) + 2] = target[i] & 0x04;
1124 datagrid[(row * 2) + 1][col * 5] = target[i] & 0x02;
1125 datagrid[(row * 2) + 1][(col * 5) + 1] = target[i] & 0x01;
1126 datagrid[row * 2][(col * 5) + 3] = target[i + 1] & 0x10;
1127 datagrid[row * 2][(col * 5) + 4] = target[i + 1] & 0x08;
1128 datagrid[(row * 2) + 1][(col * 5) + 2] = target[i + 1] & 0x04;
1129 datagrid[(row * 2) + 1][(col * 5) + 3] = target[i + 1] & 0x02;
1130 datagrid[(row * 2) + 1][(col * 5) + 4] = target[i + 1] & 0x01;
1131 i += 2;
1132 }
1133 }
1134
1135 symbol->rows = 8;
1136 symbol->width = 10 * sub_version + 1;
1137
1138 } else if (symbol->option_2 == 10) {
1139 /* Version T */
1140 unsigned int target[C1_MAX_CWS + C1_MAX_ECCS]; /* Use same buffer size as A to H to avail of loop checks */
1141 unsigned int ecc[22];
1142 int data_length;
1143 int data_cw, ecc_cw, block_width;
1144 int last_mode = 0; /* Suppress gcc 14 "-Wmaybe-uninitialized" false positive */
1145
1146 if ((i = c1_total_length_segs(segs, seg_count)) > 90) {
1147 return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 519, "Input length %d too long for Version T (maximum 90)",
1148 i);
1149 }
1150
1151 data_length = c1_encode_segs(symbol, segs, seg_count, gs1, target, &last_mode);
1152
1153 assert(data_length); /* Can't exceed C1_MAX_CWS as input <= 90 */
1154 if (data_length > 38) {
1155 return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 516,
1156 "Input too long for Version T, requires %d codewords (maximum 38)", data_length);
1157 }
1158
1159 size = 10;
1160 if (data_length <= 10) {
1161 sub_version = 1;
1162 data_cw = 10;
1163 ecc_cw = 10;
1164 block_width = 4;
1165 } else if (data_length <= 24) {
1166 sub_version = 2;
1167 data_cw = 24;
1168 ecc_cw = 16;
1169 block_width = 8;
1170 } else {
1171 sub_version = 3;
1172 data_cw = 38;
1173 ecc_cw = 22;
1174 block_width = 12;
1175 }
1176
1177 if (debug_print) {
1178 printf("Padding: %d, Subversion: %d\n", data_cw - data_length, sub_version);
1179 }
1180
1181 /* If require padding */
1182 if (data_cw > data_length) {
1183 /* If did not finish in ASCII or BYTE mode, switch to ASCII */
1184 if (last_mode != C1_ASCII && last_mode != C1_BYTE) {
1185 target[data_length++] = 255; /* Unlatch */
1186 }
1187 for (i = data_length; i < data_cw; i++) {
1188 target[i] = 129; /* Pad */
1189 }
1190 }
1191
1192 /* Calculate error correction data */
1193 rs_init_gf(&rs, 0x12d);
1194 rs_init_code(&rs, ecc_cw, 0);
1195 rs_encode_uint(&rs, data_cw, target, ecc);
1196
1197 for (i = 0; i < ecc_cw; i++) {
1198 target[data_cw + i] = ecc[i];
1199 }
1200
1201 if (debug_print) {
1202 printf("Codewords (%d):", data_cw + ecc_cw);
1203 for (i = 0; i < data_cw + ecc_cw; i++) printf(" %d", (int) target[i]);
1204 fputc('\n', stdout);
1205 }
1206
1207 i = 0;
1208 for (row = 0; row < 5; row++) {
1209 for (col = 0; col < block_width; col++) {
1210 datagrid[row * 2][col * 4] = target[i] & 0x80;
1211 datagrid[row * 2][(col * 4) + 1] = target[i] & 0x40;
1212 datagrid[row * 2][(col * 4) + 2] = target[i] & 0x20;
1213 datagrid[row * 2][(col * 4) + 3] = target[i] & 0x10;
1214 datagrid[(row * 2) + 1][col * 4] = target[i] & 0x08;
1215 datagrid[(row * 2) + 1][(col * 4) + 1] = target[i] & 0x04;
1216 datagrid[(row * 2) + 1][(col * 4) + 2] = target[i] & 0x02;
1217 datagrid[(row * 2) + 1][(col * 4) + 3] = target[i] & 0x01;
1218 i++;
1219 }
1220 }
1221
1222 symbol->rows = 16;
1223 symbol->width = (sub_version * 16) + 1;
1224
1225 } else {
1226 /* Versions A to H */
1227 unsigned int target[C1_MAX_CWS + C1_MAX_ECCS];
1228 unsigned int sub_data[185], sub_ecc[70];
1229 int data_length;
1230 int data_cw;
1231 int blocks, data_blocks, ecc_blocks, ecc_length;
1232 int last_mode;
1233
1234 data_length = c1_encode_segs(symbol, segs, seg_count, gs1, target, &last_mode);
1235
1236 if (data_length == 0) {
1237 return errtxt(ZINT_ERROR_TOO_LONG, symbol, 517,
1238 "Input too long, requires too many codewords (maximum " C1_MAX_CWS_S ")");
1239 }
1240
1241 for (i = 7; i >= 0; i--) {
1242 if (c1_data_length[i] >= data_length) {
1243 size = i + 1;
1244 }
1245 }
1246
1247 if (symbol->option_2 > size) {
1248 size = symbol->option_2;
1249 }
1250
1251 if ((symbol->option_2 != 0) && (symbol->option_2 < size)) {
1252 return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 518,
1253 "Input too long for Version %1$c, requires %2$d codewords (maximum %3$d)",
1254 'A' + symbol->option_2 - 1, data_length, c1_data_length[symbol->option_2 - 1]);
1255 }
1256 data_cw = c1_data_length[size - 1];
1257
1258 /* If require padding */
1259 if (data_cw > data_length) {
1260 /* If did not finish in ASCII or BYTE mode, switch to ASCII */
1261 if (last_mode != C1_ASCII && last_mode != C1_BYTE) {
1262 target[data_length++] = 255; /* Unlatch */
1263 }
1264 if (debug_print) {
1265 printf("Padding: %d\n", data_cw - data_length);
1266 }
1267 for (i = data_length; i < data_cw; i++) {
1268 target[i] = 129; /* Pad */
1269 }
1270 } else if (debug_print) {
1271 fputs("No padding\n", stdout);
1272 }
1273
1274 /* Calculate error correction data */
1275 blocks = c1_blocks[size - 1];
1276 data_blocks = c1_data_blocks[size - 1];
1277 ecc_blocks = c1_ecc_blocks[size - 1];
1278 ecc_length = c1_ecc_length[size - 1];
1279
1280 rs_init_gf(&rs, 0x12d);
1281 rs_init_code(&rs, ecc_blocks, 0);
1282 for (i = 0; i < blocks; i++) {
1283 for (j = 0; j < data_blocks; j++) {
1284 sub_data[j] = target[j * blocks + i];
1285 }
1286 rs_encode_uint(&rs, data_blocks, sub_data, sub_ecc);
1287 for (j = 0; j < ecc_blocks; j++) {
1288 target[data_cw + j * blocks + i] = sub_ecc[j];
1289 }
1290 }
1291
1292 if (debug_print) {
1293 printf("Codewords (%d):", data_cw + ecc_length);
1294 for (i = 0; i < data_cw + ecc_length; i++) printf(" %d", (int) target[i]);
1295 fputc('\n', stdout);
1296 }
1297
1298 i = 0;
1299 for (row = 0; row < c1_grid_height[size - 1]; row++) {
1300 for (col = 0; col < c1_grid_width[size - 1]; col++) {
1301 datagrid[row * 2][col * 4] = target[i] & 0x80;
1302 datagrid[row * 2][(col * 4) + 1] = target[i] & 0x40;
1303 datagrid[row * 2][(col * 4) + 2] = target[i] & 0x20;
1304 datagrid[row * 2][(col * 4) + 3] = target[i] & 0x10;
1305 datagrid[(row * 2) + 1][col * 4] = target[i] & 0x08;
1306 datagrid[(row * 2) + 1][(col * 4) + 1] = target[i] & 0x04;
1307 datagrid[(row * 2) + 1][(col * 4) + 2] = target[i] & 0x02;
1308 datagrid[(row * 2) + 1][(col * 4) + 3] = target[i] & 0x01;
1309 i++;
1310 }
1311 }
1312
1313 symbol->rows = c1_height[size - 1];
1314 symbol->width = c1_width[size - 1];
1315 }
1316
1317 if (debug_print) {
1318 printf("Version: %d\n", size);
1319 }
1320
1321 switch (size) {
1322 case 1: /* Version A */
1323 c1_central_finder(symbol, 6, 3, 1);
1324 c1_vert(symbol, 4, 6, 1);
1325 c1_vert(symbol, 12, 5, 0);
1326 set_module(symbol, 5, 12);
1327 c1_spigot(symbol, 0);
1328 c1_spigot(symbol, 15);
1329 c1_block_copy(symbol, datagrid, 0, 0, 5, 4, 0, 0);
1330 c1_block_copy(symbol, datagrid, 0, 4, 5, 12, 0, 2);
1331 c1_block_copy(symbol, datagrid, 5, 0, 5, 12, 6, 0);
1332 c1_block_copy(symbol, datagrid, 5, 12, 5, 4, 6, 2);
1333 break;
1334 case 2: /* Version B */
1335 c1_central_finder(symbol, 8, 4, 1);
1336 c1_vert(symbol, 4, 8, 1);
1337 c1_vert(symbol, 16, 7, 0);
1338 set_module(symbol, 7, 16);
1339 c1_spigot(symbol, 0);
1340 c1_spigot(symbol, 21);
1341 c1_block_copy(symbol, datagrid, 0, 0, 7, 4, 0, 0);
1342 c1_block_copy(symbol, datagrid, 0, 4, 7, 16, 0, 2);
1343 c1_block_copy(symbol, datagrid, 7, 0, 7, 16, 8, 0);
1344 c1_block_copy(symbol, datagrid, 7, 16, 7, 4, 8, 2);
1345 break;
1346 case 3: /* Version C */
1347 c1_central_finder(symbol, 11, 4, 2);
1348 c1_vert(symbol, 4, 11, 1);
1349 c1_vert(symbol, 26, 13, 1);
1350 c1_vert(symbol, 4, 10, 0);
1351 c1_vert(symbol, 26, 10, 0);
1352 c1_spigot(symbol, 0);
1353 c1_spigot(symbol, 27);
1354 c1_block_copy(symbol, datagrid, 0, 0, 10, 4, 0, 0);
1355 c1_block_copy(symbol, datagrid, 0, 4, 10, 20, 0, 2);
1356 c1_block_copy(symbol, datagrid, 0, 24, 10, 4, 0, 4);
1357 c1_block_copy(symbol, datagrid, 10, 0, 10, 4, 8, 0);
1358 c1_block_copy(symbol, datagrid, 10, 4, 10, 20, 8, 2);
1359 c1_block_copy(symbol, datagrid, 10, 24, 10, 4, 8, 4);
1360 break;
1361 case 4: /* Version D */
1362 c1_central_finder(symbol, 16, 5, 1);
1363 c1_vert(symbol, 4, 16, 1);
1364 c1_vert(symbol, 20, 16, 1);
1365 c1_vert(symbol, 36, 16, 1);
1366 c1_vert(symbol, 4, 15, 0);
1367 c1_vert(symbol, 20, 15, 0);
1368 c1_vert(symbol, 36, 15, 0);
1369 c1_spigot(symbol, 0);
1370 c1_spigot(symbol, 12);
1371 c1_spigot(symbol, 27);
1372 c1_spigot(symbol, 39);
1373 c1_block_copy(symbol, datagrid, 0, 0, 15, 4, 0, 0);
1374 c1_block_copy(symbol, datagrid, 0, 4, 15, 14, 0, 2);
1375 c1_block_copy(symbol, datagrid, 0, 18, 15, 14, 0, 4);
1376 c1_block_copy(symbol, datagrid, 0, 32, 15, 4, 0, 6);
1377 c1_block_copy(symbol, datagrid, 15, 0, 15, 4, 10, 0);
1378 c1_block_copy(symbol, datagrid, 15, 4, 15, 14, 10, 2);
1379 c1_block_copy(symbol, datagrid, 15, 18, 15, 14, 10, 4);
1380 c1_block_copy(symbol, datagrid, 15, 32, 15, 4, 10, 6);
1381 break;
1382 case 5: /* Version E */
1383 c1_central_finder(symbol, 22, 5, 2);
1384 c1_vert(symbol, 4, 22, 1);
1385 c1_vert(symbol, 26, 24, 1);
1386 c1_vert(symbol, 48, 22, 1);
1387 c1_vert(symbol, 4, 21, 0);
1388 c1_vert(symbol, 26, 21, 0);
1389 c1_vert(symbol, 48, 21, 0);
1390 c1_spigot(symbol, 0);
1391 c1_spigot(symbol, 12);
1392 c1_spigot(symbol, 39);
1393 c1_spigot(symbol, 51);
1394 c1_block_copy(symbol, datagrid, 0, 0, 21, 4, 0, 0);
1395 c1_block_copy(symbol, datagrid, 0, 4, 21, 20, 0, 2);
1396 c1_block_copy(symbol, datagrid, 0, 24, 21, 20, 0, 4);
1397 c1_block_copy(symbol, datagrid, 0, 44, 21, 4, 0, 6);
1398 c1_block_copy(symbol, datagrid, 21, 0, 21, 4, 10, 0);
1399 c1_block_copy(symbol, datagrid, 21, 4, 21, 20, 10, 2);
1400 c1_block_copy(symbol, datagrid, 21, 24, 21, 20, 10, 4);
1401 c1_block_copy(symbol, datagrid, 21, 44, 21, 4, 10, 6);
1402 break;
1403 case 6: /* Version F */
1404 c1_central_finder(symbol, 31, 5, 3);
1405 c1_vert(symbol, 4, 31, 1);
1406 c1_vert(symbol, 26, 35, 1);
1407 c1_vert(symbol, 48, 31, 1);
1408 c1_vert(symbol, 70, 35, 1);
1409 c1_vert(symbol, 4, 30, 0);
1410 c1_vert(symbol, 26, 30, 0);
1411 c1_vert(symbol, 48, 30, 0);
1412 c1_vert(symbol, 70, 30, 0);
1413 c1_spigot(symbol, 0);
1414 c1_spigot(symbol, 12);
1415 c1_spigot(symbol, 24);
1416 c1_spigot(symbol, 45);
1417 c1_spigot(symbol, 57);
1418 c1_spigot(symbol, 69);
1419 c1_block_copy(symbol, datagrid, 0, 0, 30, 4, 0, 0);
1420 c1_block_copy(symbol, datagrid, 0, 4, 30, 20, 0, 2);
1421 c1_block_copy(symbol, datagrid, 0, 24, 30, 20, 0, 4);
1422 c1_block_copy(symbol, datagrid, 0, 44, 30, 20, 0, 6);
1423 c1_block_copy(symbol, datagrid, 0, 64, 30, 4, 0, 8);
1424 c1_block_copy(symbol, datagrid, 30, 0, 30, 4, 10, 0);
1425 c1_block_copy(symbol, datagrid, 30, 4, 30, 20, 10, 2);
1426 c1_block_copy(symbol, datagrid, 30, 24, 30, 20, 10, 4);
1427 c1_block_copy(symbol, datagrid, 30, 44, 30, 20, 10, 6);
1428 c1_block_copy(symbol, datagrid, 30, 64, 30, 4, 10, 8);
1429 break;
1430 case 7: /* Version G */
1431 c1_central_finder(symbol, 47, 6, 2);
1432 c1_vert(symbol, 6, 47, 1);
1433 c1_vert(symbol, 27, 49, 1);
1434 c1_vert(symbol, 48, 47, 1);
1435 c1_vert(symbol, 69, 49, 1);
1436 c1_vert(symbol, 90, 47, 1);
1437 c1_vert(symbol, 6, 46, 0);
1438 c1_vert(symbol, 27, 46, 0);
1439 c1_vert(symbol, 48, 46, 0);
1440 c1_vert(symbol, 69, 46, 0);
1441 c1_vert(symbol, 90, 46, 0);
1442 c1_spigot(symbol, 0);
1443 c1_spigot(symbol, 12);
1444 c1_spigot(symbol, 24);
1445 c1_spigot(symbol, 36);
1446 c1_spigot(symbol, 67);
1447 c1_spigot(symbol, 79);
1448 c1_spigot(symbol, 91);
1449 c1_spigot(symbol, 103);
1450 c1_block_copy(symbol, datagrid, 0, 0, 46, 6, 0, 0);
1451 c1_block_copy(symbol, datagrid, 0, 6, 46, 19, 0, 2);
1452 c1_block_copy(symbol, datagrid, 0, 25, 46, 19, 0, 4);
1453 c1_block_copy(symbol, datagrid, 0, 44, 46, 19, 0, 6);
1454 c1_block_copy(symbol, datagrid, 0, 63, 46, 19, 0, 8);
1455 c1_block_copy(symbol, datagrid, 0, 82, 46, 6, 0, 10);
1456 c1_block_copy(symbol, datagrid, 46, 0, 46, 6, 12, 0);
1457 c1_block_copy(symbol, datagrid, 46, 6, 46, 19, 12, 2);
1458 c1_block_copy(symbol, datagrid, 46, 25, 46, 19, 12, 4);
1459 c1_block_copy(symbol, datagrid, 46, 44, 46, 19, 12, 6);
1460 c1_block_copy(symbol, datagrid, 46, 63, 46, 19, 12, 8);
1461 c1_block_copy(symbol, datagrid, 46, 82, 46, 6, 12, 10);
1462 break;
1463 case 8: /* Version H */
1464 c1_central_finder(symbol, 69, 6, 3);
1465 c1_vert(symbol, 6, 69, 1);
1466 c1_vert(symbol, 26, 73, 1);
1467 c1_vert(symbol, 46, 69, 1);
1468 c1_vert(symbol, 66, 73, 1);
1469 c1_vert(symbol, 86, 69, 1);
1470 c1_vert(symbol, 106, 73, 1);
1471 c1_vert(symbol, 126, 69, 1);
1472 c1_vert(symbol, 6, 68, 0);
1473 c1_vert(symbol, 26, 68, 0);
1474 c1_vert(symbol, 46, 68, 0);
1475 c1_vert(symbol, 66, 68, 0);
1476 c1_vert(symbol, 86, 68, 0);
1477 c1_vert(symbol, 106, 68, 0);
1478 c1_vert(symbol, 126, 68, 0);
1479 c1_spigot(symbol, 0);
1480 c1_spigot(symbol, 12);
1481 c1_spigot(symbol, 24);
1482 c1_spigot(symbol, 36);
1483 c1_spigot(symbol, 48);
1484 c1_spigot(symbol, 60);
1485 c1_spigot(symbol, 87);
1486 c1_spigot(symbol, 99);
1487 c1_spigot(symbol, 111);
1488 c1_spigot(symbol, 123);
1489 c1_spigot(symbol, 135);
1490 c1_spigot(symbol, 147);
1491 c1_block_copy(symbol, datagrid, 0, 0, 68, 6, 0, 0);
1492 c1_block_copy(symbol, datagrid, 0, 6, 68, 18, 0, 2);
1493 c1_block_copy(symbol, datagrid, 0, 24, 68, 18, 0, 4);
1494 c1_block_copy(symbol, datagrid, 0, 42, 68, 18, 0, 6);
1495 c1_block_copy(symbol, datagrid, 0, 60, 68, 18, 0, 8);
1496 c1_block_copy(symbol, datagrid, 0, 78, 68, 18, 0, 10);
1497 c1_block_copy(symbol, datagrid, 0, 96, 68, 18, 0, 12);
1498 c1_block_copy(symbol, datagrid, 0, 114, 68, 6, 0, 14);
1499 c1_block_copy(symbol, datagrid, 68, 0, 68, 6, 12, 0);
1500 c1_block_copy(symbol, datagrid, 68, 6, 68, 18, 12, 2);
1501 c1_block_copy(symbol, datagrid, 68, 24, 68, 18, 12, 4);
1502 c1_block_copy(symbol, datagrid, 68, 42, 68, 18, 12, 6);
1503 c1_block_copy(symbol, datagrid, 68, 60, 68, 18, 12, 8);
1504 c1_block_copy(symbol, datagrid, 68, 78, 68, 18, 12, 10);
1505 c1_block_copy(symbol, datagrid, 68, 96, 68, 18, 12, 12);
1506 c1_block_copy(symbol, datagrid, 68, 114, 68, 6, 12, 14);
1507 break;
1508 case 9: /* Version S */
1509 c1_horiz(symbol, 5, 1);
1510 c1_horiz(symbol, 7, 1);
1511 set_module(symbol, 6, 0);
1512 set_module(symbol, 6, symbol->width - 1);
1513 unset_module(symbol, 7, 1);
1514 unset_module(symbol, 7, symbol->width - 2);
1515 switch (sub_version) {
1516 case 1: /* Version S-10 */
1517 set_module(symbol, 0, 5);
1518 c1_block_copy(symbol, datagrid, 0, 0, 4, 5, 0, 0);
1519 c1_block_copy(symbol, datagrid, 0, 5, 4, 5, 0, 1);
1520 break;
1521 case 2: /* Version S-20 */
1522 set_module(symbol, 0, 10);
1523 set_module(symbol, 4, 10);
1524 c1_block_copy(symbol, datagrid, 0, 0, 4, 10, 0, 0);
1525 c1_block_copy(symbol, datagrid, 0, 10, 4, 10, 0, 1);
1526 break;
1527 case 3: /* Version S-30 */
1528 set_module(symbol, 0, 15);
1529 set_module(symbol, 4, 15);
1530 set_module(symbol, 6, 15);
1531 c1_block_copy(symbol, datagrid, 0, 0, 4, 15, 0, 0);
1532 c1_block_copy(symbol, datagrid, 0, 15, 4, 15, 0, 1);
1533 break;
1534 }
1535 break;
1536 case 10: /* Version T */
1537 c1_horiz(symbol, 11, 1);
1538 c1_horiz(symbol, 13, 1);
1539 c1_horiz(symbol, 15, 1);
1540 set_module(symbol, 12, 0);
1541 set_module(symbol, 12, symbol->width - 1);
1542 set_module(symbol, 14, 0);
1543 set_module(symbol, 14, symbol->width - 1);
1544 unset_module(symbol, 13, 1);
1545 unset_module(symbol, 13, symbol->width - 2);
1546 unset_module(symbol, 15, 1);
1547 unset_module(symbol, 15, symbol->width - 2);
1548 switch (sub_version) {
1549 case 1: /* Version T-16 */
1550 set_module(symbol, 0, 8);
1551 set_module(symbol, 10, 8);
1552 c1_block_copy(symbol, datagrid, 0, 0, 10, 8, 0, 0);
1553 c1_block_copy(symbol, datagrid, 0, 8, 10, 8, 0, 1);
1554 break;
1555 case 2: /* Version T-32 */
1556 set_module(symbol, 0, 16);
1557 set_module(symbol, 10, 16);
1558 set_module(symbol, 12, 16);
1559 c1_block_copy(symbol, datagrid, 0, 0, 10, 16, 0, 0);
1560 c1_block_copy(symbol, datagrid, 0, 16, 10, 16, 0, 1);
1561 break;
1562 case 3: /* Verion T-48 */
1563 set_module(symbol, 0, 24);
1564 set_module(symbol, 10, 24);
1565 set_module(symbol, 12, 24);
1566 set_module(symbol, 14, 24);
1567 c1_block_copy(symbol, datagrid, 0, 0, 10, 24, 0, 0);
1568 c1_block_copy(symbol, datagrid, 0, 24, 10, 24, 0, 1);
1569 break;
1570 }
1571 break;
1572 }
1573
1574 for (i = 0; i < symbol->rows; i++) {
1575 symbol->row_height[i] = 1;
1576 }
1577 symbol->height = symbol->rows;
1578
1579 if (symbol->option_2 == 9) { /* Version S */
1580 if (symbol->eci || gs1) {
1581 return errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 511, "%s ignored for Version S",
1582 symbol->eci && gs1 ? "ECI and GS1 mode" : symbol->eci ? "ECI" : "GS1 mode");
1583 }
1584 } else if (symbol->eci && gs1) {
1585 return errtxt(ZINT_WARN_INVALID_OPTION, symbol, 512, "ECI ignored for GS1 mode");
1586 }
1587
1588 return 0;
1589 }
1590
1591 /* vim: set ts=4 sw=4 et : */