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