1 /* library.c - external functions of libzint
2
3 libzint - the open source barcode library
4 Copyright (C) 2009 - 2021 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 /* vim: set ts=4 sw=4 et : */
32
33 #include <stdio.h>
34 #include <errno.h>
35 #include <limits.h>
36 #ifdef _MSC_VER
37 #include <malloc.h>
38 #endif
39 #include "common.h"
40 #include "eci.h"
41 #include "gs1.h"
42 #include "zfiletypes.h"
43
44 #define TECHNETIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"
45
46 /* It's assumed that int is at least 32 bits, the following will compile-time fail if not
47 * https://stackoverflow.com/a/1980056/664741 */
48 typedef int static_assert_int_at_least_32bits[CHAR_BIT != 8 || sizeof(int) < 4 ? -1 : 1];
49
50 /* Create and initialize a symbol structure */
ZBarcode_Create()51 struct zint_symbol *ZBarcode_Create() {
52 struct zint_symbol *symbol;
53
54 symbol = (struct zint_symbol *) malloc(sizeof(*symbol));
55 if (!symbol) return NULL;
56
57 memset(symbol, 0, sizeof(*symbol));
58
59 symbol->symbology = BARCODE_CODE128;
60 strcpy(symbol->fgcolour, "000000");
61 symbol->fgcolor = &symbol->fgcolour[0];
62 strcpy(symbol->bgcolour, "ffffff");
63 symbol->bgcolor = &symbol->bgcolour[0];
64 #ifdef NO_PNG
65 strcpy(symbol->outfile, "out.gif");
66 #else
67 strcpy(symbol->outfile, "out.png");
68 #endif
69 symbol->scale = 1.0f;
70 symbol->option_1 = -1;
71 symbol->show_hrt = 1; // Show human readable text
72 symbol->fontsize = 8;
73 symbol->input_mode = DATA_MODE;
74 symbol->bitmap = NULL;
75 symbol->alphamap = NULL;
76 symbol->eci = 0; // Default 0 uses ECI 3
77 symbol->dot_size = 4.0f / 5.0f;
78 symbol->vector = NULL;
79 symbol->warn_level = WARN_DEFAULT;
80
81 return symbol;
82 }
83
84 INTERNAL void vector_free(struct zint_symbol *symbol); /* Free vector structures */
85
86 /* Free any output buffers that may have been created and initialize output fields */
ZBarcode_Clear(struct zint_symbol * symbol)87 void ZBarcode_Clear(struct zint_symbol *symbol) {
88 int i, j;
89
90 if (!symbol) return;
91
92 for (i = 0; i < symbol->rows; i++) {
93 for (j = 0; j < symbol->width; j++) {
94 unset_module(symbol, i, j);
95 }
96 }
97 symbol->rows = 0;
98 symbol->width = 0;
99 memset(symbol->row_height, 0, sizeof(symbol->row_height));
100 memset(symbol->text, 0, sizeof(symbol->text));
101 symbol->errtxt[0] = '\0';
102 if (symbol->bitmap != NULL) {
103 free(symbol->bitmap);
104 symbol->bitmap = NULL;
105 }
106 if (symbol->alphamap != NULL) {
107 free(symbol->alphamap);
108 symbol->alphamap = NULL;
109 }
110 symbol->bitmap_width = 0;
111 symbol->bitmap_height = 0;
112 symbol->bitmap_byte_length = 0;
113
114 // If there is a rendered version, ensure its memory is released
115 vector_free(symbol);
116 }
117
118 /* Free a symbol structure, including any output buffers */
ZBarcode_Delete(struct zint_symbol * symbol)119 void ZBarcode_Delete(struct zint_symbol *symbol) {
120 if (!symbol) return;
121
122 if (symbol->bitmap != NULL)
123 free(symbol->bitmap);
124 if (symbol->alphamap != NULL)
125 free(symbol->alphamap);
126
127 // If there is a rendered version, ensure its memory is released
128 vector_free(symbol);
129
130 free(symbol);
131 }
132
133 INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */
134 INTERNAL int c39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */
135 /* Pharmazentral Nummer (PZN) */
136 INTERNAL int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length);
137 /* Extended Code 3 from 9 (or Code 39+) */
138 INTERNAL int ec39(struct zint_symbol *symbol, unsigned char source[], int length);
139 /* Codabar - a simple substitution cipher */
140 INTERNAL int codabar(struct zint_symbol *symbol, unsigned char source[], int length);
141 /* Code 2 of 5 Standard (& Matrix) */
142 INTERNAL int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length);
143 /* Code 2 of 5 Industrial */
144 INTERNAL int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length);
145 INTERNAL int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */
146 /* Code 2 of 5 Interleaved */
147 INTERNAL int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length);
148 /* Code 2 of 5 Data Logic */
149 INTERNAL int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length);
150 INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */
151 INTERNAL int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */
152 INTERNAL int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */
153 /* Code 93 - a re-working of Code 39+, generates 2 check digits */
154 INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length);
155 INTERNAL int code_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */
156 INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-128 (GS1-128) */
157 INTERNAL int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */
158 INTERNAL int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */
159 INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen ASCII */
160 INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen Numeric */
161 INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], int length); /* Plessey Code */
162 INTERNAL int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */
163 INTERNAL int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */
164 INTERNAL int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */
165 INTERNAL int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */
166 INTERNAL int post_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */
167 INTERNAL int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */
168 /* Intelligent Mail (aka USPS OneCode) */
169 INTERNAL int imail(struct zint_symbol *symbol, unsigned char source[], int length);
170 INTERNAL int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */
171 /* Australia Post 4-state */
172 INTERNAL int australia_post(struct zint_symbol *symbol, unsigned char source[], int length);
173 INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */
174 INTERNAL int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length); /* PDF417 */
175 INTERNAL int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length); /* Micro PDF417 */
176 INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */
177 INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */
178 INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */
179 INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */
180 INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */
181 INTERNAL int kix_code(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */
182 INTERNAL int aztec(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Code */
183 INTERNAL int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */
184 INTERNAL int daft_code(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */
185 INTERNAL int ean_14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */
186 INTERNAL int nve_18(struct zint_symbol *symbol, unsigned char source[], int length); /* NVE-18 */
187 INTERNAL int microqr(struct zint_symbol *symbol, unsigned char source[], int length); /* Micro QR Code */
188 INTERNAL int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */
189 INTERNAL int korea_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */
190 INTERNAL int japan_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */
191 INTERNAL int code_49(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 49 */
192 INTERNAL int channel_code(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */
193 INTERNAL int code_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */
194 INTERNAL int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Grid Matrix */
195 INTERNAL int han_xin(struct zint_symbol *symbol, unsigned char source[], int length); /* Han Xin */
196 INTERNAL int dotcode(struct zint_symbol *symbol, unsigned char source[], int length); /* DotCode */
197 INTERNAL int codablock(struct zint_symbol *symbol, unsigned char source[], int length); /* Codablock */
198 INTERNAL int upnqr(struct zint_symbol *symbol, unsigned char source[], int length); /* UPNQR */
199 INTERNAL int qr_code(struct zint_symbol *symbol, unsigned char source[], int length); /* QR Code */
200 INTERNAL int dmatrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Data Matrix (IEC16022) */
201 /* VIN Code (Vehicle Identification Number) */
202 INTERNAL int vin(struct zint_symbol *symbol, unsigned char source[], int length);
203 /* Royal Mail 4-state Mailmark */
204 INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int length);
205 INTERNAL int ultracode(struct zint_symbol *symbol, unsigned char source[], int length); /* Ultracode */
206 INTERNAL int rmqr(struct zint_symbol *symbol, unsigned char source[], int length); /* rMQR */
207 INTERNAL int dpd_parcel(struct zint_symbol *symbol, unsigned char source[], int length); /* DPD Code */
208
209 INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to PNG/BMP/PCX */
210 INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to EPS/EMF/SVG */
211
212 /* Prefix error message with Error/Warning */
error_tag(struct zint_symbol * symbol,int error_number,const char * error_string)213 STATIC_UNLESS_ZINT_TEST int error_tag(struct zint_symbol *symbol, int error_number, const char *error_string) {
214
215 if (error_number != 0) {
216 static const char *error_fmt = "Error %.93s"; /* Truncate if too long */
217 static const char *warn_fmt = "Warning %.91s"; /* Truncate if too long */
218 const char *fmt = error_number >= ZINT_ERROR ? error_fmt : warn_fmt;
219 char error_buffer[100];
220
221 if (symbol->warn_level == WARN_FAIL_ALL) {
222 /* Convert to error equivalent */
223 if (error_number == ZINT_WARN_NONCOMPLIANT) {
224 error_number = ZINT_ERROR_NONCOMPLIANT;
225 } else if (error_number == ZINT_WARN_USES_ECI) {
226 error_number = ZINT_ERROR_USES_ECI;
227 } else { /* ZINT_WARN_INVALID_OPTION */
228 error_number = ZINT_ERROR_INVALID_OPTION;
229 }
230 fmt = error_fmt;
231 }
232 sprintf(error_buffer, fmt, error_string ? error_string : symbol->errtxt);
233 strcpy(symbol->errtxt, error_buffer);
234 }
235
236 return error_number;
237 }
238
239 /* Output a hexadecimal representation of the rendered symbol */
dump_plot(struct zint_symbol * symbol)240 static int dump_plot(struct zint_symbol *symbol) {
241 FILE *f;
242 int i, r;
243 char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
244 '9', 'A', 'B', 'C', 'D', 'E', 'F'};
245 int space = 0;
246
247 if (symbol->output_options & BARCODE_STDOUT) {
248 f = stdout;
249 } else {
250 f = fopen(symbol->outfile, "w");
251 if (!f) {
252 strcpy(symbol->errtxt, "201: Could not open output file");
253 return ZINT_ERROR_FILE_ACCESS;
254 }
255 }
256
257 for (r = 0; r < symbol->rows; r++) {
258 int byt = 0;
259 for (i = 0; i < symbol->width; i++) {
260 byt = byt << 1;
261 if (symbol->symbology == BARCODE_ULTRA) {
262 if (module_colour_is_set(symbol, r, i)) {
263 byt += 1;
264 }
265 } else {
266 if (module_is_set(symbol, r, i)) {
267 byt += 1;
268 }
269 }
270 if (((i + 1) % 4) == 0) {
271 fputc(hex[byt], f);
272 space++;
273 byt = 0;
274 }
275 if (space == 2 && i + 1 < symbol->width) {
276 fputc(' ', f);
277 space = 0;
278 }
279 }
280
281 if ((symbol->width % 4) != 0) {
282 byt = byt << (4 - (symbol->width % 4));
283 fputc(hex[byt], f);
284 }
285 fputs("\n", f);
286 space = 0;
287 }
288
289 if (symbol->output_options & BARCODE_STDOUT) {
290 fflush(f);
291 } else {
292 fclose(f);
293 }
294
295 return 0;
296 }
297
298 /* Process health industry bar code data */
hibc(struct zint_symbol * symbol,unsigned char source[],int length)299 static int hibc(struct zint_symbol *symbol, unsigned char source[], int length) {
300 int i;
301 int counter, error_number;
302 char to_process[113], check_digit;
303
304 /* without "+" and check: max 110 characters in HIBC 2.6 */
305 if (length > 110) {
306 strcpy(symbol->errtxt, "202: Data too long for HIBC LIC (110 character maximum)");
307 return ZINT_ERROR_TOO_LONG;
308 }
309 to_upper(source);
310 error_number = is_sane(TECHNETIUM, source, length);
311 if (error_number == ZINT_ERROR_INVALID_DATA) {
312 strcpy(symbol->errtxt, "203: Invalid character in data (alphanumerics, space and \"-.$/+%\" only)");
313 return error_number;
314 }
315
316 counter = 41;
317 for (i = 0; i < length; i++) {
318 counter += posn(TECHNETIUM, source[i]);
319 }
320 counter = counter % 43;
321
322 if (counter < 10) {
323 check_digit = itoc(counter);
324 } else {
325 if (counter < 36) {
326 check_digit = (counter - 10) + 'A';
327 } else {
328 switch (counter) {
329 case 36: check_digit = '-';
330 break;
331 case 37: check_digit = '.';
332 break;
333 case 38: check_digit = ' ';
334 break;
335 case 39: check_digit = '$';
336 break;
337 case 40: check_digit = '/';
338 break;
339 case 41: check_digit = '+';
340 break;
341 case 42: check_digit = '%';
342 break;
343 default: check_digit = ' ';
344 break; /* Keep compiler happy */
345 }
346 }
347 }
348
349 to_process[0] = '+';
350 memcpy(to_process + 1, source, length);
351 to_process[length + 1] = check_digit;
352 length += 2;
353 to_process[length] = '\0';
354
355 switch (symbol->symbology) {
356 case BARCODE_HIBC_128:
357 error_number = code_128(symbol, (unsigned char *) to_process, length);
358 ustrcpy(symbol->text, "*");
359 ustrcat(symbol->text, to_process);
360 ustrcat(symbol->text, "*");
361 break;
362 case BARCODE_HIBC_39:
363 symbol->option_2 = 0;
364 error_number = c39(symbol, (unsigned char *) to_process, length);
365 ustrcpy(symbol->text, "*");
366 ustrcat(symbol->text, to_process);
367 ustrcat(symbol->text, "*");
368 break;
369 case BARCODE_HIBC_DM:
370 error_number = dmatrix(symbol, (unsigned char *) to_process, length);
371 break;
372 case BARCODE_HIBC_QR:
373 error_number = qr_code(symbol, (unsigned char *) to_process, length);
374 break;
375 case BARCODE_HIBC_PDF:
376 error_number = pdf417enc(symbol, (unsigned char *) to_process, length);
377 break;
378 case BARCODE_HIBC_MICPDF:
379 error_number = micro_pdf417(symbol, (unsigned char *) to_process, length);
380 break;
381 case BARCODE_HIBC_AZTEC:
382 error_number = aztec(symbol, (unsigned char *) to_process, length);
383 break;
384 case BARCODE_HIBC_BLOCKF:
385 error_number = codablock(symbol, (unsigned char *) to_process, length);
386 break;
387 }
388
389 return error_number;
390 }
391
check_force_gs1(const int symbology)392 static int check_force_gs1(const int symbology) {
393 /* Returns 1 if symbology MUST have GS1 data */
394
395 switch (symbology) {
396 case BARCODE_GS1_128:
397 case BARCODE_EAN14:
398 case BARCODE_NVE18:
399 case BARCODE_DBAR_EXP:
400 case BARCODE_DBAR_EXPSTK:
401 return 1;
402 break;
403 }
404
405 return is_composite(symbology);
406 }
407
gs1_compliant(const int symbology)408 static int gs1_compliant(const int symbology) {
409 /* Returns 1 if symbology supports GS1 data */
410
411 switch (symbology) {
412 case BARCODE_CODE16K:
413 case BARCODE_AZTEC:
414 case BARCODE_DATAMATRIX:
415 case BARCODE_CODEONE:
416 case BARCODE_CODE49:
417 case BARCODE_QRCODE:
418 case BARCODE_DOTCODE:
419 case BARCODE_RMQR:
420 case BARCODE_ULTRA:
421 return 1;
422 break;
423 }
424
425 return check_force_gs1(symbology);
426 }
427
is_dotty(const int symbology)428 static int is_dotty(const int symbology) {
429 /* Returns 1 if symbology is a matrix design renderable as dots */
430
431 switch (symbology) {
432 /* Note MAXICODE and ULTRA absent */
433 case BARCODE_QRCODE:
434 case BARCODE_DATAMATRIX:
435 case BARCODE_MICROQR:
436 case BARCODE_HIBC_DM:
437 case BARCODE_AZTEC:
438 case BARCODE_HIBC_QR:
439 case BARCODE_HIBC_AZTEC:
440 case BARCODE_AZRUNE:
441 case BARCODE_CODEONE:
442 case BARCODE_GRIDMATRIX:
443 case BARCODE_HANXIN:
444 case BARCODE_DOTCODE:
445 case BARCODE_UPNQR:
446 case BARCODE_RMQR:
447 return 1;
448 break;
449 }
450
451 return 0;
452 }
453
is_fixed_ratio(const int symbology)454 static int is_fixed_ratio(const int symbology) {
455 /* Returns 1 if symbology has fixed aspect ratio (matrix design) */
456
457 if (is_dotty(symbology)) {
458 return 1;
459 }
460
461 switch (symbology) {
462 case BARCODE_MAXICODE:
463 case BARCODE_ULTRA:
464 return 1;
465 break;
466 }
467
468 return 0;
469 }
470
supports_eci(const int symbology)471 static int supports_eci(const int symbology) {
472 /* Returns 1 if symbology can encode the ECI character */
473
474 switch (symbology) {
475 case BARCODE_AZTEC:
476 case BARCODE_DATAMATRIX:
477 case BARCODE_MAXICODE:
478 case BARCODE_MICROPDF417:
479 case BARCODE_PDF417:
480 case BARCODE_PDF417COMP:
481 case BARCODE_QRCODE:
482 case BARCODE_DOTCODE:
483 case BARCODE_CODEONE:
484 case BARCODE_GRIDMATRIX:
485 case BARCODE_HANXIN:
486 case BARCODE_ULTRA:
487 return 1;
488 break;
489 }
490
491 return 0;
492 }
493
has_hrt(const int symbology)494 static int has_hrt(const int symbology) {
495 /* Returns 1 if symbology supports HRT */
496
497 if (is_fixed_ratio(symbology)) {
498 return 0;
499 }
500
501 switch (symbology) { /* These don't support HRT */
502 case BARCODE_CODE16K:
503 case BARCODE_CODE49:
504 case BARCODE_FLAT:
505 case BARCODE_POSTNET:
506 case BARCODE_FIM:
507 case BARCODE_PHARMA:
508 case BARCODE_PHARMA_TWO:
509 case BARCODE_PDF417:
510 case BARCODE_PDF417COMP:
511 case BARCODE_AUSPOST:
512 case BARCODE_AUSREPLY:
513 case BARCODE_AUSROUTE:
514 case BARCODE_AUSREDIRECT:
515 case BARCODE_RM4SCC:
516 case BARCODE_CODABLOCKF:
517 case BARCODE_JAPANPOST:
518 case BARCODE_DBAR_STK:
519 case BARCODE_DBAR_OMNSTK:
520 case BARCODE_DBAR_EXPSTK:
521 case BARCODE_PLANET:
522 case BARCODE_MICROPDF417:
523 case BARCODE_USPS_IMAIL:
524 case BARCODE_KIX:
525 case BARCODE_DAFT:
526 case BARCODE_HIBC_PDF:
527 case BARCODE_HIBC_MICPDF:
528 case BARCODE_HIBC_BLOCKF:
529 case BARCODE_MAILMARK:
530 case BARCODE_DBAR_STK_CC:
531 case BARCODE_DBAR_OMNSTK_CC:
532 case BARCODE_DBAR_EXPSTK_CC:
533 return 0;
534 break;
535 }
536
537 return 1;
538 }
539
540 static int reduced_charset(struct zint_symbol *symbol, unsigned char *source, int length);
541
extended_or_reduced_charset(struct zint_symbol * symbol,unsigned char * source,const int length)542 static int extended_or_reduced_charset(struct zint_symbol *symbol, unsigned char *source, const int length) {
543 int error_number = 0;
544
545 switch (symbol->symbology) {
546 /* These are the "elite" standards which have support for specific character sets */
547 case BARCODE_QRCODE: error_number = qr_code(symbol, source, length);
548 break;
549 case BARCODE_MICROQR: error_number = microqr(symbol, source, length);
550 break;
551 case BARCODE_GRIDMATRIX: error_number = grid_matrix(symbol, source, length);
552 break;
553 case BARCODE_HANXIN: error_number = han_xin(symbol, source, length);
554 break;
555 case BARCODE_UPNQR: error_number = upnqr(symbol, source, length);
556 break;
557 case BARCODE_RMQR: error_number = rmqr(symbol, source, length);
558 break;
559 default: error_number = reduced_charset(symbol, source, length);
560 break;
561 }
562
563 return error_number;
564 }
565
reduced_charset(struct zint_symbol * symbol,unsigned char * source,int length)566 static int reduced_charset(struct zint_symbol *symbol, unsigned char *source, int length) {
567 /* These are the "norm" standards which only support Latin-1 at most, though a few support ECI */
568 int error_number = 0;
569 unsigned char *preprocessed = source;
570
571 int eci_length = get_eci_length(symbol->eci, source, length);
572 #ifndef _MSC_VER
573 unsigned char preprocessed_buf[eci_length + 1];
574 #else
575 unsigned char *preprocessed_buf = (unsigned char *) _alloca(eci_length + 1);
576 #endif
577
578 if ((symbol->input_mode & 0x07) == UNICODE_MODE && is_eci_convertible(symbol->eci)) {
579 /* Prior check ensures ECI only set for those that support it */
580 preprocessed = preprocessed_buf;
581 error_number = utf8_to_eci(symbol->eci, source, preprocessed, &length);
582 if (error_number != 0) {
583 if (symbol->eci) {
584 sprintf(symbol->errtxt, "244: Invalid character in input data for ECI %d", symbol->eci);
585 } else {
586 strcpy(symbol->errtxt, "204: Invalid character in input data (ISO/IEC 8859-1 only)");
587 }
588 return error_number;
589 }
590 }
591
592 switch (symbol->symbology) {
593 case BARCODE_C25STANDARD: error_number = matrix_two_of_five(symbol, preprocessed, length);
594 break;
595 case BARCODE_C25IND: error_number = industrial_two_of_five(symbol, preprocessed, length);
596 break;
597 case BARCODE_C25INTER: error_number = interleaved_two_of_five(symbol, preprocessed, length);
598 break;
599 case BARCODE_C25IATA: error_number = iata_two_of_five(symbol, preprocessed, length);
600 break;
601 case BARCODE_C25LOGIC: error_number = logic_two_of_five(symbol, preprocessed, length);
602 break;
603 case BARCODE_DPLEIT: error_number = dpleit(symbol, preprocessed, length);
604 break;
605 case BARCODE_DPIDENT: error_number = dpident(symbol, preprocessed, length);
606 break;
607 case BARCODE_UPCA:
608 case BARCODE_UPCA_CHK:
609 case BARCODE_UPCE:
610 case BARCODE_UPCE_CHK:
611 case BARCODE_EANX:
612 case BARCODE_EANX_CHK:
613 case BARCODE_ISBNX:
614 error_number = eanx(symbol, preprocessed, length);
615 break;
616 case BARCODE_GS1_128: error_number = ean_128(symbol, preprocessed, length);
617 break;
618 case BARCODE_CODE39: error_number = c39(symbol, preprocessed, length);
619 break;
620 case BARCODE_PZN: error_number = pharmazentral(symbol, preprocessed, length);
621 break;
622 case BARCODE_EXCODE39: error_number = ec39(symbol, preprocessed, length);
623 break;
624 case BARCODE_CODABAR: error_number = codabar(symbol, preprocessed, length);
625 break;
626 case BARCODE_CODE93: error_number = c93(symbol, preprocessed, length);
627 break;
628 case BARCODE_LOGMARS: error_number = c39(symbol, preprocessed, length);
629 break;
630 case BARCODE_CODE128:
631 case BARCODE_CODE128B:
632 error_number = code_128(symbol, preprocessed, length);
633 break;
634 case BARCODE_NVE18: error_number = nve_18(symbol, preprocessed, length);
635 break;
636 case BARCODE_CODE11: error_number = code_11(symbol, preprocessed, length);
637 break;
638 case BARCODE_MSI_PLESSEY: error_number = msi_handle(symbol, preprocessed, length);
639 break;
640 case BARCODE_TELEPEN: error_number = telepen(symbol, preprocessed, length);
641 break;
642 case BARCODE_TELEPEN_NUM: error_number = telepen_num(symbol, preprocessed, length);
643 break;
644 case BARCODE_PHARMA: error_number = pharma_one(symbol, preprocessed, length);
645 break;
646 case BARCODE_PLESSEY: error_number = plessey(symbol, preprocessed, length);
647 break;
648 case BARCODE_ITF14: error_number = itf14(symbol, preprocessed, length);
649 break;
650 case BARCODE_FLAT: error_number = flattermarken(symbol, preprocessed, length);
651 break;
652 case BARCODE_FIM: error_number = fim(symbol, preprocessed, length);
653 break;
654 case BARCODE_POSTNET: error_number = post_plot(symbol, preprocessed, length);
655 break;
656 case BARCODE_PLANET: error_number = planet_plot(symbol, preprocessed, length);
657 break;
658 case BARCODE_RM4SCC: error_number = royal_plot(symbol, preprocessed, length);
659 break;
660 case BARCODE_AUSPOST:
661 case BARCODE_AUSREPLY:
662 case BARCODE_AUSROUTE:
663 case BARCODE_AUSREDIRECT:
664 error_number = australia_post(symbol, preprocessed, length);
665 break;
666 case BARCODE_CODE16K: error_number = code16k(symbol, preprocessed, length);
667 break;
668 case BARCODE_PHARMA_TWO: error_number = pharma_two(symbol, preprocessed, length);
669 break;
670 case BARCODE_USPS_IMAIL: error_number = imail(symbol, preprocessed, length);
671 break;
672 case BARCODE_DBAR_OMN:
673 case BARCODE_DBAR_STK:
674 case BARCODE_DBAR_OMNSTK:
675 error_number = rss14(symbol, preprocessed, length);
676 break;
677 case BARCODE_DBAR_LTD: error_number = rsslimited(symbol, preprocessed, length);
678 break;
679 case BARCODE_DBAR_EXP:
680 case BARCODE_DBAR_EXPSTK:
681 error_number = rssexpanded(symbol, preprocessed, length);
682 break;
683 case BARCODE_EANX_CC:
684 case BARCODE_GS1_128_CC:
685 case BARCODE_DBAR_OMN_CC:
686 case BARCODE_DBAR_LTD_CC:
687 case BARCODE_DBAR_EXP_CC:
688 case BARCODE_UPCA_CC:
689 case BARCODE_UPCE_CC:
690 case BARCODE_DBAR_STK_CC:
691 case BARCODE_DBAR_OMNSTK_CC:
692 case BARCODE_DBAR_EXPSTK_CC:
693 error_number = composite(symbol, preprocessed, length);
694 break;
695 case BARCODE_KIX: error_number = kix_code(symbol, preprocessed, length);
696 break;
697 case BARCODE_CODE32: error_number = code32(symbol, preprocessed, length);
698 break;
699 case BARCODE_DAFT: error_number = daft_code(symbol, preprocessed, length);
700 break;
701 case BARCODE_EAN14:
702 error_number = ean_14(symbol, preprocessed, length);
703 break;
704 case BARCODE_AZRUNE: error_number = aztec_runes(symbol, preprocessed, length);
705 break;
706 case BARCODE_KOREAPOST: error_number = korea_post(symbol, preprocessed, length);
707 break;
708 case BARCODE_HIBC_128:
709 case BARCODE_HIBC_39:
710 case BARCODE_HIBC_DM:
711 case BARCODE_HIBC_QR:
712 case BARCODE_HIBC_PDF:
713 case BARCODE_HIBC_MICPDF:
714 case BARCODE_HIBC_AZTEC:
715 case BARCODE_HIBC_BLOCKF:
716 error_number = hibc(symbol, preprocessed, length);
717 break;
718 case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed, length);
719 break;
720 case BARCODE_CODE49: error_number = code_49(symbol, preprocessed, length);
721 break;
722 case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed, length);
723 break;
724 case BARCODE_CODEONE: error_number = code_one(symbol, preprocessed, length);
725 break;
726 case BARCODE_DATAMATRIX: error_number = dmatrix(symbol, preprocessed, length);
727 break;
728 case BARCODE_PDF417:
729 case BARCODE_PDF417COMP:
730 error_number = pdf417enc(symbol, preprocessed, length);
731 break;
732 case BARCODE_MICROPDF417: error_number = micro_pdf417(symbol, preprocessed, length);
733 break;
734 case BARCODE_MAXICODE: error_number = maxicode(symbol, preprocessed, length);
735 break;
736 case BARCODE_AZTEC: error_number = aztec(symbol, preprocessed, length);
737 break;
738 case BARCODE_DOTCODE: error_number = dotcode(symbol, preprocessed, length);
739 break;
740 case BARCODE_CODABLOCKF: error_number = codablock(symbol, preprocessed, length);
741 break;
742 case BARCODE_VIN: error_number = vin(symbol, preprocessed, length);
743 break;
744 case BARCODE_MAILMARK: error_number = mailmark(symbol, preprocessed, length);
745 break;
746 case BARCODE_ULTRA: error_number = ultracode(symbol, preprocessed, length);
747 break;
748 case BARCODE_DPD: error_number = dpd_parcel(symbol, preprocessed, length);
749 break;
750 default: /* Should never happen */
751 strcpy(symbol->errtxt, "001: Internal error"); /* Not reached */
752 error_number = ZINT_ERROR_ENCODING_PROBLEM;
753 break;
754 }
755
756 return error_number;
757 }
758
strip_bom(unsigned char * source,int * input_length)759 STATIC_UNLESS_ZINT_TEST void strip_bom(unsigned char *source, int *input_length) {
760 int i;
761
762 /* Note if BOM is only data then not stripped */
763 if (*input_length > 3 && (source[0] == 0xef) && (source[1] == 0xbb) && (source[2] == 0xbf)) {
764 /* BOM at start of input data, strip in accordance with RFC 3629 */
765 for (i = 3; i <= *input_length; i++) { /* Include terminating NUL */
766 source[i - 3] = source[i];
767 }
768 *input_length -= 3;
769 }
770 }
771
escape_char_process(struct zint_symbol * symbol,unsigned char * input_string,int * length)772 static int escape_char_process(struct zint_symbol *symbol, unsigned char *input_string, int *length) {
773 int in_posn, out_posn;
774 int hex1, hex2;
775 int i, unicode;
776
777 #ifndef _MSC_VER
778 unsigned char escaped_string[*length + 1];
779 #else
780 unsigned char *escaped_string = (unsigned char *) _alloca(*length + 1);
781 #endif
782
783 in_posn = 0;
784 out_posn = 0;
785
786 do {
787 if (input_string[in_posn] == '\\') {
788 if (in_posn + 1 >= *length) {
789 strcpy(symbol->errtxt, "236: Incomplete escape character in input data");
790 return ZINT_ERROR_INVALID_DATA;
791 }
792 switch (input_string[in_posn + 1]) {
793 case '0': escaped_string[out_posn] = 0x00; /* Null */
794 in_posn += 2;
795 break;
796 case 'E': escaped_string[out_posn] = 0x04; /* End of Transmission */
797 in_posn += 2;
798 break;
799 case 'a': escaped_string[out_posn] = 0x07; /* Bell */
800 in_posn += 2;
801 break;
802 case 'b': escaped_string[out_posn] = 0x08; /* Backspace */
803 in_posn += 2;
804 break;
805 case 't': escaped_string[out_posn] = 0x09; /* Horizontal tab */
806 in_posn += 2;
807 break;
808 case 'n': escaped_string[out_posn] = 0x0a; /* Line feed */
809 in_posn += 2;
810 break;
811 case 'v': escaped_string[out_posn] = 0x0b; /* Vertical tab */
812 in_posn += 2;
813 break;
814 case 'f': escaped_string[out_posn] = 0x0c; /* Form feed */
815 in_posn += 2;
816 break;
817 case 'r': escaped_string[out_posn] = 0x0d; /* Carriage return */
818 in_posn += 2;
819 break;
820 case 'e': escaped_string[out_posn] = 0x1b; /* Escape */
821 in_posn += 2;
822 break;
823 case 'G': escaped_string[out_posn] = 0x1d; /* Group Separator */
824 in_posn += 2;
825 break;
826 case 'R': escaped_string[out_posn] = 0x1e; /* Record Separator */
827 in_posn += 2;
828 break;
829 case 'x': if (in_posn + 4 > *length) {
830 strcpy(symbol->errtxt, "232: Incomplete escape character in input data");
831 return ZINT_ERROR_INVALID_DATA;
832 }
833 hex1 = ctoi(input_string[in_posn + 2]);
834 hex2 = ctoi(input_string[in_posn + 3]);
835 if ((hex1 >= 0) && (hex2 >= 0)) {
836 escaped_string[out_posn] = (hex1 << 4) + hex2;
837 in_posn += 4;
838 } else {
839 strcpy(symbol->errtxt, "233: Corrupt escape character in input data");
840 return ZINT_ERROR_INVALID_DATA;
841 }
842 break;
843 case '\\': escaped_string[out_posn] = '\\';
844 in_posn += 2;
845 break;
846 case 'u':
847 if (in_posn + 6 > *length) {
848 strcpy(symbol->errtxt, "209: Incomplete Unicode escape character in input data");
849 return ZINT_ERROR_INVALID_DATA;
850 }
851 unicode = 0;
852 for (i = 0; i < 4; i++) {
853 if (ctoi(input_string[in_posn + i + 2]) == -1) {
854 strcpy(symbol->errtxt, "211: Corrupt Unicode escape character in input data");
855 return ZINT_ERROR_INVALID_DATA;
856 }
857 unicode = unicode << 4;
858 unicode += ctoi(input_string[in_posn + i + 2]);
859 }
860 /* Exclude reversed BOM and surrogates */
861 if (unicode == 0xfffe || (unicode >= 0xd800 && unicode < 0xe000)) {
862 strcpy(symbol->errtxt, "246: Invalid Unicode BMP escape character in input data");
863 return ZINT_ERROR_INVALID_DATA;
864 }
865 if (unicode >= 0x800) {
866 escaped_string[out_posn] = 0xe0 + ((unicode & 0xf000) >> 12);
867 out_posn++;
868 escaped_string[out_posn] = 0x80 + ((unicode & 0x0fc0) >> 6);
869 out_posn++;
870 escaped_string[out_posn] = 0x80 + (unicode & 0x003f);
871 } else if (unicode >= 0x80) {
872 escaped_string[out_posn] = 0xc0 + ((unicode & 0x07c0) >> 6);
873 out_posn++;
874 escaped_string[out_posn] = 0x80 + (unicode & 0x003f);
875 } else {
876 escaped_string[out_posn] = unicode & 0x7f;
877 }
878 in_posn += 6;
879 break;
880 default: strcpy(symbol->errtxt, "234: Unrecognised escape character in input data");
881 return ZINT_ERROR_INVALID_DATA;
882 break;
883 }
884 } else {
885 escaped_string[out_posn] = input_string[in_posn];
886 in_posn++;
887 }
888 out_posn++;
889 } while (in_posn < *length);
890
891 memcpy(input_string, escaped_string, out_posn);
892 input_string[out_posn] = '\0';
893 *length = out_posn;
894
895 return 0;
896 }
897
898 /* Encode a barcode. If `length` is 0, `source` must be NUL-terminated. */
ZBarcode_Encode(struct zint_symbol * symbol,const unsigned char * source,int length)899 int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int length) {
900 int error_number, warn_number;
901 #ifdef _MSC_VER
902 unsigned char *local_source;
903 #endif
904
905 if (!symbol) return ZINT_ERROR_INVALID_DATA;
906
907 if (symbol->debug & ZINT_DEBUG_PRINT) {
908 printf("ZBarcode_Encode: symbology: %d, input_mode: 0x%X, ECI: %d, option_1: %d, option_2: %d,"
909 " option_3: %d, scale: %g\n output_options: 0x%X, fg: %s, bg: %s,"
910 " length: %d, First 10 source: \"%.*s\", First 10 primary: \"%.10s\"\n",
911 symbol->symbology, symbol->input_mode, symbol->eci, symbol->option_1, symbol->option_2,
912 symbol->option_3, symbol->scale, symbol->output_options, symbol->fgcolour, symbol->bgcolour,
913 length, length < 10 ? length : 10, source ? (const char *) source : "<NULL>", symbol->primary);
914 }
915
916 warn_number = 0;
917
918 if (source == NULL) {
919 return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "200: Input data NULL");
920 }
921 if (length <= 0) {
922 length = (int) ustrlen(source);
923 }
924 if (length <= 0) {
925 return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "205: No input data");
926 }
927 if (length > ZINT_MAX_DATA_LEN) {
928 return error_tag(symbol, ZINT_ERROR_TOO_LONG, "243: Input data too long");
929 }
930
931 /* First check the symbology field */
932 if (!ZBarcode_ValidID(symbol->symbology)) {
933 int orig_symbology = symbol->symbology; /* For self-check */
934 if (symbol->symbology < 1) {
935 warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "206: Symbology out of range");
936 if (warn_number >= ZINT_ERROR) {
937 return warn_number;
938 }
939 symbol->symbology = BARCODE_CODE128;
940 /* symbol->symbologys 1 to 126 are defined by tbarcode */
941 } else if (symbol->symbology == 5) {
942 symbol->symbology = BARCODE_C25STANDARD;
943 } else if ((symbol->symbology >= 10) && (symbol->symbology <= 12)) {
944 symbol->symbology = BARCODE_EANX;
945 } else if (symbol->symbology == 15) {
946 symbol->symbology = BARCODE_EANX;
947 } else if (symbol->symbology == 17) {
948 symbol->symbology = BARCODE_UPCA;
949 } else if (symbol->symbology == 19) {
950 warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "207: Codabar 18 not supported");
951 if (warn_number >= ZINT_ERROR) {
952 return warn_number;
953 }
954 symbol->symbology = BARCODE_CODABAR;
955 } else if (symbol->symbology == 26) { /* UPC-A up to tbarcode 9, ISSN for tbarcode 10+ */
956 symbol->symbology = BARCODE_UPCA;
957 } else if (symbol->symbology == 27) { /* UPCD1 up to tbarcode 9, ISSN + 2 digit add-on for tbarcode 10+ */
958 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "208: UPCD1 not supported");
959 } else if (symbol->symbology == 33) {
960 symbol->symbology = BARCODE_GS1_128;
961 } else if (symbol->symbology == 36) {
962 symbol->symbology = BARCODE_UPCA;
963 } else if (symbol->symbology == 39) {
964 symbol->symbology = BARCODE_UPCE;
965 } else if ((symbol->symbology >= 41) && (symbol->symbology <= 45)) {
966 symbol->symbology = BARCODE_POSTNET;
967 } else if (symbol->symbology == 46) {
968 symbol->symbology = BARCODE_PLESSEY;
969 } else if (symbol->symbology == 48) {
970 symbol->symbology = BARCODE_NVE18;
971 } else if (symbol->symbology == 54) { /* General Parcel up to tbarcode 9, Brazelian CEPNet for tbarcode 10+ */
972 warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "210: General Parcel Code not supported");
973 if (warn_number >= ZINT_ERROR) {
974 return warn_number;
975 }
976 symbol->symbology = BARCODE_CODE128;
977 } else if ((symbol->symbology == 59) || (symbol->symbology == 61)) {
978 symbol->symbology = BARCODE_CODE128;
979 } else if (symbol->symbology == 62) {
980 symbol->symbology = BARCODE_CODE93;
981 } else if ((symbol->symbology == 64) || (symbol->symbology == 65)) {
982 symbol->symbology = BARCODE_AUSPOST;
983 } else if (symbol->symbology == 78) {
984 symbol->symbology = BARCODE_DBAR_OMN;
985 } else if (symbol->symbology == 83) {
986 symbol->symbology = BARCODE_PLANET;
987 } else if (symbol->symbology == 88) {
988 symbol->symbology = BARCODE_GS1_128;
989 } else if (symbol->symbology == 91) { /* BC412 up to tbarcode 9, Code 32 for tbarcode 10+ */
990 warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "212: Symbology out of range");
991 if (warn_number >= ZINT_ERROR) {
992 return warn_number;
993 }
994 symbol->symbology = BARCODE_CODE128;
995 } else if ((symbol->symbology >= 94) && (symbol->symbology <= 95)) {
996 warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "213: Symbology out of range");
997 if (warn_number >= ZINT_ERROR) {
998 return warn_number;
999 }
1000 symbol->symbology = BARCODE_CODE128;
1001 } else if (symbol->symbology == 100) {
1002 symbol->symbology = BARCODE_HIBC_128;
1003 } else if (symbol->symbology == 101) {
1004 symbol->symbology = BARCODE_HIBC_39;
1005 } else if (symbol->symbology == 103) {
1006 symbol->symbology = BARCODE_HIBC_DM;
1007 } else if (symbol->symbology == 105) {
1008 symbol->symbology = BARCODE_HIBC_QR;
1009 } else if (symbol->symbology == 107) {
1010 symbol->symbology = BARCODE_HIBC_PDF;
1011 } else if (symbol->symbology == 109) {
1012 symbol->symbology = BARCODE_HIBC_MICPDF;
1013 } else if (symbol->symbology == 111) {
1014 symbol->symbology = BARCODE_HIBC_BLOCKF;
1015 } else if ((symbol->symbology == 113) || (symbol->symbology == 114)) {
1016 warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "214: Symbology out of range");
1017 if (warn_number >= ZINT_ERROR) {
1018 return warn_number;
1019 }
1020 symbol->symbology = BARCODE_CODE128;
1021 } else if ((symbol->symbology >= 117) && (symbol->symbology <= 127)) {
1022 if (symbol->symbology != 121) { /* BARCODE_MAILMARK */
1023 warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "215: Symbology out of range");
1024 if (warn_number >= ZINT_ERROR) {
1025 return warn_number;
1026 }
1027 symbol->symbology = BARCODE_CODE128;
1028 }
1029 /* Everything from 128 up is Zint-specific */
1030 } else if (symbol->symbology > 145) {
1031 warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "216: Symbology out of range");
1032 if (warn_number >= ZINT_ERROR) {
1033 return warn_number;
1034 }
1035 symbol->symbology = BARCODE_CODE128;
1036 }
1037 if (symbol->symbology == orig_symbology) { /* Should never happen */
1038 return error_tag(symbol, ZINT_ERROR_ENCODING_PROBLEM, "000: Internal error"); /* Not reached */
1039 }
1040 }
1041
1042 if (symbol->eci != 0) {
1043 if (!(supports_eci(symbol->symbology))) {
1044 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "217: Symbology does not support ECI switching");
1045 }
1046 if ((symbol->eci < 0) || (symbol->eci == 1) || (symbol->eci == 2) || (symbol->eci > 999999)) {
1047 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "218: Invalid ECI mode");
1048 }
1049 }
1050
1051 if ((symbol->dot_size < 0.01f) || (symbol->dot_size > 20.0f)) {
1052 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "221: Invalid dot size");
1053 }
1054
1055 if ((symbol->input_mode & 0x07) > 2) {
1056 symbol->input_mode = DATA_MODE; /* Reset completely TODO: in future, warn/error */
1057 }
1058
1059 if ((symbol->input_mode & 0x07) == UNICODE_MODE && !is_valid_utf8(source, length)) {
1060 return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "245: Invalid UTF-8 in input data");
1061 }
1062
1063 #ifndef _MSC_VER
1064 unsigned char local_source[length + 1];
1065 #else
1066 local_source = (unsigned char *) _alloca(length + 1);
1067 #endif
1068
1069 memcpy(local_source, source, length);
1070 local_source[length] = '\0';
1071
1072 /* Start acting on input mode */
1073 if (symbol->input_mode & ESCAPE_MODE) {
1074 error_number = escape_char_process(symbol, local_source, &length); /* Only returns errors, not warnings */
1075 if (error_number != 0) {
1076 return error_tag(symbol, error_number, NULL);
1077 }
1078 }
1079
1080 if ((symbol->input_mode & 0x07) == UNICODE_MODE) {
1081 strip_bom(local_source, &length);
1082 }
1083
1084 if (((symbol->input_mode & 0x07) == GS1_MODE) || (check_force_gs1(symbol->symbology))) {
1085 if (gs1_compliant(symbol->symbology) == 1) {
1086 // Reduce input for composite and non-forced symbologies, others (EAN128 and RSS_EXP based) will
1087 // handle it themselves
1088 if (is_composite(symbol->symbology) || !check_force_gs1(symbol->symbology)) {
1089 #ifndef _MSC_VER
1090 unsigned char reduced[length + 1];
1091 #else
1092 unsigned char *reduced = (unsigned char *) _alloca(length + 1);
1093 #endif
1094 error_number = gs1_verify(symbol, local_source, length, reduced);
1095 if (error_number) {
1096 static const char in_2d_comp[] = " in 2D component";
1097 if (is_composite(symbol->symbology)
1098 && strlen(symbol->errtxt) + strlen(in_2d_comp) < sizeof(symbol->errtxt)) {
1099 strcat(symbol->errtxt, in_2d_comp);
1100 }
1101 error_number = error_tag(symbol, error_number, NULL);
1102 if (error_number >= ZINT_ERROR) {
1103 return error_number;
1104 }
1105 warn_number = error_number; /* Override any previous warning (errtxt has been overwritten) */
1106 }
1107 ustrcpy(local_source, reduced); // Cannot contain NUL char
1108 length = (int) ustrlen(local_source);
1109 }
1110 } else {
1111 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "220: Selected symbology does not support GS1 mode");
1112 }
1113 }
1114
1115 error_number = extended_or_reduced_charset(symbol, local_source, length);
1116
1117 if ((error_number == ZINT_ERROR_INVALID_DATA) && symbol->eci == 0 && supports_eci(symbol->symbology)
1118 && (symbol->input_mode & 0x07) == UNICODE_MODE) {
1119 /* Try another ECI mode */
1120 symbol->eci = get_best_eci(local_source, length);
1121 if (symbol->eci != 0) {
1122 error_number = extended_or_reduced_charset(symbol, local_source, length);
1123 /* Inclusion of ECI more noteworthy than other warnings, so overwrite (if any) */
1124 if (error_number < ZINT_ERROR) {
1125 error_number = ZINT_WARN_USES_ECI;
1126 if (!(symbol->debug & ZINT_DEBUG_TEST)) {
1127 sprintf(symbol->errtxt, "222: Encoded data includes ECI %d", symbol->eci);
1128 }
1129 if (symbol->debug & ZINT_DEBUG_PRINT) printf("Added ECI %d\n", symbol->eci);
1130 }
1131 }
1132 }
1133
1134 if (error_number == 0) {
1135 error_number = warn_number; /* Already tagged */
1136 } else {
1137 error_number = error_tag(symbol, error_number, NULL);
1138 }
1139
1140 if (error_number < ZINT_ERROR) {
1141 if (symbol->height < 0.5f) { /* Absolute minimum */
1142 (void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
1143 }
1144 }
1145
1146 return error_number;
1147 }
1148
1149 /* Output a previously encoded symbol to file `symbol->outfile` */
ZBarcode_Print(struct zint_symbol * symbol,int rotate_angle)1150 int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) {
1151 int error_number;
1152 int len;
1153
1154 if (!symbol) return ZINT_ERROR_INVALID_DATA;
1155
1156 switch (rotate_angle) {
1157 case 0:
1158 case 90:
1159 case 180:
1160 case 270:
1161 break;
1162 default:
1163 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "223: Invalid rotation angle");
1164 break;
1165 }
1166
1167 if (symbol->output_options & BARCODE_DOTTY_MODE) {
1168 if (!(is_dotty(symbol->symbology))) {
1169 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "224: Selected symbology cannot be rendered as dots");
1170 }
1171 }
1172
1173 len = (int) strlen(symbol->outfile);
1174 if (len > 3) {
1175 char output[4];
1176 output[0] = symbol->outfile[len - 3];
1177 output[1] = symbol->outfile[len - 2];
1178 output[2] = symbol->outfile[len - 1];
1179 output[3] = '\0';
1180 to_upper((unsigned char *) output);
1181
1182 if (!(strcmp(output, "PNG"))) {
1183 error_number = plot_raster(symbol, rotate_angle, OUT_PNG_FILE);
1184
1185 } else if (!(strcmp(output, "BMP"))) {
1186 error_number = plot_raster(symbol, rotate_angle, OUT_BMP_FILE);
1187
1188 } else if (!(strcmp(output, "PCX"))) {
1189 error_number = plot_raster(symbol, rotate_angle, OUT_PCX_FILE);
1190
1191 } else if (!(strcmp(output, "GIF"))) {
1192 error_number = plot_raster(symbol, rotate_angle, OUT_GIF_FILE);
1193
1194 } else if (!(strcmp(output, "TIF"))) {
1195 error_number = plot_raster(symbol, rotate_angle, OUT_TIF_FILE);
1196
1197 } else if (!(strcmp(output, "TXT"))) {
1198 error_number = dump_plot(symbol);
1199
1200 } else if (!(strcmp(output, "EPS"))) {
1201 error_number = plot_vector(symbol, rotate_angle, OUT_EPS_FILE);
1202
1203 } else if (!(strcmp(output, "SVG"))) {
1204 error_number = plot_vector(symbol, rotate_angle, OUT_SVG_FILE);
1205
1206 } else if (!(strcmp(output, "EMF"))) {
1207 error_number = plot_vector(symbol, rotate_angle, OUT_EMF_FILE);
1208
1209 } else {
1210 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "225: Unknown output format");
1211 }
1212 } else {
1213 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "226: Unknown output format");
1214 }
1215
1216 return error_tag(symbol, error_number, NULL);
1217 }
1218
1219 /* Output a previously encoded symbol to memory as raster (`symbol->bitmap`) */
ZBarcode_Buffer(struct zint_symbol * symbol,int rotate_angle)1220 int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle) {
1221 int error_number;
1222
1223 if (!symbol) return ZINT_ERROR_INVALID_DATA;
1224
1225 switch (rotate_angle) {
1226 case 0:
1227 case 90:
1228 case 180:
1229 case 270:
1230 break;
1231 default:
1232 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "228: Invalid rotation angle");
1233 break;
1234 }
1235
1236 if (symbol->output_options & BARCODE_DOTTY_MODE) {
1237 if (!(is_dotty(symbol->symbology))) {
1238 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "237: Selected symbology cannot be rendered as dots");
1239 }
1240 }
1241
1242 error_number = plot_raster(symbol, rotate_angle, OUT_BUFFER);
1243 return error_tag(symbol, error_number, NULL);
1244 }
1245
1246 /* Output a previously encoded symbol to memory as vector (`symbol->vector`) */
ZBarcode_Buffer_Vector(struct zint_symbol * symbol,int rotate_angle)1247 int ZBarcode_Buffer_Vector(struct zint_symbol *symbol, int rotate_angle) {
1248 int error_number;
1249
1250 if (!symbol) return ZINT_ERROR_INVALID_DATA;
1251
1252 switch (rotate_angle) {
1253 case 0:
1254 case 90:
1255 case 180:
1256 case 270:
1257 break;
1258 default:
1259 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "219: Invalid rotation angle");
1260 break;
1261 }
1262
1263 if (symbol->output_options & BARCODE_DOTTY_MODE) {
1264 if (!(is_dotty(symbol->symbology))) {
1265 return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "238: Selected symbology cannot be rendered as dots");
1266 }
1267 }
1268
1269 error_number = plot_vector(symbol, rotate_angle, OUT_BUFFER);
1270 return error_tag(symbol, error_number, NULL);
1271 }
1272
1273 /* Encode and output a symbol to file `symbol->outfile` */
ZBarcode_Encode_and_Print(struct zint_symbol * symbol,const unsigned char * source,int length,int rotate_angle)1274 int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, const unsigned char *source, int length, int rotate_angle) {
1275 int error_number;
1276 int first_err;
1277
1278 error_number = ZBarcode_Encode(symbol, source, length);
1279 if (error_number >= ZINT_ERROR) {
1280 return error_number;
1281 }
1282
1283 first_err = error_number;
1284 error_number = ZBarcode_Print(symbol, rotate_angle);
1285 if (error_number == 0) {
1286 error_number = first_err;
1287 }
1288 return error_number;
1289 }
1290
1291 /* Encode and output a symbol to memory as raster (`symbol->bitmap`) */
ZBarcode_Encode_and_Buffer(struct zint_symbol * symbol,const unsigned char * source,int length,int rotate_angle)1292 int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, const unsigned char *source, int length,
1293 int rotate_angle) {
1294 int error_number;
1295 int first_err;
1296
1297 error_number = ZBarcode_Encode(symbol, source, length);
1298 if (error_number >= ZINT_ERROR) {
1299 return error_number;
1300 }
1301
1302 first_err = error_number;
1303 error_number = ZBarcode_Buffer(symbol, rotate_angle);
1304 if (error_number == 0) {
1305 error_number = first_err;
1306 }
1307
1308 return error_number;
1309 }
1310
1311 /* Encode and output a symbol to memory as vector (`symbol->vector`) */
ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol * symbol,const unsigned char * source,int length,int rotate_angle)1312 int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol, const unsigned char *source, int length,
1313 int rotate_angle) {
1314 int error_number;
1315 int first_err;
1316
1317 error_number = ZBarcode_Encode(symbol, source, length);
1318 if (error_number >= ZINT_ERROR) {
1319 return error_number;
1320 }
1321
1322 first_err = error_number;
1323 error_number = ZBarcode_Buffer_Vector(symbol, rotate_angle);
1324 if (error_number == 0) {
1325 error_number = first_err;
1326 }
1327
1328 return error_number;
1329 }
1330
1331 /* Encode a barcode using input data from file `filename` */
ZBarcode_Encode_File(struct zint_symbol * symbol,const char * filename)1332 int ZBarcode_Encode_File(struct zint_symbol *symbol, const char *filename) {
1333 FILE *file;
1334 int file_opened = 0;
1335 unsigned char *buffer;
1336 long fileLen;
1337 size_t n;
1338 size_t nRead = 0;
1339 int ret;
1340
1341 if (!symbol) return ZINT_ERROR_INVALID_DATA;
1342
1343 if (!filename) {
1344 return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "239: Filename NULL");
1345 }
1346
1347 if (!strcmp(filename, "-")) {
1348 file = stdin;
1349 fileLen = ZINT_MAX_DATA_LEN;
1350 } else {
1351 file = fopen(filename, "rb");
1352 if (!file) {
1353 sprintf(symbol->errtxt, "229: Unable to read input file (%d: %.30s)", errno, strerror(errno));
1354 return error_tag(symbol, ZINT_ERROR_INVALID_DATA, NULL);
1355 }
1356 file_opened = 1;
1357
1358 /* Get file length */
1359 fseek(file, 0, SEEK_END);
1360 fileLen = ftell(file);
1361 fseek(file, 0, SEEK_SET);
1362
1363 /* On many Linux distros ftell() returns LONG_MAX not -1 on error */
1364 if (fileLen <= 0 || fileLen == LONG_MAX) {
1365 fclose(file);
1366 return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "235: Input file empty or unseekable");
1367 }
1368 if (fileLen > ZINT_MAX_DATA_LEN) {
1369 fclose(file);
1370 return error_tag(symbol, ZINT_ERROR_TOO_LONG, "230: Input file too long");
1371 }
1372 }
1373
1374 /* Allocate memory */
1375 buffer = (unsigned char *) malloc(fileLen);
1376 if (!buffer) {
1377 if (file_opened) {
1378 fclose(file);
1379 }
1380 return error_tag(symbol, ZINT_ERROR_MEMORY, "231: Insufficient memory for file read buffer");
1381 }
1382
1383 /* Read file contents into buffer */
1384
1385 do {
1386 n = fread(buffer + nRead, 1, fileLen - nRead, file);
1387 if (ferror(file)) {
1388 sprintf(symbol->errtxt, "241: Input file read error (%d: %.30s)", errno, strerror(errno));
1389 if (file_opened) {
1390 fclose(file);
1391 }
1392 free(buffer);
1393 return error_tag(symbol, ZINT_ERROR_INVALID_DATA, NULL);
1394 }
1395 nRead += n;
1396 } while (!feof(file) && (0 < n) && ((long) nRead < fileLen));
1397
1398 if (file_opened) {
1399 fclose(file);
1400 }
1401 ret = ZBarcode_Encode(symbol, buffer, (int) nRead);
1402 free(buffer);
1403 return ret;
1404 }
1405
1406 /* Encode a symbol using input data from file `filename` and output to file `symbol->outfile` */
ZBarcode_Encode_File_and_Print(struct zint_symbol * symbol,const char * filename,int rotate_angle)1407 int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, const char *filename, int rotate_angle) {
1408 int error_number;
1409 int first_err;
1410
1411 error_number = ZBarcode_Encode_File(symbol, filename);
1412 if (error_number >= ZINT_ERROR) {
1413 return error_number;
1414 }
1415
1416 first_err = error_number;
1417 error_number = ZBarcode_Print(symbol, rotate_angle);
1418 if (error_number == 0) {
1419 error_number = first_err;
1420 }
1421
1422 return error_number;
1423 }
1424
1425 /* Encode a symbol using input data from file `filename` and output to memory as raster (`symbol->bitmap`) */
ZBarcode_Encode_File_and_Buffer(struct zint_symbol * symbol,char const * filename,int rotate_angle)1426 int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char const *filename, int rotate_angle) {
1427 int error_number;
1428 int first_err;
1429
1430 error_number = ZBarcode_Encode_File(symbol, filename);
1431 if (error_number >= ZINT_ERROR) {
1432 return error_number;
1433 }
1434
1435 first_err = error_number;
1436 error_number = ZBarcode_Buffer(symbol, rotate_angle);
1437 if (error_number == 0) {
1438 error_number = first_err;
1439 }
1440
1441 return error_number;
1442 }
1443
1444 /* Encode a symbol using input data from file `filename` and output to memory as vector (`symbol->vector`) */
ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol * symbol,const char * filename,int rotate_angle)1445 int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol, const char *filename, int rotate_angle) {
1446 int error_number;
1447 int first_err;
1448
1449 error_number = ZBarcode_Encode_File(symbol, filename);
1450 if (error_number >= ZINT_ERROR) {
1451 return error_number;
1452 }
1453
1454 first_err = error_number;
1455 error_number = ZBarcode_Buffer_Vector(symbol, rotate_angle);
1456 if (error_number == 0) {
1457 error_number = first_err;
1458 }
1459
1460 return error_number;
1461 }
1462
ZBarcode_ValidID(int symbol_id)1463 int ZBarcode_ValidID(int symbol_id) {
1464 /* Checks whether a symbology is supported */
1465 static const unsigned char ids[146] = {
1466 0, 1, 2, 3, 4, 0, 6, 7, 8, 9,
1467 0, 0, 0, 13, 14, 0, 16, 0, 18, 0,
1468 20, 21, 22, 23, 24, 25, 0, 0, 28, 29,
1469 30, 31, 32, 0, 34, 35, 0, 37, 38, 0,
1470 40, 0, 0, 0, 0, 0, 0, 47, 0, 49,
1471 50, 51, 52, 53, 0, 55, 56, 57, 58, 0,
1472 60, 0, 0, 63, 0, 0, 66, 67, 68, 69,
1473 70, 71, 72, 73, 74, 75, 76, 77, 0, 79,
1474 80, 81, 82, 0, 84, 85, 86, 87, 0, 89,
1475 90, 0, 92, 93, 0, 0, 96, 97, 98, 99,
1476 0, 0, 102, 0, 104, 0, 106, 0, 108, 0,
1477 110, 0, 112, 0, 0, 115, 116, 0, 0, 0,
1478 0, 121, 0, 0, 0, 0, 0, 0, 128, 129,
1479 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
1480 140, 141, 142, 143, 144, 145,
1481 };
1482
1483 if (symbol_id <= 0 || symbol_id > 145) {
1484 return 0;
1485 }
1486
1487 return ids[symbol_id] != 0;
1488 }
1489
1490 /* Return the capability flags for symbology `symbol_id` that match `cap_flag` */
ZBarcode_Cap(int symbol_id,unsigned int cap_flag)1491 unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag) {
1492 unsigned int result = 0;
1493
1494 if (!ZBarcode_ValidID(symbol_id)) {
1495 return 0;
1496 }
1497
1498 if ((cap_flag & ZINT_CAP_HRT) && has_hrt(symbol_id)) {
1499 result |= ZINT_CAP_HRT;
1500 }
1501 if ((cap_flag & ZINT_CAP_STACKABLE) && is_stackable(symbol_id)) {
1502 result |= ZINT_CAP_STACKABLE;
1503 }
1504 if ((cap_flag & ZINT_CAP_EXTENDABLE) && is_extendable(symbol_id)) {
1505 result |= ZINT_CAP_EXTENDABLE;
1506 }
1507 if ((cap_flag & ZINT_CAP_COMPOSITE) && is_composite(symbol_id)) {
1508 result |= ZINT_CAP_COMPOSITE;
1509 }
1510 if ((cap_flag & ZINT_CAP_ECI) && supports_eci(symbol_id)) {
1511 result |= ZINT_CAP_ECI;
1512 }
1513 if ((cap_flag & ZINT_CAP_GS1) && gs1_compliant(symbol_id)) {
1514 result |= ZINT_CAP_GS1;
1515 }
1516 if ((cap_flag & ZINT_CAP_DOTTY) && is_dotty(symbol_id)) {
1517 result |= ZINT_CAP_DOTTY;
1518 }
1519 if ((cap_flag & ZINT_CAP_FIXED_RATIO) && is_fixed_ratio(symbol_id)) {
1520 result |= ZINT_CAP_FIXED_RATIO;
1521 }
1522 if (cap_flag & ZINT_CAP_READER_INIT) {
1523 /* Note does not include HIBC versions */
1524 switch (symbol_id) {
1525 case BARCODE_CODE128: /* Note does not include GS1_128 or NVE18 */
1526 case BARCODE_CODE128B:
1527 case BARCODE_CODE16K:
1528 case BARCODE_CODABLOCKF:
1529 case BARCODE_PDF417:
1530 case BARCODE_PDF417COMP:
1531 case BARCODE_DATAMATRIX:
1532 case BARCODE_MICROPDF417:
1533 case BARCODE_AZTEC:
1534 case BARCODE_DOTCODE:
1535 case BARCODE_GRIDMATRIX:
1536 case BARCODE_ULTRA:
1537 result |= ZINT_CAP_READER_INIT;
1538 break;
1539 }
1540 }
1541 if (cap_flag & ZINT_CAP_FULL_MULTIBYTE) {
1542 switch (symbol_id) {
1543 case BARCODE_QRCODE:
1544 case BARCODE_MICROQR:
1545 //case BARCODE_HIBC_QR: Note character set restricted to ASCII subset
1546 //case BARCODE_UPNQR: Note does not use Kanji mode
1547 case BARCODE_RMQR:
1548 case BARCODE_HANXIN:
1549 case BARCODE_GRIDMATRIX:
1550 result |= ZINT_CAP_FULL_MULTIBYTE;
1551 break;
1552 }
1553 }
1554 if (cap_flag & ZINT_CAP_MASK) {
1555 switch (symbol_id) {
1556 case BARCODE_QRCODE:
1557 case BARCODE_MICROQR:
1558 case BARCODE_HANXIN:
1559 case BARCODE_DOTCODE:
1560 result |= ZINT_CAP_MASK;
1561 break;
1562 }
1563 }
1564
1565 return result;
1566 }
1567
1568 /* Return the version of Zint linked to */
ZBarcode_Version()1569 int ZBarcode_Version() {
1570 if (ZINT_VERSION_BUILD) {
1571 return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE * 10
1572 + ZINT_VERSION_BUILD;
1573 }
1574 return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE;
1575 }
1576