Created
November 25, 2022 20:08
-
-
Save brozkeff/b8a5b2b27bf236f1399e197899a4780c to your computer and use it in GitHub Desktop.
Attempt to re-insert code to Zint 2.11 from Zint 2.6.7 supporting old code needed for gLabels3 compatibility
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From da94d696fac2c4e2eedc6c82e71bd867b5bce177 Mon Sep 17 00:00:00 2001 | |
From: brozkeff <brozkeff@gmail.com> | |
Date: Fri, 25 Nov 2022 21:03:49 +0100 | |
Subject: [PATCH] Squashed history | |
--- | |
CMakeLists.txt | 75 ++ | |
library.c | 1874 ++++++++++++++++++++++++++++++++++++++++++++++++ | |
render.c | 859 ++++++++++++++++++++++ | |
zint.h | 454 ++++++++++++ | |
4 files changed, 3262 insertions(+) | |
create mode 100644 CMakeLists.txt | |
create mode 100644 library.c | |
create mode 100755 render.c | |
create mode 100644 zint.h | |
diff --git a/CMakeLists.txt b/CMakeLists.txt | |
new file mode 100644 | |
index 0000000..2d2fa56 | |
--- /dev/null | |
+++ b/CMakeLists.txt | |
@@ -0,0 +1,75 @@ | |
+# Copyright (C) 2008 by BogDan Vatra < bogdan@licentia.eu > | |
+# Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com> | |
+# vim: set ts=4 sw=4 et : | |
+# re-added render.c to zint_COMMON_SRCS from 2.6.7 for gLabels, by brozkeff 2022-11-25 | |
+ | |
+project(zint) | |
+ | |
+configure_file(zintconfig.h.in ${CMAKE_CURRENT_SOURCE_DIR}/zintconfig.h) | |
+ | |
+set(zint_COMMON_SRCS common.c library.c render.c large.c reedsol.c gs1.c eci.c general_field.c) | |
+set(zint_ONEDIM_SRCS bc412.c code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c) | |
+set(zint_POSTAL_SRCS postal.c auspost.c imail.c mailmark.c) | |
+set(zint_TWODIM_SRCS code16k.c codablock.c dmatrix.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c hanxin.c dotcode.c ultra.c) | |
+set(zint_OUTPUT_SRCS vector.c ps.c svg.c emf.c bmp.c pcx.c gif.c png.c tif.c raster.c output.c) | |
+set(zint_SRCS ${zint_OUTPUT_SRCS} ${zint_COMMON_SRCS} ${zint_ONEDIM_SRCS} ${zint_POSTAL_SRCS} ${zint_TWODIM_SRCS}) | |
+ | |
+add_library(zint SHARED ${zint_SRCS}) | |
+ | |
+if(WIN32) | |
+ target_sources(${PROJECT_NAME} PRIVATE libzint.rc) | |
+endif() | |
+ | |
+if(ZINT_STATIC) | |
+ add_library(zint-static STATIC ${zint_SRCS}) | |
+endif() | |
+ | |
+function(zint_target_link_libraries library) | |
+ target_link_libraries(zint ${library}) | |
+ if(ZINT_STATIC) | |
+ target_link_libraries(zint-static ${library}) | |
+ endif() | |
+endfunction() | |
+ | |
+function(zint_target_compile_definitions scope definition) | |
+ target_compile_definitions(zint ${scope} ${definition}) | |
+ if(ZINT_STATIC) | |
+ target_compile_definitions(zint-static ${scope} ${definition}) | |
+ endif() | |
+endfunction() | |
+ | |
+set_target_properties(zint PROPERTIES SOVERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}" | |
+ VERSION ${ZINT_VERSION}) | |
+ | |
+if(ZINT_USE_PNG) | |
+ find_package(PNG) | |
+endif() | |
+ | |
+if(ZINT_USE_PNG AND PNG_FOUND) | |
+ zint_target_link_libraries(PNG::PNG) | |
+else() | |
+ zint_target_compile_definitions(PUBLIC NO_PNG) | |
+endif() | |
+ | |
+if(ZINT_TEST) | |
+ zint_target_compile_definitions(PUBLIC ZINT_TEST) | |
+endif() | |
+ | |
+if(NOT MSVC) | |
+ # Link with standard C math library. | |
+ zint_target_link_libraries(m) | |
+endif() | |
+ | |
+if(MSVC) | |
+ target_compile_definitions(zint PRIVATE DLL_EXPORT) | |
+endif() | |
+ | |
+install(TARGETS zint ${INSTALL_TARGETS_DEFAULT_ARGS}) | |
+if(ZINT_STATIC) | |
+ install(TARGETS zint-static ${INSTALL_TARGETS_DEFAULT_ARGS}) | |
+endif() | |
+install(FILES zint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel) | |
+ | |
+if(ZINT_TEST) | |
+ add_subdirectory(tests) | |
+endif() | |
diff --git a/library.c b/library.c | |
new file mode 100644 | |
index 0000000..f4e787b | |
--- /dev/null | |
+++ b/library.c | |
@@ -0,0 +1,1874 @@ | |
+/* library.c - external functions of libzint */ | |
+/* | |
+ libzint - the open source barcode library | |
+ Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com> | |
+ | |
+ Redistribution and use in source and binary forms, with or without | |
+ modification, are permitted provided that the following conditions | |
+ are met: | |
+ | |
+ 1. Redistributions of source code must retain the above copyright | |
+ notice, this list of conditions and the following disclaimer. | |
+ 2. Redistributions in binary form must reproduce the above copyright | |
+ notice, this list of conditions and the following disclaimer in the | |
+ documentation and/or other materials provided with the distribution. | |
+ 3. Neither the name of the project nor the names of its contributors | |
+ may be used to endorse or promote products derived from this software | |
+ without specific prior written permission. | |
+ | |
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | |
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
+ SUCH DAMAGE. | |
+ */ | |
+/* SPDX-License-Identifier: BSD-3-Clause */ | |
+ | |
+#include <assert.h> | |
+#include <errno.h> | |
+#include <limits.h> | |
+#include <stdio.h> | |
+#include "common.h" | |
+#include "eci.h" | |
+#include "gs1.h" | |
+#include "zfiletypes.h" | |
+ | |
+/* It's assumed that int is at least 32 bits, the following will compile-time fail if not | |
+ * https://stackoverflow.com/a/1980056 */ | |
+typedef char static_assert_int_at_least_32bits[CHAR_BIT != 8 || sizeof(int) < 4 ? -1 : 1]; | |
+ | |
+typedef char static_assert_uint16_is_16bits[sizeof(uint16_t) != 2 ? -1 : 1]; | |
+typedef char static_assert_int32_is_32bits[sizeof(int32_t) != 4 ? -1 : 1]; | |
+typedef char static_assert_uint32_is_32bits[sizeof(uint32_t) != 4 ? -1 : 1]; | |
+typedef char static_assert_uint64_at_least_64bits[sizeof(uint64_t) < 8 ? -1 : 1]; | |
+ | |
+/* Create and initialize a symbol structure */ | |
+struct zint_symbol *ZBarcode_Create(void) { | |
+ struct zint_symbol *symbol; | |
+ | |
+ symbol = (struct zint_symbol *) calloc(1, sizeof(*symbol)); | |
+ if (!symbol) return NULL; | |
+ | |
+ symbol->symbology = BARCODE_CODE128; | |
+ symbol->scale = 1.0f; | |
+ strcpy(symbol->fgcolour, "000000"); | |
+ symbol->fgcolor = &symbol->fgcolour[0]; | |
+ strcpy(symbol->bgcolour, "ffffff"); | |
+ symbol->bgcolor = &symbol->bgcolour[0]; | |
+#ifdef NO_PNG | |
+ strcpy(symbol->outfile, "out.gif"); | |
+#else | |
+ strcpy(symbol->outfile, "out.png"); | |
+#endif | |
+ symbol->option_1 = -1; | |
+ symbol->show_hrt = 1; /* Show human readable text */ | |
+ symbol->fontsize = 8; | |
+ symbol->input_mode = DATA_MODE; | |
+ symbol->eci = 0; /* Default 0 uses ECI 3 */ | |
+ symbol->dot_size = 4.0f / 5.0f; | |
+ symbol->guard_descent = 5.0f; | |
+ symbol->warn_level = WARN_DEFAULT; | |
+ symbol->bitmap = NULL; | |
+ symbol->alphamap = NULL; | |
+ symbol->vector = NULL; | |
+ | |
+ return symbol; | |
+} | |
+ | |
+INTERNAL void vector_free(struct zint_symbol *symbol); /* Free vector structures */ | |
+ | |
+/* Free any output buffers that may have been created and initialize output fields */ | |
+void ZBarcode_Clear(struct zint_symbol *symbol) { | |
+ int i; | |
+ | |
+ if (!symbol) return; | |
+ | |
+ for (i = 0; i < symbol->rows; i++) { | |
+ memset(symbol->encoded_data[i], 0, sizeof(symbol->encoded_data[0])); | |
+ } | |
+ symbol->rows = 0; | |
+ symbol->width = 0; | |
+ memset(symbol->row_height, 0, sizeof(symbol->row_height)); | |
+ memset(symbol->text, 0, sizeof(symbol->text)); | |
+ symbol->errtxt[0] = '\0'; | |
+ if (symbol->bitmap != NULL) { | |
+ free(symbol->bitmap); | |
+ symbol->bitmap = NULL; | |
+ } | |
+ if (symbol->alphamap != NULL) { | |
+ free(symbol->alphamap); | |
+ symbol->alphamap = NULL; | |
+ } | |
+ symbol->bitmap_width = 0; | |
+ symbol->bitmap_height = 0; | |
+ symbol->bitmap_byte_length = 0; | |
+ | |
+ /* If there is a rendered version, ensure its memory is released */ | |
+ vector_free(symbol); | |
+} | |
+ | |
+/* Free a symbol structure, including any output buffers */ | |
+void ZBarcode_Delete(struct zint_symbol *symbol) { | |
+ if (!symbol) return; | |
+ | |
+ if (symbol->bitmap != NULL) | |
+ free(symbol->bitmap); | |
+ if (symbol->alphamap != NULL) | |
+ free(symbol->alphamap); | |
+ | |
+ /* If there is a rendered version, ensure its memory is released */ | |
+ vector_free(symbol); | |
+ | |
+ free(symbol); | |
+} | |
+ | |
+/* Symbology handlers */ | |
+INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */ | |
+INTERNAL int code39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */ | |
+INTERNAL int pzn(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */ | |
+/* Extended Code 3 from 9 (or Code 39+) */ | |
+INTERNAL int excode39(struct zint_symbol *symbol, unsigned char source[], int length); | |
+/* Codabar - a simple substitution cipher */ | |
+INTERNAL int codabar(struct zint_symbol *symbol, unsigned char source[], int length); | |
+/* Code 2 of 5 Standard (& Matrix) */ | |
+INTERNAL int c25standard(struct zint_symbol *symbol, unsigned char source[], int length); | |
+INTERNAL int c25ind(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Industrial */ | |
+INTERNAL int c25iata(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */ | |
+INTERNAL int c25inter(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Interleaved */ | |
+INTERNAL int c25logic(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Data Logic */ | |
+INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */ | |
+INTERNAL int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */ | |
+INTERNAL int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */ | |
+/* Code 93 - a re-working of Code 39+, generates 2 check digits */ | |
+INTERNAL int code93(struct zint_symbol *symbol, unsigned char source[], int length); | |
+INTERNAL int code128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */ | |
+INTERNAL int gs1_128(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-128 (GS1-128) */ | |
+INTERNAL int code11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */ | |
+INTERNAL int msi_plessey(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */ | |
+INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen ASCII */ | |
+INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen Numeric */ | |
+INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], int length); /* Plessey Code */ | |
+INTERNAL int pharma(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */ | |
+INTERNAL int flat(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */ | |
+INTERNAL int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */ | |
+INTERNAL int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */ | |
+INTERNAL int postnet(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */ | |
+INTERNAL int planet(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */ | |
+/* Intelligent Mail (aka USPS OneCode) */ | |
+INTERNAL int usps_imail(struct zint_symbol *symbol, unsigned char source[], int length); | |
+INTERNAL int rm4scc(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */ | |
+INTERNAL int auspost(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */ | |
+INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */ | |
+INTERNAL int pdf417(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* PDF417 */ | |
+INTERNAL int micropdf417(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Micro PDF417 */ | |
+INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Maxicode */ | |
+INTERNAL int dbar_omn(struct zint_symbol *symbol, unsigned char source[], int length); /* DataBar Omnidirectional */ | |
+INTERNAL int dbar_ltd(struct zint_symbol *symbol, unsigned char source[], int length); /* DataBar Limited */ | |
+INTERNAL int dbar_exp(struct zint_symbol *symbol, unsigned char source[], int length); /* DataBar Expanded */ | |
+INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */ | |
+INTERNAL int kix(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */ | |
+INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Aztec Code */ | |
+INTERNAL int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */ | |
+INTERNAL int daft(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */ | |
+INTERNAL int ean14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */ | |
+INTERNAL int nve18(struct zint_symbol *symbol, unsigned char source[], int length); /* NVE-18 */ | |
+INTERNAL int microqr(struct zint_symbol *symbol, unsigned char source[], int length); /* Micro QR Code */ | |
+INTERNAL int azrune(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */ | |
+INTERNAL int koreapost(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */ | |
+INTERNAL int japanpost(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */ | |
+INTERNAL int code49(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 49 */ | |
+INTERNAL int channel(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */ | |
+INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Code One */ | |
+INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Grid Matrix */ | |
+INTERNAL int hanxin(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Han Xin */ | |
+INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* DotCode */ | |
+INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int length); /* Codablock */ | |
+INTERNAL int upnqr(struct zint_symbol *symbol, unsigned char source[], int length); /* UPNQR */ | |
+INTERNAL int qrcode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* QR Code */ | |
+/* Data Matrix (IEC16022) */ | |
+INTERNAL int datamatrix(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); | |
+/* VIN Code (Vehicle Identification Number) */ | |
+INTERNAL int vin(struct zint_symbol *symbol, unsigned char source[], int length); | |
+/* Royal Mail 4-state Mailmark */ | |
+INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int length); | |
+INTERNAL int ultra(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* Ultracode */ | |
+INTERNAL int rmqr(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); /* rMQR */ | |
+INTERNAL int dpd(struct zint_symbol *symbol, unsigned char source[], int length); /* DPD Code */ | |
+INTERNAL int bc412(struct zint_symbol *symbol, unsigned char source[], int length); /* BC412 */ | |
+ | |
+/* Output handlers */ | |
+INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to PNG/BMP/PCX */ | |
+INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to EPS/EMF/SVG */ | |
+ | |
+extern int render_plot(struct zint_symbol *symbol, float width, float height); /* Plot to gLabels - backported from 2.6.7 by brozkeff 2022-11-25 */ | |
+ | |
+/* Prefix error message with Error/Warning */ | |
+static int error_tag(struct zint_symbol *symbol, int error_number, const char *error_string) { | |
+ | |
+ if (error_number != 0) { | |
+ static const char error_fmt[] = "Error %.93s"; /* Truncate if too long */ | |
+ static const char warn_fmt[] = "Warning %.91s"; /* Truncate if too long */ | |
+ const char *fmt = error_number >= ZINT_ERROR ? error_fmt : warn_fmt; | |
+ char error_buffer[100]; | |
+ | |
+ if (error_number < ZINT_ERROR && symbol->warn_level == WARN_FAIL_ALL) { | |
+ /* Convert to error equivalent */ | |
+ if (error_number == ZINT_WARN_NONCOMPLIANT) { | |
+ error_number = ZINT_ERROR_NONCOMPLIANT; | |
+ } else if (error_number == ZINT_WARN_USES_ECI) { | |
+ error_number = ZINT_ERROR_USES_ECI; | |
+ } else { /* ZINT_WARN_INVALID_OPTION */ | |
+ error_number = ZINT_ERROR_INVALID_OPTION; | |
+ } | |
+ fmt = error_fmt; | |
+ } | |
+ sprintf(error_buffer, fmt, error_string ? error_string : symbol->errtxt); | |
+ strcpy(symbol->errtxt, error_buffer); | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+#ifdef ZINT_TEST /* Wrapper for direct testing */ | |
+INTERNAL int error_tag_test(struct zint_symbol *symbol, int error_number, const char *error_string) { | |
+ return error_tag(symbol, error_number, error_string); | |
+} | |
+#endif | |
+ | |
+/* Output a hexadecimal representation of the rendered symbol */ | |
+static int dump_plot(struct zint_symbol *symbol) { | |
+ FILE *f; | |
+ int i, r; | |
+ char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', | |
+ '9', 'A', 'B', 'C', 'D', 'E', 'F'}; | |
+ int space = 0; | |
+ | |
+ if (symbol->output_options & BARCODE_STDOUT) { | |
+ f = stdout; | |
+ } else { | |
+ f = fopen(symbol->outfile, "w"); | |
+ if (!f) { | |
+ strcpy(symbol->errtxt, "201: Could not open output file"); | |
+ return ZINT_ERROR_FILE_ACCESS; | |
+ } | |
+ } | |
+ | |
+ for (r = 0; r < symbol->rows; r++) { | |
+ int byt = 0; | |
+ for (i = 0; i < symbol->width; i++) { | |
+ byt = byt << 1; | |
+ if (symbol->symbology == BARCODE_ULTRA) { | |
+ if (module_colour_is_set(symbol, r, i)) { | |
+ byt += 1; | |
+ } | |
+ } else { | |
+ if (module_is_set(symbol, r, i)) { | |
+ byt += 1; | |
+ } | |
+ } | |
+ if (((i + 1) % 4) == 0) { | |
+ fputc(hex[byt], f); | |
+ space++; | |
+ byt = 0; | |
+ } | |
+ if (space == 2 && i + 1 < symbol->width) { | |
+ fputc(' ', f); | |
+ space = 0; | |
+ } | |
+ } | |
+ | |
+ if ((symbol->width % 4) != 0) { | |
+ byt = byt << (4 - (symbol->width % 4)); | |
+ fputc(hex[byt], f); | |
+ } | |
+ fputs("\n", f); | |
+ space = 0; | |
+ } | |
+ | |
+ if (symbol->output_options & BARCODE_STDOUT) { | |
+ fflush(f); | |
+ } else { | |
+ fclose(f); | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+/* Permitted HIBC characters */ | |
+static const char TECHNETIUM[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; /* Same as SILVER (CODE39) */ | |
+ | |
+/* Process health industry bar code data */ | |
+static int hibc(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { | |
+ unsigned char *source = segs[0].source; | |
+ int length = segs[0].length; | |
+ | |
+ int i; | |
+ int counter, error_number = 0; | |
+ char to_process[110 + 2 + 1]; | |
+ int posns[110]; | |
+ | |
+ /* without "+" and check: max 110 characters in HIBC 2.6 */ | |
+ if (length > 110) { | |
+ strcpy(symbol->errtxt, "202: Data too long for HIBC LIC (110 character maximum)"); | |
+ return ZINT_ERROR_TOO_LONG; | |
+ } | |
+ to_upper(source, length); | |
+ if (!is_sane_lookup(TECHNETIUM, sizeof(TECHNETIUM) - 1, source, length, posns)) { | |
+ strcpy(symbol->errtxt, "203: Invalid character in data (alphanumerics, space and \"-.$/+%\" only)"); | |
+ return ZINT_ERROR_INVALID_DATA; | |
+ } | |
+ | |
+ counter = 41; | |
+ for (i = 0; i < length; i++) { | |
+ counter += posns[i]; | |
+ } | |
+ counter = counter % 43; | |
+ | |
+ to_process[0] = '+'; | |
+ memcpy(to_process + 1, source, length); | |
+ to_process[++length] = TECHNETIUM[counter]; | |
+ to_process[++length] = '\0'; | |
+ | |
+ segs[0].source = (unsigned char *) to_process; | |
+ segs[0].length = length; | |
+ | |
+ switch (symbol->symbology) { | |
+ case BARCODE_HIBC_128: | |
+ error_number = code128(symbol, segs[0].source, segs[0].length); | |
+ ustrcpy(symbol->text, "*"); | |
+ ustrcat(symbol->text, to_process); | |
+ ustrcat(symbol->text, "*"); | |
+ break; | |
+ case BARCODE_HIBC_39: | |
+ symbol->option_2 = 0; | |
+ error_number = code39(symbol, segs[0].source, segs[0].length); | |
+ ustrcpy(symbol->text, "*"); | |
+ ustrcat(symbol->text, to_process); | |
+ ustrcat(symbol->text, "*"); | |
+ break; | |
+ case BARCODE_HIBC_DM: | |
+ error_number = datamatrix(symbol, segs, seg_count); | |
+ break; | |
+ case BARCODE_HIBC_QR: | |
+ error_number = qrcode(symbol, segs, seg_count); | |
+ break; | |
+ case BARCODE_HIBC_PDF: | |
+ error_number = pdf417(symbol, segs, seg_count); | |
+ break; | |
+ case BARCODE_HIBC_MICPDF: | |
+ error_number = micropdf417(symbol, segs, seg_count); | |
+ break; | |
+ case BARCODE_HIBC_AZTEC: | |
+ error_number = aztec(symbol, segs, seg_count); | |
+ break; | |
+ case BARCODE_HIBC_BLOCKF: | |
+ error_number = codablockf(symbol, segs[0].source, segs[0].length); | |
+ break; | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+/* Returns 1 if symbology MUST have GS1 data */ | |
+static int check_force_gs1(const int symbology) { | |
+ | |
+ switch (symbology) { | |
+ case BARCODE_GS1_128: | |
+ case BARCODE_EAN14: | |
+ case BARCODE_NVE18: | |
+ case BARCODE_DBAR_EXP: | |
+ case BARCODE_DBAR_EXPSTK: | |
+ return 1; | |
+ break; | |
+ } | |
+ | |
+ return is_composite(symbology); | |
+} | |
+ | |
+/* Returns 1 if symbology supports GS1 data */ | |
+static int gs1_compliant(const int symbology) { | |
+ | |
+ switch (symbology) { | |
+ case BARCODE_CODE16K: | |
+ case BARCODE_AZTEC: | |
+ case BARCODE_DATAMATRIX: | |
+ case BARCODE_CODE49: | |
+ case BARCODE_QRCODE: | |
+ case BARCODE_DOTCODE: | |
+ case BARCODE_CODEONE: | |
+ case BARCODE_ULTRA: | |
+ case BARCODE_RMQR: | |
+ /* TODO: case BARCODE_CODABLOCKF: */ | |
+ /* TODO: case BARCODE_HANXIN: */ | |
+ /* TODO: case BARCODE_GRIDMATRIX: */ | |
+ return 1; | |
+ break; | |
+ } | |
+ | |
+ return check_force_gs1(symbology); | |
+} | |
+ | |
+/* Returns 1 if symbology can encode the ECI character */ | |
+static int supports_eci(const int symbology) { | |
+ | |
+ switch (symbology) { | |
+ case BARCODE_AZTEC: | |
+ case BARCODE_DATAMATRIX: | |
+ case BARCODE_MAXICODE: | |
+ case BARCODE_MICROPDF417: | |
+ case BARCODE_PDF417: | |
+ case BARCODE_PDF417COMP: | |
+ case BARCODE_QRCODE: | |
+ case BARCODE_DOTCODE: | |
+ case BARCODE_CODEONE: | |
+ case BARCODE_GRIDMATRIX: | |
+ case BARCODE_HANXIN: | |
+ case BARCODE_ULTRA: | |
+ case BARCODE_RMQR: | |
+ return 1; | |
+ break; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+/* Returns 1 if symbology is Health Industry Bar Code */ | |
+static int is_hibc(const int symbology) { | |
+ | |
+ switch (symbology) { | |
+ case BARCODE_HIBC_128: | |
+ case BARCODE_HIBC_39: | |
+ case BARCODE_HIBC_DM: | |
+ case BARCODE_HIBC_QR: | |
+ case BARCODE_HIBC_PDF: | |
+ case BARCODE_HIBC_MICPDF: | |
+ case BARCODE_HIBC_BLOCKF: | |
+ case BARCODE_HIBC_AZTEC: | |
+ return 1; | |
+ break; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+/* Returns 1 if symbology supports HRT */ | |
+static int has_hrt(const int symbology) { | |
+ | |
+ if (is_fixed_ratio(symbology)) { | |
+ return 0; | |
+ } | |
+ | |
+ switch (symbology) { /* These don't support HRT */ | |
+ case BARCODE_CODE16K: | |
+ case BARCODE_CODE49: | |
+ case BARCODE_FLAT: | |
+ case BARCODE_POSTNET: | |
+ case BARCODE_FIM: | |
+ case BARCODE_PHARMA: | |
+ case BARCODE_PHARMA_TWO: | |
+ case BARCODE_PDF417: | |
+ case BARCODE_PDF417COMP: | |
+ case BARCODE_AUSPOST: | |
+ case BARCODE_AUSREPLY: | |
+ case BARCODE_AUSROUTE: | |
+ case BARCODE_AUSREDIRECT: | |
+ case BARCODE_RM4SCC: | |
+ case BARCODE_CODABLOCKF: | |
+ case BARCODE_JAPANPOST: | |
+ case BARCODE_DBAR_STK: | |
+ case BARCODE_DBAR_OMNSTK: | |
+ case BARCODE_DBAR_EXPSTK: | |
+ case BARCODE_PLANET: | |
+ case BARCODE_MICROPDF417: | |
+ case BARCODE_USPS_IMAIL: | |
+ case BARCODE_KIX: | |
+ case BARCODE_DAFT: | |
+ case BARCODE_HIBC_PDF: | |
+ case BARCODE_HIBC_MICPDF: | |
+ case BARCODE_HIBC_BLOCKF: | |
+ case BARCODE_MAILMARK: | |
+ case BARCODE_DBAR_STK_CC: | |
+ case BARCODE_DBAR_OMNSTK_CC: | |
+ case BARCODE_DBAR_EXPSTK_CC: | |
+ return 0; | |
+ break; | |
+ } | |
+ | |
+ return 1; | |
+} | |
+ | |
+/* Suppress warning ISO C forbids initialization between function pointer and ‘void *’ */ | |
+#if defined(__GNUC__) || defined(__clang__) | |
+#pragma GCC diagnostic push | |
+#pragma GCC diagnostic ignored "-Wpedantic" | |
+#endif | |
+ | |
+/* Used for dispatching barcodes and for whether symbol id valid */ | |
+typedef int (*barcode_segs_func_t)(struct zint_symbol *, struct zint_seg[], const int); | |
+typedef int (*barcode_func_t)(struct zint_symbol *, unsigned char[], int); | |
+static const void *barcode_funcs[BARCODE_LAST + 1] = { | |
+ NULL, code11, c25standard, c25inter, c25iata, /*0-4*/ | |
+ NULL, c25logic, c25ind, code39, excode39, /*5-9*/ | |
+ NULL, NULL, NULL, eanx, eanx, /*10-14*/ | |
+ NULL, gs1_128, NULL, codabar, NULL, /*15-19*/ | |
+ code128, dpleit, dpident, code16k, code49, /*20-24*/ | |
+ code93, NULL, NULL, flat, dbar_omn, /*25-29*/ | |
+ dbar_ltd, dbar_exp, telepen, NULL, eanx, /*30-34*/ | |
+ eanx, NULL, eanx, eanx, NULL, /*35-39*/ | |
+ postnet, NULL, NULL, NULL, NULL, /*40-44*/ | |
+ NULL, NULL, msi_plessey, NULL, fim, /*45-49*/ | |
+ code39, pharma, pzn, pharma_two, postnet, /*50-54*/ | |
+ pdf417, pdf417, maxicode, qrcode, NULL, /*55-59*/ | |
+ code128, NULL, NULL, auspost, NULL, /*60-64*/ | |
+ NULL, auspost, auspost, auspost, eanx, /*65-69*/ | |
+ rm4scc, datamatrix, ean14, vin, codablockf, /*70-74*/ | |
+ nve18, japanpost, koreapost, NULL, dbar_omn, /*75-79*/ | |
+ dbar_omn, dbar_exp, planet, NULL, micropdf417, /*80-84*/ | |
+ usps_imail, plessey, telepen_num, NULL, itf14, /*85-89*/ | |
+ kix, NULL, aztec, daft, NULL, /*90-94*/ | |
+ NULL, dpd, microqr, hibc, hibc, /*95-99*/ | |
+ NULL, NULL, hibc, NULL, hibc, /*100-104*/ | |
+ NULL, hibc, NULL, hibc, NULL, /*105-109*/ | |
+ hibc, NULL, hibc, NULL, NULL, /*110-114*/ | |
+ dotcode, hanxin, NULL, NULL, NULL, /*115-119*/ | |
+ NULL, mailmark, NULL, NULL, NULL, /*120-124*/ | |
+ NULL, NULL, NULL, azrune, code32, /*125-129*/ | |
+ composite, composite, composite, composite, composite, /*130-134*/ | |
+ composite, composite, composite, composite, composite, /*135-139*/ | |
+ channel, codeone, gridmatrix, upnqr, ultra, /*140-144*/ | |
+ rmqr, bc412, | |
+}; | |
+ | |
+static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count); | |
+ | |
+/* Main dispatch, checking for barcodes which handle ECIs/character sets themselves, otherwise calling | |
+ `reduced_charset()` */ | |
+static int extended_or_reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { | |
+ int error_number = 0; | |
+ | |
+ switch (symbol->symbology) { | |
+ /* These are the "elite" standards which have support for specific character sets + ECI */ | |
+ case BARCODE_QRCODE: | |
+ case BARCODE_GRIDMATRIX: | |
+ case BARCODE_HANXIN: | |
+ case BARCODE_RMQR: | |
+ error_number = (*(barcode_segs_func_t)barcode_funcs[symbol->symbology])(symbol, segs, seg_count); | |
+ break; | |
+ /* These are the standards which have support for specific character sets but not ECI */ | |
+ case BARCODE_MICROQR: | |
+ case BARCODE_UPNQR: | |
+ error_number = (*(barcode_func_t)barcode_funcs[symbol->symbology])(symbol, segs[0].source, | |
+ segs[0].length); | |
+ break; | |
+ default: error_number = reduced_charset(symbol, segs, seg_count); | |
+ break; | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+/* These are the "norm" standards which only support Latin-1 at most, though a few support ECI */ | |
+static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) { | |
+ int error_number = 0; | |
+ int i; | |
+ struct zint_seg *local_segs = (struct zint_seg *) z_alloca(sizeof(struct zint_seg) * seg_count); | |
+ int *convertible = (int *) z_alloca(sizeof(int) * seg_count); | |
+ | |
+ if ((symbol->input_mode & 0x07) == UNICODE_MODE && is_eci_convertible_segs(segs, seg_count, convertible)) { | |
+ unsigned char *preprocessed; | |
+ const int eci_length_segs = get_eci_length_segs(segs, seg_count); | |
+ unsigned char *preprocessed_buf = (unsigned char *) z_alloca(eci_length_segs + seg_count); | |
+ | |
+ /* Prior check ensures ECI only set for those that support it */ | |
+ segs_cpy(symbol, segs, seg_count, local_segs); /* Shallow copy (needed to set default ECIs) */ | |
+ preprocessed = preprocessed_buf; | |
+ for (i = 0; i < seg_count; i++) { | |
+ if (convertible[i]) { | |
+ error_number = utf8_to_eci(local_segs[i].eci, local_segs[i].source, preprocessed, | |
+ &local_segs[i].length); | |
+ if (error_number != 0) { | |
+ if (local_segs[i].eci) { | |
+ sprintf(symbol->errtxt, "244: Invalid character in input data for ECI %d", local_segs[i].eci); | |
+ } else { | |
+ strcpy(symbol->errtxt, "204: Invalid character in input data (ISO/IEC 8859-1 only)"); | |
+ } | |
+ return error_number; | |
+ } | |
+ local_segs[i].source = preprocessed; | |
+ preprocessed += local_segs[i].length + 1; | |
+ } | |
+ } | |
+ if (supports_eci(symbol->symbology) || is_hibc(symbol->symbology)) { | |
+ error_number = (*(barcode_segs_func_t)barcode_funcs[symbol->symbology])(symbol, local_segs, seg_count); | |
+ } else { | |
+ error_number = (*(barcode_func_t)barcode_funcs[symbol->symbology])(symbol, local_segs[0].source, | |
+ local_segs[0].length); | |
+ } | |
+ } else { | |
+ if (supports_eci(symbol->symbology) || is_hibc(symbol->symbology)) { | |
+ segs_cpy(symbol, segs, seg_count, local_segs); /* Shallow copy (needed to set default ECIs) */ | |
+ error_number = (*(barcode_segs_func_t)barcode_funcs[symbol->symbology])(symbol, local_segs, seg_count); | |
+ } else { | |
+ error_number = (*(barcode_func_t)barcode_funcs[symbol->symbology])(symbol, segs[0].source, | |
+ segs[0].length); | |
+ } | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+#if defined(__GNUC__) || defined(__clang__) | |
+#pragma GCC diagnostic pop | |
+#endif | |
+ | |
+/* Remove Unicode BOM at start of data */ | |
+static void strip_bom(unsigned char *source, int *input_length) { | |
+ int i; | |
+ | |
+ /* Note if BOM is only data then not stripped */ | |
+ if (*input_length > 3 && (source[0] == 0xef) && (source[1] == 0xbb) && (source[2] == 0xbf)) { | |
+ /* BOM at start of input data, strip in accordance with RFC 3629 */ | |
+ for (i = 3; i <= *input_length; i++) { /* Include terminating NUL */ | |
+ source[i - 3] = source[i]; | |
+ } | |
+ *input_length -= 3; | |
+ } | |
+} | |
+ | |
+#ifdef ZINT_TEST /* Wrapper for direct testing */ | |
+INTERNAL void strip_bom_test(unsigned char *source, int *input_length) { | |
+ strip_bom(source, input_length); | |
+} | |
+#endif | |
+ | |
+/* Helper to convert base octal, decimal, hexadecimal escape sequence */ | |
+static int esc_base(struct zint_symbol *symbol, unsigned char *input_string, int length, int in_posn, int base) { | |
+ int c1, c2, c3; | |
+ int min_len = base == 'x' ? 2 : 3; | |
+ | |
+ if (in_posn + min_len > length) { | |
+ sprintf(symbol->errtxt, "232: Incomplete '\\%c' escape sequence in input data", base); | |
+ return -1; | |
+ } | |
+ c1 = ctoi(input_string[in_posn]); | |
+ c2 = ctoi(input_string[in_posn + 1]); | |
+ if (base == 'd') { | |
+ c3 = ctoi(input_string[in_posn + 2]); | |
+ if ((c1 >= 0 && c1 <= 9) && (c2 >= 0 && c2 <= 9) && (c3 >= 0 && c3 <= 9)) { | |
+ return c1 * 100 + c2 * 10 + c3; | |
+ } | |
+ } else if (base == 'o') { | |
+ c3 = ctoi(input_string[in_posn + 2]); | |
+ if ((c1 >= 0 && c1 <= 7) && (c2 >= 0 && c2 <= 7) && (c3 >= 0 && c3 <= 7)) { | |
+ return (c1 << 6) | (c2 << 3) | c3; | |
+ } | |
+ } else { | |
+ if ((c1 >= 0) && (c2 >= 0)) { | |
+ return (c1 << 4) | c2; | |
+ } | |
+ } | |
+ | |
+ sprintf(symbol->errtxt, "233: Invalid character for '\\%c' escape sequence in input data (%s only)", | |
+ base, base == 'd' ? "decimal" : base == 'o' ? "octal" : "hexadecimal" ); | |
+ return -1; | |
+} | |
+ | |
+/* Helper to parse escape sequences */ | |
+static int escape_char_process(struct zint_symbol *symbol, unsigned char *input_string, int *p_length) { | |
+ const int length = *p_length; | |
+ int in_posn, out_posn; | |
+ int ch; | |
+ int val; | |
+ int i; | |
+ unsigned long unicode; | |
+ unsigned char *escaped_string = (unsigned char *) z_alloca(length + 1); | |
+ | |
+ in_posn = 0; | |
+ out_posn = 0; | |
+ | |
+ do { | |
+ if (input_string[in_posn] == '\\') { | |
+ if (in_posn + 1 >= length) { | |
+ strcpy(symbol->errtxt, "236: Incomplete escape character in input data"); | |
+ return ZINT_ERROR_INVALID_DATA; | |
+ } | |
+ ch = input_string[in_posn + 1]; | |
+ /* NOTE: if add escape character, must also update regex in "frontend_qt/datawindow.php" */ | |
+ switch (ch) { | |
+ case '0': escaped_string[out_posn] = 0x00; /* Null */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'E': escaped_string[out_posn] = 0x04; /* End of Transmission */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'a': escaped_string[out_posn] = 0x07; /* Bell */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'b': escaped_string[out_posn] = 0x08; /* Backspace */ | |
+ in_posn += 2; | |
+ break; | |
+ case 't': escaped_string[out_posn] = 0x09; /* Horizontal tab */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'n': escaped_string[out_posn] = 0x0a; /* Line feed */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'v': escaped_string[out_posn] = 0x0b; /* Vertical tab */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'f': escaped_string[out_posn] = 0x0c; /* Form feed */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'r': escaped_string[out_posn] = 0x0d; /* Carriage return */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'e': escaped_string[out_posn] = 0x1b; /* Escape */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'G': escaped_string[out_posn] = 0x1d; /* Group Separator */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'R': escaped_string[out_posn] = 0x1e; /* Record Separator */ | |
+ in_posn += 2; | |
+ break; | |
+ case 'd': | |
+ case 'o': /* Undocumented (as not very useful for most people) */ | |
+ case 'x': | |
+ if ((val = esc_base(symbol, input_string, length, in_posn + 2, ch)) == -1) { | |
+ return ZINT_ERROR_INVALID_DATA; | |
+ } | |
+ escaped_string[out_posn] = val; | |
+ in_posn += 4 + (ch != 'x'); | |
+ break; | |
+ case '\\': escaped_string[out_posn] = '\\'; | |
+ in_posn += 2; | |
+ break; | |
+ case 'u': | |
+ case 'U': | |
+ if (in_posn + 6 > length || (ch == 'U' && in_posn + 8 > length)) { | |
+ sprintf(symbol->errtxt, "209: Incomplete '\\%c' escape sequence in input data", ch); | |
+ return ZINT_ERROR_INVALID_DATA; | |
+ } | |
+ unicode = 0; | |
+ for (i = 0; i < 6; i++) { | |
+ if ((val = ctoi(input_string[in_posn + i + 2])) == -1) { | |
+ sprintf(symbol->errtxt, | |
+ "211: Invalid character for '\\%c' escape sequence in input data (hexadecimal only)", | |
+ ch); | |
+ return ZINT_ERROR_INVALID_DATA; | |
+ } | |
+ unicode = (unicode << 4) | val; | |
+ if (i == 3 && ch == 'u') { | |
+ break; | |
+ } | |
+ } | |
+ /* Exclude reversed BOM and surrogates and out-of-range */ | |
+ if (unicode == 0xfffe || (unicode >= 0xd800 && unicode < 0xe000) || unicode > 0x10ffff) { | |
+ sprintf(symbol->errtxt, "246: Invalid value for '\\%c' escape sequence in input data", ch); | |
+ return ZINT_ERROR_INVALID_DATA; | |
+ } | |
+ if (unicode >= 0x800) { | |
+ if (unicode >= 0x10000) { | |
+ escaped_string[out_posn] = 0xf0 + (unsigned char) (unicode >> 16); | |
+ out_posn++; | |
+ } | |
+ escaped_string[out_posn] = 0xe0 + ((unicode & 0xf000) >> 12); | |
+ out_posn++; | |
+ escaped_string[out_posn] = 0x80 + ((unicode & 0x0fc0) >> 6); | |
+ out_posn++; | |
+ escaped_string[out_posn] = 0x80 + (unicode & 0x003f); | |
+ } else if (unicode >= 0x80) { | |
+ escaped_string[out_posn] = 0xc0 + ((unicode & 0x07c0) >> 6); | |
+ out_posn++; | |
+ escaped_string[out_posn] = 0x80 + (unicode & 0x003f); | |
+ } else { | |
+ escaped_string[out_posn] = unicode & 0x7f; | |
+ } | |
+ in_posn += 6 + (ch == 'U') * 2; | |
+ break; | |
+ default: sprintf(symbol->errtxt, "234: Unrecognised escape character '\\%c' in input data", ch); | |
+ return ZINT_ERROR_INVALID_DATA; | |
+ break; | |
+ } | |
+ } else { | |
+ escaped_string[out_posn] = input_string[in_posn]; | |
+ in_posn++; | |
+ } | |
+ out_posn++; | |
+ } while (in_posn < length); | |
+ | |
+ memcpy(input_string, escaped_string, out_posn); | |
+ input_string[out_posn] = '\0'; | |
+ *p_length = out_posn; | |
+ | |
+ return 0; | |
+} | |
+ | |
+#ifdef ZINT_TEST /* Wrapper for direct testing */ | |
+INTERNAL int escape_char_process_test(struct zint_symbol *symbol, unsigned char *input_string, int *length) { | |
+ return escape_char_process(symbol, input_string, length); | |
+} | |
+#endif | |
+ | |
+/* Encode a barcode. If `length` is 0, `source` must be NUL-terminated. */ | |
+int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int length) { | |
+ struct zint_seg segs[1]; | |
+ | |
+ if (!symbol) return ZINT_ERROR_INVALID_DATA; | |
+ | |
+ segs[0].eci = symbol->eci; | |
+ segs[0].source = (unsigned char *) source; | |
+ segs[0].length = length; | |
+ | |
+ return ZBarcode_Encode_Segs(symbol, segs, 1); | |
+} | |
+ | |
+/* Encode a barcode with multiple ECI segments. */ | |
+int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[], const int seg_count) { | |
+ int error_number, warn_number = 0; | |
+ int total_len = 0; | |
+ int have_zero_eci = 0; | |
+ int i; | |
+ unsigned char *local_source; | |
+ struct zint_seg *local_segs; | |
+ unsigned char *local_sources; | |
+ local_segs = (struct zint_seg *) z_alloca(sizeof(struct zint_seg) * (seg_count > 0 ? seg_count : 1)); | |
+ | |
+ if (!symbol) return ZINT_ERROR_INVALID_DATA; | |
+ | |
+ if (segs == NULL) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "200: Input segments NULL"); | |
+ } | |
+ /* `seg_count` zero dealt with via `total_len` zero below */ | |
+ if (seg_count > ZINT_MAX_SEG_COUNT) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "771: Too many input segments (max 256)"); | |
+ } | |
+ | |
+ if ((symbol->input_mode & 0x07) > 2) { | |
+ symbol->input_mode = DATA_MODE; /* Reset completely TODO: in future, warn/error */ | |
+ } | |
+ | |
+ /* Check segment lengths */ | |
+ for (i = 0; i < seg_count; i++) { | |
+ local_segs[i] = segs[i]; | |
+ if (local_segs[i].source == NULL) { | |
+ sprintf(symbol->errtxt, "772: Input segment %d source NULL", i); | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, NULL); | |
+ } | |
+ if (local_segs[i].length <= 0) { | |
+ local_segs[i].length = (int) ustrlen(local_segs[i].source); | |
+ } | |
+ if (local_segs[i].length <= 0) { | |
+ if (i == 0) { | |
+ /* Note: should really be referencing the symbology only after the symbology check switch below */ | |
+ if (is_composite(symbol->symbology) && | |
+ ((symbol->input_mode & 0x07) == GS1_MODE || check_force_gs1(symbol->symbology))) { | |
+ strcpy(symbol->errtxt, "779: No composite data in 2D component"); | |
+ } else { | |
+ sprintf(symbol->errtxt, "778: No input data%s", | |
+ supports_eci(symbol->symbology) ? " (segment 0 empty)" : ""); | |
+ } | |
+ } else { | |
+ sprintf(symbol->errtxt, "773: Input segment %d empty", i); | |
+ } | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, NULL); | |
+ } | |
+ if (local_segs[i].length > ZINT_MAX_DATA_LEN) { | |
+ return error_tag(symbol, ZINT_ERROR_TOO_LONG, "777: Input data too long"); | |
+ } | |
+ total_len += local_segs[i].length; | |
+ } | |
+ | |
+ if (total_len == 0) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "205: No input data"); | |
+ } | |
+ | |
+ if (symbol->debug & ZINT_DEBUG_PRINT) { | |
+ printf("ZBarcode_Encode_Segs: symbology: %d, input_mode: 0x%X, ECI: %d, option_1: %d, option_2: %d," | |
+ " option_3: %d, scale: %g\n output_options: 0x%X, fg: %s, bg: %s," | |
+ " seg_count: %d, length[0] %d," " First 10 source[0] \"%.*s\", First 10 primary: \"%.10s\"\n", | |
+ symbol->symbology, symbol->input_mode, symbol->eci, symbol->option_1, symbol->option_2, | |
+ symbol->option_3, symbol->scale, symbol->output_options, symbol->fgcolour, symbol->bgcolour, | |
+ seg_count, local_segs[0].length, local_segs[0].length < 10 ? local_segs[0].length : 10, | |
+ local_segs[0].source, symbol->primary); | |
+ } | |
+ | |
+ if (total_len > ZINT_MAX_DATA_LEN) { | |
+ return error_tag(symbol, ZINT_ERROR_TOO_LONG, "243: Input data too long"); | |
+ } | |
+ | |
+ /* Reconcile symbol ECI and first segment ECI if both set */ | |
+ if (symbol->eci != local_segs[0].eci) { | |
+ if (symbol->eci && local_segs[0].eci) { | |
+ sprintf(symbol->errtxt, "774: Symbol ECI %d must match segment zero ECI %d", symbol->eci, | |
+ local_segs[0].eci); | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, NULL); | |
+ } | |
+ if (symbol->eci) { | |
+ local_segs[0].eci = symbol->eci; | |
+ } else { | |
+ symbol->eci = local_segs[0].eci; | |
+ } | |
+ } | |
+ | |
+ /* Check the symbology field */ | |
+ if (!ZBarcode_ValidID(symbol->symbology)) { | |
+ int orig_symbology = symbol->symbology; /* For self-check */ | |
+ if (symbol->symbology < 1) { | |
+ warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "206: Symbology out of range"); | |
+ if (warn_number >= ZINT_ERROR) { | |
+ return warn_number; | |
+ } | |
+ symbol->symbology = BARCODE_CODE128; | |
+ /* symbol->symbologys 1 to 126 are defined by tbarcode */ | |
+ } else if (symbol->symbology == 5) { | |
+ symbol->symbology = BARCODE_C25STANDARD; | |
+ } else if ((symbol->symbology >= 10) && (symbol->symbology <= 12)) { | |
+ symbol->symbology = BARCODE_EANX; | |
+ } else if (symbol->symbology == 15) { | |
+ symbol->symbology = BARCODE_EANX; | |
+ } else if (symbol->symbology == 17) { | |
+ symbol->symbology = BARCODE_UPCA; | |
+ } else if (symbol->symbology == 19) { | |
+ warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "207: Codabar 18 not supported"); | |
+ if (warn_number >= ZINT_ERROR) { | |
+ return warn_number; | |
+ } | |
+ symbol->symbology = BARCODE_CODABAR; | |
+ } else if (symbol->symbology == 26) { /* UPC-A up to tbarcode 9, ISSN for tbarcode 10+ */ | |
+ symbol->symbology = BARCODE_UPCA; | |
+ } else if (symbol->symbology == 27) { /* UPCD1 up to tbarcode 9, ISSN + 2 digit add-on for tbarcode 10+ */ | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "208: UPCD1 not supported"); | |
+ } else if (symbol->symbology == 33) { | |
+ symbol->symbology = BARCODE_GS1_128; | |
+ } else if (symbol->symbology == 36) { | |
+ symbol->symbology = BARCODE_UPCA; | |
+ } else if (symbol->symbology == 39) { | |
+ symbol->symbology = BARCODE_UPCE; | |
+ } else if ((symbol->symbology >= 41) && (symbol->symbology <= 45)) { | |
+ symbol->symbology = BARCODE_POSTNET; | |
+ } else if (symbol->symbology == 46) { | |
+ symbol->symbology = BARCODE_PLESSEY; | |
+ } else if (symbol->symbology == 48) { | |
+ symbol->symbology = BARCODE_NVE18; | |
+ } else if ((symbol->symbology == 59) || (symbol->symbology == 61)) { | |
+ symbol->symbology = BARCODE_CODE128; | |
+ } else if (symbol->symbology == 62) { | |
+ symbol->symbology = BARCODE_CODE93; | |
+ } else if ((symbol->symbology == 64) || (symbol->symbology == 65)) { | |
+ symbol->symbology = BARCODE_AUSPOST; | |
+ } else if (symbol->symbology == 78) { | |
+ symbol->symbology = BARCODE_DBAR_OMN; | |
+ } else if (symbol->symbology == 83) { | |
+ symbol->symbology = BARCODE_PLANET; | |
+ } else if (symbol->symbology == 88) { | |
+ symbol->symbology = BARCODE_GS1_128; | |
+ } else if (symbol->symbology == 91) { /* BC412 up to tbarcode 9, Code 32 for tbarcode 10+ */ | |
+ warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "212: Symbology out of range"); | |
+ if (warn_number >= ZINT_ERROR) { | |
+ return warn_number; | |
+ } | |
+ symbol->symbology = BARCODE_CODE128; | |
+ } else if ((symbol->symbology >= 94) && (symbol->symbology <= 95)) { | |
+ warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "213: Symbology out of range"); | |
+ if (warn_number >= ZINT_ERROR) { | |
+ return warn_number; | |
+ } | |
+ symbol->symbology = BARCODE_CODE128; | |
+ } else if (symbol->symbology == 100) { | |
+ symbol->symbology = BARCODE_HIBC_128; | |
+ } else if (symbol->symbology == 101) { | |
+ symbol->symbology = BARCODE_HIBC_39; | |
+ } else if (symbol->symbology == 103) { | |
+ symbol->symbology = BARCODE_HIBC_DM; | |
+ } else if (symbol->symbology == 105) { | |
+ symbol->symbology = BARCODE_HIBC_QR; | |
+ } else if (symbol->symbology == 107) { | |
+ symbol->symbology = BARCODE_HIBC_PDF; | |
+ } else if (symbol->symbology == 109) { | |
+ symbol->symbology = BARCODE_HIBC_MICPDF; | |
+ } else if (symbol->symbology == 111) { | |
+ symbol->symbology = BARCODE_HIBC_BLOCKF; | |
+ } else if ((symbol->symbology == 113) || (symbol->symbology == 114)) { | |
+ warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "214: Symbology out of range"); | |
+ if (warn_number >= ZINT_ERROR) { | |
+ return warn_number; | |
+ } | |
+ symbol->symbology = BARCODE_CODE128; | |
+ } else if ((symbol->symbology >= 117) && (symbol->symbology <= 127)) { | |
+ if (symbol->symbology != 121) { /* BARCODE_MAILMARK */ | |
+ warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "215: Symbology out of range"); | |
+ if (warn_number >= ZINT_ERROR) { | |
+ return warn_number; | |
+ } | |
+ symbol->symbology = BARCODE_CODE128; | |
+ } | |
+ /* Everything from 128 up is Zint-specific */ | |
+ } else if (symbol->symbology > BARCODE_LAST) { | |
+ warn_number = error_tag(symbol, ZINT_WARN_INVALID_OPTION, "216: Symbology out of range"); | |
+ if (warn_number >= ZINT_ERROR) { | |
+ return warn_number; | |
+ } | |
+ symbol->symbology = BARCODE_CODE128; | |
+ } | |
+ if (symbol->symbology == orig_symbology) { /* Should never happen */ | |
+ return error_tag(symbol, ZINT_ERROR_ENCODING_PROBLEM, "000: Internal error"); /* Not reached */ | |
+ } | |
+ } | |
+ | |
+ if (seg_count > 1 && !supports_eci(symbol->symbology)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "775: Symbology does not support multiple segments"); | |
+ } | |
+ | |
+ /* Check ECI(s) */ | |
+ for (i = 0; i < seg_count; i++) { | |
+ if (local_segs[i].eci) { | |
+ if (!supports_eci(symbol->symbology)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "217: Symbology does not support ECI switching"); | |
+ } | |
+ if (local_segs[i].eci < 0 || local_segs[i].eci == 1 || local_segs[i].eci == 2 || local_segs[i].eci == 14 | |
+ || local_segs[i].eci == 19 || local_segs[i].eci > 999999) { | |
+ sprintf(symbol->errtxt, "218: Invalid ECI code %d", local_segs[i].eci); | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, NULL); | |
+ } | |
+ } else { | |
+ have_zero_eci = 1; | |
+ } | |
+ } | |
+ | |
+ /* Check other symbol fields */ | |
+ if ((symbol->scale < 0.01f) || (symbol->scale > 100.0f)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "227: Scale out of range (0.01 to 100)"); | |
+ } | |
+ if ((symbol->dot_size < 0.01f) || (symbol->dot_size > 20.0f)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "221: Dot size out of range (0.01 to 20)"); | |
+ } | |
+ | |
+ if ((symbol->height < 0.0f) || (symbol->height > 2000.0f)) { /* Allow for 44 row CODABLOCKF at 45X each */ | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "765: Height out of range (0 to 2000)"); | |
+ } | |
+ if ((symbol->guard_descent < 0.0f) || (symbol->guard_descent > 50.0f)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "769: Guard bar descent out of range (0 to 50)"); | |
+ } | |
+ if ((symbol->whitespace_width < 0) || (symbol->whitespace_width > 100)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "766: Whitespace width out of range (0 to 100)"); | |
+ } | |
+ if ((symbol->whitespace_height < 0) || (symbol->whitespace_height > 100)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "767: Whitespace height out of range (0 to 100)"); | |
+ } | |
+ if ((symbol->border_width < 0) || (symbol->border_width > 100)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "768: Border width out of range (0 to 100)"); | |
+ } | |
+ | |
+ if (symbol->rows >= 200) { /* Check for stacking too many symbols */ | |
+ return error_tag(symbol, ZINT_ERROR_TOO_LONG, "770: Too many stacked symbols"); | |
+ } | |
+ | |
+ if ((symbol->input_mode & 0x07) == GS1_MODE && !gs1_compliant(symbol->symbology)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "220: Selected symbology does not support GS1 mode"); | |
+ } | |
+ if (seg_count > 1) { | |
+ /* Note: GS1_MODE not currently supported when using multiple segments */ | |
+ if ((symbol->input_mode & 0x07) == GS1_MODE) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "776: GS1 mode not supported for multiple segments"); | |
+ } | |
+ } | |
+ | |
+ if ((symbol->input_mode & 0x07) == UNICODE_MODE) { | |
+ for (i = 0; i < seg_count; i++) { | |
+ if (!is_valid_utf8(local_segs[i].source, local_segs[i].length)) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "245: Invalid UTF-8 in input data"); | |
+ } | |
+ } | |
+ } | |
+ | |
+ local_sources = (unsigned char *) z_alloca(total_len + seg_count); | |
+ | |
+ for (i = 0, local_source = local_sources; i < seg_count; i++) { | |
+ local_segs[i].source = local_source; | |
+ memcpy(local_segs[i].source, segs[i].source, local_segs[i].length); | |
+ local_segs[i].source[local_segs[i].length] = '\0'; | |
+ local_source += local_segs[i].length + 1; | |
+ } | |
+ | |
+ /* Start acting on input mode */ | |
+ if (symbol->input_mode & ESCAPE_MODE) { | |
+ for (i = 0; i < seg_count; i++) { | |
+ error_number = escape_char_process(symbol, local_segs[i].source, &local_segs[i].length); | |
+ if (error_number != 0) { /* Only returns errors, not warnings */ | |
+ return error_tag(symbol, error_number, NULL); | |
+ } | |
+ } | |
+ if (symbol->primary[0]) { | |
+ int primary_len = (int) strlen(symbol->primary); | |
+ error_number = escape_char_process(symbol, (unsigned char *) symbol->primary, &primary_len); | |
+ if (error_number != 0) { /* Only returns errors, not warnings */ | |
+ return error_tag(symbol, error_number, NULL); | |
+ } | |
+ } | |
+ } | |
+ | |
+ if ((symbol->input_mode & 0x07) == UNICODE_MODE) { | |
+ /* Only strip BOM on first segment */ | |
+ strip_bom(local_segs[0].source, &local_segs[0].length); | |
+ } | |
+ | |
+ if (((symbol->input_mode & 0x07) == GS1_MODE) || (check_force_gs1(symbol->symbology))) { | |
+ if (gs1_compliant(symbol->symbology)) { | |
+ /* Reduce input for composite and non-forced symbologies, others (EAN128 and RSS_EXP based) will | |
+ handle it themselves */ | |
+ if (is_composite(symbol->symbology) || !check_force_gs1(symbol->symbology)) { | |
+ unsigned char *reduced = (unsigned char *) z_alloca(local_segs[0].length + 1); | |
+ error_number = gs1_verify(symbol, local_segs[0].source, local_segs[0].length, reduced); | |
+ if (error_number) { | |
+ static const char in_2d_comp[] = " in 2D component"; | |
+ if (is_composite(symbol->symbology) | |
+ && strlen(symbol->errtxt) + strlen(in_2d_comp) < sizeof(symbol->errtxt)) { | |
+ strcat(symbol->errtxt, in_2d_comp); | |
+ } | |
+ error_number = error_tag(symbol, error_number, NULL); | |
+ if (error_number >= ZINT_ERROR) { | |
+ return error_number; | |
+ } | |
+ warn_number = error_number; /* Override any previous warning (errtxt has been overwritten) */ | |
+ } | |
+ ustrcpy(local_segs[0].source, reduced); /* Cannot contain NUL char */ | |
+ local_segs[0].length = (int) ustrlen(reduced); | |
+ } | |
+ } else { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "220: Selected symbology does not support GS1 mode"); | |
+ } | |
+ } | |
+ | |
+ error_number = extended_or_reduced_charset(symbol, local_segs, seg_count); | |
+ | |
+ if ((error_number == ZINT_ERROR_INVALID_DATA) && have_zero_eci && supports_eci(symbol->symbology) | |
+ && (symbol->input_mode & 0x07) == UNICODE_MODE) { | |
+ /* Try another ECI mode */ | |
+ const int first_eci_set = get_best_eci_segs(symbol, local_segs, seg_count); | |
+ if (first_eci_set != 0) { | |
+ error_number = extended_or_reduced_charset(symbol, local_segs, seg_count); | |
+ /* Inclusion of ECI more noteworthy than other warnings, so overwrite (if any) */ | |
+ if (error_number < ZINT_ERROR) { | |
+ error_number = ZINT_WARN_USES_ECI; | |
+ if (!(symbol->debug & ZINT_DEBUG_TEST)) { | |
+ sprintf(symbol->errtxt, "222: Encoded data includes ECI %d", first_eci_set); | |
+ } | |
+ if (symbol->debug & ZINT_DEBUG_PRINT) printf("Added ECI %d\n", first_eci_set); | |
+ } | |
+ } | |
+ } | |
+ | |
+ if (error_number == 0) { | |
+ error_number = warn_number; /* Already tagged */ | |
+ } else { | |
+ error_number = error_tag(symbol, error_number, NULL); | |
+ } | |
+ | |
+ if (error_number < ZINT_ERROR) { | |
+ if (symbol->height < 0.5f) { /* Absolute minimum */ | |
+ (void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/); | |
+ } | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+/* Helper for output routines to check `rotate_angle` and dottiness */ | |
+static int check_output_args(struct zint_symbol *symbol, int rotate_angle) { | |
+ | |
+ if (!symbol) return ZINT_ERROR_INVALID_DATA; | |
+ | |
+ switch (rotate_angle) { | |
+ case 0: | |
+ case 90: | |
+ case 180: | |
+ case 270: | |
+ break; | |
+ default: | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "223: Invalid rotation angle"); | |
+ break; | |
+ } | |
+ | |
+ if ((symbol->output_options & BARCODE_DOTTY_MODE) && !(is_dotty(symbol->symbology))) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "224: Selected symbology cannot be rendered as dots"); | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+/* Output a previously encoded symbol to file `symbol->outfile` */ | |
+int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) { | |
+ int error_number; | |
+ int len; | |
+ | |
+ if ((error_number = check_output_args(symbol, rotate_angle))) { /* >= ZINT_ERROR only */ | |
+ return error_number; /* Already tagged */ | |
+ } | |
+ | |
+ len = (int) strlen(symbol->outfile); | |
+ if (len > 3) { | |
+ char output[4]; | |
+ output[0] = symbol->outfile[len - 3]; | |
+ output[1] = symbol->outfile[len - 2]; | |
+ output[2] = symbol->outfile[len - 1]; | |
+ output[3] = '\0'; | |
+ to_upper((unsigned char *) output, 3); | |
+ | |
+ if (!(strcmp(output, "PNG"))) { | |
+ error_number = plot_raster(symbol, rotate_angle, OUT_PNG_FILE); | |
+ | |
+ } else if (!(strcmp(output, "BMP"))) { | |
+ error_number = plot_raster(symbol, rotate_angle, OUT_BMP_FILE); | |
+ | |
+ } else if (!(strcmp(output, "PCX"))) { | |
+ error_number = plot_raster(symbol, rotate_angle, OUT_PCX_FILE); | |
+ | |
+ } else if (!(strcmp(output, "GIF"))) { | |
+ error_number = plot_raster(symbol, rotate_angle, OUT_GIF_FILE); | |
+ | |
+ } else if (!(strcmp(output, "TIF"))) { | |
+ error_number = plot_raster(symbol, rotate_angle, OUT_TIF_FILE); | |
+ | |
+ } else if (!(strcmp(output, "TXT"))) { | |
+ error_number = dump_plot(symbol); | |
+ | |
+ } else if (!(strcmp(output, "EPS"))) { | |
+ error_number = plot_vector(symbol, rotate_angle, OUT_EPS_FILE); | |
+ | |
+ } else if (!(strcmp(output, "SVG"))) { | |
+ error_number = plot_vector(symbol, rotate_angle, OUT_SVG_FILE); | |
+ | |
+ } else if (!(strcmp(output, "EMF"))) { | |
+ error_number = plot_vector(symbol, rotate_angle, OUT_EMF_FILE); | |
+ | |
+ } else { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "225: Unknown output format"); | |
+ } | |
+ } else { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_OPTION, "226: Unknown output format"); | |
+ } | |
+ | |
+ return error_tag(symbol, error_number, NULL); | |
+} | |
+ | |
+/* Output a previously encoded symbol to memory as raster (`symbol->bitmap`) */ | |
+int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle) { | |
+ int error_number; | |
+ | |
+ if ((error_number = check_output_args(symbol, rotate_angle))) { /* >= ZINT_ERROR only */ | |
+ return error_number; /* Already tagged */ | |
+ } | |
+ | |
+ error_number = plot_raster(symbol, rotate_angle, OUT_BUFFER); | |
+ return error_tag(symbol, error_number, NULL); | |
+} | |
+ | |
+/* Output a previously encoded symbol to memory as vector (`symbol->vector`) */ | |
+int ZBarcode_Buffer_Vector(struct zint_symbol *symbol, int rotate_angle) { | |
+ int error_number; | |
+ | |
+ if ((error_number = check_output_args(symbol, rotate_angle))) { /* >= ZINT_ERROR only */ | |
+ return error_number; /* Already tagged */ | |
+ } | |
+ | |
+ error_number = plot_vector(symbol, rotate_angle, OUT_BUFFER); | |
+ return error_tag(symbol, error_number, NULL); | |
+} | |
+ | |
+/* Encode and output a symbol to file `symbol->outfile` */ | |
+int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, const unsigned char *source, int length, int rotate_angle) { | |
+ struct zint_seg segs[1]; | |
+ | |
+ if (!symbol) return ZINT_ERROR_INVALID_DATA; | |
+ | |
+ segs[0].eci = symbol->eci; | |
+ segs[0].source = (unsigned char *) source; | |
+ segs[0].length = length; | |
+ | |
+ return ZBarcode_Encode_Segs_and_Print(symbol, segs, 1, rotate_angle); | |
+} | |
+ | |
+/* Encode a symbol with multiple ECI segments and output to file `symbol->outfile` */ | |
+int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol, const struct zint_seg segs[], const int seg_count, | |
+ int rotate_angle) { | |
+ int error_number; | |
+ int first_err; | |
+ | |
+ error_number = ZBarcode_Encode_Segs(symbol, segs, seg_count); | |
+ if (error_number >= ZINT_ERROR) { | |
+ return error_number; | |
+ } | |
+ | |
+ first_err = error_number; | |
+ error_number = ZBarcode_Print(symbol, rotate_angle); | |
+ if (error_number == 0) { | |
+ error_number = first_err; | |
+ } | |
+ return error_number; | |
+} | |
+ | |
+/* Encode and output a symbol to memory as raster (`symbol->bitmap`) */ | |
+int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, const unsigned char *source, int length, | |
+ int rotate_angle) { | |
+ struct zint_seg segs[1]; | |
+ | |
+ if (!symbol) return ZINT_ERROR_INVALID_DATA; | |
+ | |
+ segs[0].eci = symbol->eci; | |
+ segs[0].source = (unsigned char *) source; | |
+ segs[0].length = length; | |
+ | |
+ return ZBarcode_Encode_Segs_and_Buffer(symbol, segs, 1, rotate_angle); | |
+} | |
+ | |
+/* Encode a symbol with multiple ECI segments and output to memory as raster (`symbol->bitmap`) */ | |
+int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol, const struct zint_seg segs[], | |
+ const int seg_count, int rotate_angle) { | |
+ int error_number; | |
+ int first_err; | |
+ | |
+ error_number = ZBarcode_Encode_Segs(symbol, segs, seg_count); | |
+ if (error_number >= ZINT_ERROR) { | |
+ return error_number; | |
+ } | |
+ | |
+ first_err = error_number; | |
+ error_number = ZBarcode_Buffer(symbol, rotate_angle); | |
+ if (error_number == 0) { | |
+ error_number = first_err; | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+/* Encode and output a symbol to memory as vector (`symbol->vector`) */ | |
+int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol, const unsigned char *source, int length, | |
+ int rotate_angle) { | |
+ struct zint_seg segs[1]; | |
+ | |
+ if (!symbol) return ZINT_ERROR_INVALID_DATA; | |
+ | |
+ segs[0].eci = symbol->eci; | |
+ segs[0].source = (unsigned char *) source; | |
+ segs[0].length = length; | |
+ | |
+ return ZBarcode_Encode_Segs_and_Buffer_Vector(symbol, segs, 1, rotate_angle); | |
+} | |
+ | |
+/* Encode a symbol with multiple ECI segments and output to memory as vector (`symbol->vector`) */ | |
+int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol, const struct zint_seg segs[], | |
+ const int seg_count, int rotate_angle) { | |
+ int error_number; | |
+ int first_err; | |
+ | |
+ error_number = ZBarcode_Encode_Segs(symbol, segs, seg_count); | |
+ if (error_number >= ZINT_ERROR) { | |
+ return error_number; | |
+ } | |
+ | |
+ first_err = error_number; | |
+ error_number = ZBarcode_Buffer_Vector(symbol, rotate_angle); | |
+ if (error_number == 0) { | |
+ error_number = first_err; | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+/* Encode a barcode using input data from file `filename` */ | |
+int ZBarcode_Encode_File(struct zint_symbol *symbol, const char *filename) { | |
+ FILE *file; | |
+ int file_opened = 0; | |
+ unsigned char *buffer; | |
+ long fileLen; | |
+ size_t n; | |
+ size_t nRead = 0; | |
+ int ret; | |
+ | |
+ if (!symbol) return ZINT_ERROR_INVALID_DATA; | |
+ | |
+ if (!filename) { | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "239: Filename NULL"); | |
+ } | |
+ | |
+ if (!strcmp(filename, "-")) { | |
+ file = stdin; | |
+ fileLen = ZINT_MAX_DATA_LEN; | |
+ } else { | |
+ file = fopen(filename, "rb"); | |
+ if (!file) { | |
+ sprintf(symbol->errtxt, "229: Unable to read input file (%d: %.30s)", errno, strerror(errno)); | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, NULL); | |
+ } | |
+ file_opened = 1; | |
+ | |
+ /* Get file length */ | |
+ fseek(file, 0, SEEK_END); | |
+ fileLen = ftell(file); | |
+ fseek(file, 0, SEEK_SET); | |
+ | |
+ /* On many Linux distros ftell() returns LONG_MAX not -1 on error */ | |
+ if (fileLen <= 0 || fileLen == LONG_MAX) { | |
+ fclose(file); | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "235: Input file empty or unseekable"); | |
+ } | |
+ if (fileLen > ZINT_MAX_DATA_LEN) { | |
+ fclose(file); | |
+ return error_tag(symbol, ZINT_ERROR_TOO_LONG, "230: Input file too long"); | |
+ } | |
+ } | |
+ | |
+ /* Allocate memory */ | |
+ buffer = (unsigned char *) malloc(fileLen); | |
+ if (!buffer) { | |
+ if (file_opened) { | |
+ fclose(file); | |
+ } | |
+ return error_tag(symbol, ZINT_ERROR_MEMORY, "231: Insufficient memory for file read buffer"); | |
+ } | |
+ | |
+ /* Read file contents into buffer */ | |
+ | |
+ do { | |
+ n = fread(buffer + nRead, 1, fileLen - nRead, file); | |
+ if (ferror(file)) { | |
+ sprintf(symbol->errtxt, "241: Input file read error (%d: %.30s)", errno, strerror(errno)); | |
+ if (file_opened) { | |
+ fclose(file); | |
+ } | |
+ free(buffer); | |
+ return error_tag(symbol, ZINT_ERROR_INVALID_DATA, NULL); | |
+ } | |
+ nRead += n; | |
+ } while (!feof(file) && (0 < n) && ((long) nRead < fileLen)); | |
+ | |
+ if (file_opened) { | |
+ fclose(file); | |
+ } | |
+ ret = ZBarcode_Encode(symbol, buffer, (int) nRead); | |
+ free(buffer); | |
+ return ret; | |
+} | |
+ | |
+/* Encode a symbol using input data from file `filename` and output to file `symbol->outfile` */ | |
+int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, const char *filename, int rotate_angle) { | |
+ int error_number; | |
+ int first_err; | |
+ | |
+ error_number = ZBarcode_Encode_File(symbol, filename); | |
+ if (error_number >= ZINT_ERROR) { | |
+ return error_number; | |
+ } | |
+ | |
+ first_err = error_number; | |
+ error_number = ZBarcode_Print(symbol, rotate_angle); | |
+ if (error_number == 0) { | |
+ error_number = first_err; | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+/* Encode a symbol using input data from file `filename` and output to memory as raster (`symbol->bitmap`) */ | |
+int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char const *filename, int rotate_angle) { | |
+ int error_number; | |
+ int first_err; | |
+ | |
+ error_number = ZBarcode_Encode_File(symbol, filename); | |
+ if (error_number >= ZINT_ERROR) { | |
+ return error_number; | |
+ } | |
+ | |
+ first_err = error_number; | |
+ error_number = ZBarcode_Buffer(symbol, rotate_angle); | |
+ if (error_number == 0) { | |
+ error_number = first_err; | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+/* Encode a symbol using input data from file `filename` and output to memory as vector (`symbol->vector`) */ | |
+int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol, const char *filename, int rotate_angle) { | |
+ int error_number; | |
+ int first_err; | |
+ | |
+ error_number = ZBarcode_Encode_File(symbol, filename); | |
+ if (error_number >= ZINT_ERROR) { | |
+ return error_number; | |
+ } | |
+ | |
+ first_err = error_number; | |
+ error_number = ZBarcode_Buffer_Vector(symbol, rotate_angle); | |
+ if (error_number == 0) { | |
+ error_number = first_err; | |
+ } | |
+ | |
+ return error_number; | |
+} | |
+ | |
+/* Checks whether a symbology is supported */ | |
+int ZBarcode_ValidID(int symbol_id) { | |
+ | |
+ if (symbol_id <= 0 || symbol_id > BARCODE_LAST) { | |
+ return 0; | |
+ } | |
+ | |
+ return barcode_funcs[symbol_id] != NULL; | |
+} | |
+ | |
+/* Copy BARCODE_XXX name of `symbol_id` into `name` buffer, NUL-terminated. | |
+ Returns 0 if valid, non-zero (1 or -1) if not valid */ | |
+int ZBarcode_BarcodeName(int symbol_id, char name[32]) { | |
+ struct item { | |
+ const char *name; | |
+ int define; | |
+ int val; | |
+ }; | |
+ static const struct item data[] = { | |
+ { "", -1, 0 }, | |
+ { "BARCODE_CODE11", BARCODE_CODE11, 1 }, | |
+ { "BARCODE_C25STANDARD", BARCODE_C25STANDARD, 2 }, | |
+ { "BARCODE_C25INTER", BARCODE_C25INTER, 3 }, | |
+ { "BARCODE_C25IATA", BARCODE_C25IATA, 4 }, | |
+ { "", -1, 5 }, | |
+ { "BARCODE_C25LOGIC", BARCODE_C25LOGIC, 6 }, | |
+ { "BARCODE_C25IND", BARCODE_C25IND, 7 }, | |
+ { "BARCODE_CODE39", BARCODE_CODE39, 8 }, | |
+ { "BARCODE_EXCODE39", BARCODE_EXCODE39, 9 }, | |
+ { "", -1, 10 }, | |
+ { "", -1, 11 }, | |
+ { "", -1, 12 }, | |
+ { "BARCODE_EANX", BARCODE_EANX, 13 }, | |
+ { "BARCODE_EANX_CHK", BARCODE_EANX_CHK, 14 }, | |
+ { "", -1, 15 }, | |
+ { "BARCODE_GS1_128", BARCODE_GS1_128, 16 }, | |
+ { "", -1, 17 }, | |
+ { "BARCODE_CODABAR", BARCODE_CODABAR, 18 }, | |
+ { "", -1, 19 }, | |
+ { "BARCODE_CODE128", BARCODE_CODE128, 20 }, | |
+ { "BARCODE_DPLEIT", BARCODE_DPLEIT, 21 }, | |
+ { "BARCODE_DPIDENT", BARCODE_DPIDENT, 22 }, | |
+ { "BARCODE_CODE16K", BARCODE_CODE16K, 23 }, | |
+ { "BARCODE_CODE49", BARCODE_CODE49, 24 }, | |
+ { "BARCODE_CODE93", BARCODE_CODE93, 25 }, | |
+ { "", -1, 26 }, | |
+ { "", -1, 27 }, | |
+ { "BARCODE_FLAT", BARCODE_FLAT, 28 }, | |
+ { "BARCODE_DBAR_OMN", BARCODE_DBAR_OMN, 29 }, | |
+ { "BARCODE_DBAR_LTD", BARCODE_DBAR_LTD, 30 }, | |
+ { "BARCODE_DBAR_EXP", BARCODE_DBAR_EXP, 31 }, | |
+ { "BARCODE_TELEPEN", BARCODE_TELEPEN, 32 }, | |
+ { "", -1, 33 }, | |
+ { "BARCODE_UPCA", BARCODE_UPCA, 34 }, | |
+ { "BARCODE_UPCA_CHK", BARCODE_UPCA_CHK, 35 }, | |
+ { "", -1, 36 }, | |
+ { "BARCODE_UPCE", BARCODE_UPCE, 37 }, | |
+ { "BARCODE_UPCE_CHK", BARCODE_UPCE_CHK, 38 }, | |
+ { "", -1, 39 }, | |
+ { "BARCODE_POSTNET", BARCODE_POSTNET, 40 }, | |
+ { "", -1, 41 }, | |
+ { "", -1, 42 }, | |
+ { "", -1, 43 }, | |
+ { "", -1, 44 }, | |
+ { "", -1, 45 }, | |
+ { "", -1, 46 }, | |
+ { "BARCODE_MSI_PLESSEY", BARCODE_MSI_PLESSEY, 47 }, | |
+ { "", -1, 48 }, | |
+ { "BARCODE_FIM", BARCODE_FIM, 49 }, | |
+ { "BARCODE_LOGMARS", BARCODE_LOGMARS, 50 }, | |
+ { "BARCODE_PHARMA", BARCODE_PHARMA, 51 }, | |
+ { "BARCODE_PZN", BARCODE_PZN, 52 }, | |
+ { "BARCODE_PHARMA_TWO", BARCODE_PHARMA_TWO, 53 }, | |
+ { "BARCODE_CEPNET", BARCODE_CEPNET, 54 }, | |
+ { "BARCODE_PDF417", BARCODE_PDF417, 55 }, | |
+ { "BARCODE_PDF417COMP", BARCODE_PDF417COMP, 56 }, | |
+ { "BARCODE_MAXICODE", BARCODE_MAXICODE, 57 }, | |
+ { "BARCODE_QRCODE", BARCODE_QRCODE, 58 }, | |
+ { "", -1, 59 }, | |
+ { "BARCODE_CODE128B", BARCODE_CODE128B, 60 }, | |
+ { "", -1, 61 }, | |
+ { "", -1, 62 }, | |
+ { "BARCODE_AUSPOST", BARCODE_AUSPOST, 63 }, | |
+ { "", -1, 64 }, | |
+ { "", -1, 65 }, | |
+ { "BARCODE_AUSREPLY", BARCODE_AUSREPLY, 66 }, | |
+ { "BARCODE_AUSROUTE", BARCODE_AUSROUTE, 67 }, | |
+ { "BARCODE_AUSREDIRECT", BARCODE_AUSREDIRECT, 68 }, | |
+ { "BARCODE_ISBNX", BARCODE_ISBNX, 69 }, | |
+ { "BARCODE_RM4SCC", BARCODE_RM4SCC, 70 }, | |
+ { "BARCODE_DATAMATRIX", BARCODE_DATAMATRIX, 71 }, | |
+ { "BARCODE_EAN14", BARCODE_EAN14, 72 }, | |
+ { "BARCODE_VIN", BARCODE_VIN, 73 }, | |
+ { "BARCODE_CODABLOCKF", BARCODE_CODABLOCKF, 74 }, | |
+ { "BARCODE_NVE18", BARCODE_NVE18, 75 }, | |
+ { "BARCODE_JAPANPOST", BARCODE_JAPANPOST, 76 }, | |
+ { "BARCODE_KOREAPOST", BARCODE_KOREAPOST, 77 }, | |
+ { "", -1, 78 }, | |
+ { "BARCODE_DBAR_STK", BARCODE_DBAR_STK, 79 }, | |
+ { "BARCODE_DBAR_OMNSTK", BARCODE_DBAR_OMNSTK, 80 }, | |
+ { "BARCODE_DBAR_EXPSTK", BARCODE_DBAR_EXPSTK, 81 }, | |
+ { "BARCODE_PLANET", BARCODE_PLANET, 82 }, | |
+ { "", -1, 83 }, | |
+ { "BARCODE_MICROPDF417", BARCODE_MICROPDF417, 84 }, | |
+ { "BARCODE_USPS_IMAIL", BARCODE_USPS_IMAIL, 85 }, | |
+ { "BARCODE_PLESSEY", BARCODE_PLESSEY, 86 }, | |
+ { "BARCODE_TELEPEN_NUM", BARCODE_TELEPEN_NUM, 87 }, | |
+ { "", -1, 88 }, | |
+ { "BARCODE_ITF14", BARCODE_ITF14, 89 }, | |
+ { "BARCODE_KIX", BARCODE_KIX, 90 }, | |
+ { "", -1, 91 }, | |
+ { "BARCODE_AZTEC", BARCODE_AZTEC, 92 }, | |
+ { "BARCODE_DAFT", BARCODE_DAFT, 93 }, | |
+ { "", -1, 94 }, | |
+ { "", -1, 95 }, | |
+ { "BARCODE_DPD", BARCODE_DPD, 96 }, | |
+ { "BARCODE_MICROQR", BARCODE_MICROQR, 97 }, | |
+ { "BARCODE_HIBC_128", BARCODE_HIBC_128, 98 }, | |
+ { "BARCODE_HIBC_39", BARCODE_HIBC_39, 99 }, | |
+ { "", -1, 100 }, | |
+ { "", -1, 101 }, | |
+ { "BARCODE_HIBC_DM", BARCODE_HIBC_DM, 102 }, | |
+ { "", -1, 103 }, | |
+ { "BARCODE_HIBC_QR", BARCODE_HIBC_QR, 104 }, | |
+ { "", -1, 105 }, | |
+ { "BARCODE_HIBC_PDF", BARCODE_HIBC_PDF, 106 }, | |
+ { "", -1, 107 }, | |
+ { "BARCODE_HIBC_MICPDF", BARCODE_HIBC_MICPDF, 108 }, | |
+ { "", -1, 109 }, | |
+ { "BARCODE_HIBC_BLOCKF", BARCODE_HIBC_BLOCKF, 110 }, | |
+ { "", -1, 111 }, | |
+ { "BARCODE_HIBC_AZTEC", BARCODE_HIBC_AZTEC, 112 }, | |
+ { "", -1, 113 }, | |
+ { "", -1, 114 }, | |
+ { "BARCODE_DOTCODE", BARCODE_DOTCODE, 115 }, | |
+ { "BARCODE_HANXIN", BARCODE_HANXIN, 116 }, | |
+ { "", -1, 117 }, | |
+ { "", -1, 118 }, | |
+ { "", -1, 119 }, | |
+ { "", -1, 120 }, | |
+ { "BARCODE_MAILMARK", BARCODE_MAILMARK, 121 }, | |
+ { "", -1, 122 }, | |
+ { "", -1, 123 }, | |
+ { "", -1, 124 }, | |
+ { "", -1, 125 }, | |
+ { "", -1, 126 }, | |
+ { "", -1, 127 }, | |
+ { "BARCODE_AZRUNE", BARCODE_AZRUNE, 128 }, | |
+ { "BARCODE_CODE32", BARCODE_CODE32, 129 }, | |
+ { "BARCODE_EANX_CC", BARCODE_EANX_CC, 130 }, | |
+ { "BARCODE_GS1_128_CC", BARCODE_GS1_128_CC, 131 }, | |
+ { "BARCODE_DBAR_OMN_CC", BARCODE_DBAR_OMN_CC, 132 }, | |
+ { "BARCODE_DBAR_LTD_CC", BARCODE_DBAR_LTD_CC, 133 }, | |
+ { "BARCODE_DBAR_EXP_CC", BARCODE_DBAR_EXP_CC, 134 }, | |
+ { "BARCODE_UPCA_CC", BARCODE_UPCA_CC, 135 }, | |
+ { "BARCODE_UPCE_CC", BARCODE_UPCE_CC, 136 }, | |
+ { "BARCODE_DBAR_STK_CC", BARCODE_DBAR_STK_CC, 137 }, | |
+ { "BARCODE_DBAR_OMNSTK_CC", BARCODE_DBAR_OMNSTK_CC, 138 }, | |
+ { "BARCODE_DBAR_EXPSTK_CC", BARCODE_DBAR_EXPSTK_CC, 139 }, | |
+ { "BARCODE_CHANNEL", BARCODE_CHANNEL, 140 }, | |
+ { "BARCODE_CODEONE", BARCODE_CODEONE, 141 }, | |
+ { "BARCODE_GRIDMATRIX", BARCODE_GRIDMATRIX, 142 }, | |
+ { "BARCODE_UPNQR", BARCODE_UPNQR, 143 }, | |
+ { "BARCODE_ULTRA", BARCODE_ULTRA, 144 }, | |
+ { "BARCODE_RMQR", BARCODE_RMQR, 145 }, | |
+ { "BARCODE_BC412", BARCODE_BC412, 146 }, | |
+ }; | |
+ | |
+ name[0] = '\0'; | |
+ | |
+ if (!ZBarcode_ValidID(symbol_id)) { | |
+ return 1; | |
+ } | |
+ assert(symbol_id >= 0 && symbol_id < ARRAY_SIZE(data) && data[symbol_id].name[0]); | |
+ | |
+ /* Self-check, shouldn't happen */ | |
+ if (data[symbol_id].val != symbol_id || (data[symbol_id].define != -1 && data[symbol_id].define != symbol_id)) { | |
+ assert(0); /* Not reached */ | |
+ return -1; | |
+ } | |
+ | |
+ strcpy(name, data[symbol_id].name); | |
+ | |
+ return 0; | |
+} | |
+ | |
+/* Return the capability flags for symbology `symbol_id` that match `cap_flag` */ | |
+unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag) { | |
+ unsigned int result = 0; | |
+ | |
+ if (!ZBarcode_ValidID(symbol_id)) { | |
+ return 0; | |
+ } | |
+ | |
+ if ((cap_flag & ZINT_CAP_HRT) && has_hrt(symbol_id)) { | |
+ result |= ZINT_CAP_HRT; | |
+ } | |
+ if ((cap_flag & ZINT_CAP_STACKABLE) && is_stackable(symbol_id)) { | |
+ result |= ZINT_CAP_STACKABLE; | |
+ } | |
+ if ((cap_flag & ZINT_CAP_EXTENDABLE) && is_extendable(symbol_id)) { | |
+ result |= ZINT_CAP_EXTENDABLE; | |
+ } | |
+ if ((cap_flag & ZINT_CAP_COMPOSITE) && is_composite(symbol_id)) { | |
+ result |= ZINT_CAP_COMPOSITE; | |
+ } | |
+ if ((cap_flag & ZINT_CAP_ECI) && supports_eci(symbol_id)) { | |
+ result |= ZINT_CAP_ECI; | |
+ } | |
+ if ((cap_flag & ZINT_CAP_GS1) && gs1_compliant(symbol_id)) { | |
+ result |= ZINT_CAP_GS1; | |
+ } | |
+ if ((cap_flag & ZINT_CAP_DOTTY) && is_dotty(symbol_id)) { | |
+ result |= ZINT_CAP_DOTTY; | |
+ } | |
+ if (cap_flag & ZINT_CAP_QUIET_ZONES) { | |
+ switch (symbol_id) { /* See `out_quiet_zones()` in "output.c" */ | |
+ case BARCODE_CODE16K: | |
+ case BARCODE_CODE49: | |
+ case BARCODE_CODABLOCKF: | |
+ case BARCODE_HIBC_BLOCKF: | |
+ case BARCODE_ITF14: | |
+ case BARCODE_EANX: | |
+ case BARCODE_EANX_CHK: | |
+ case BARCODE_EANX_CC: | |
+ case BARCODE_ISBNX: | |
+ case BARCODE_UPCA: | |
+ case BARCODE_UPCA_CHK: | |
+ case BARCODE_UPCA_CC: | |
+ case BARCODE_UPCE: | |
+ case BARCODE_UPCE_CHK: | |
+ case BARCODE_UPCE_CC: | |
+ result |= ZINT_CAP_QUIET_ZONES; | |
+ break; | |
+ } | |
+ } | |
+ if ((cap_flag & ZINT_CAP_FIXED_RATIO) && is_fixed_ratio(symbol_id)) { | |
+ result |= ZINT_CAP_FIXED_RATIO; | |
+ } | |
+ if (cap_flag & ZINT_CAP_READER_INIT) { | |
+ /* Note does not include HIBC versions */ | |
+ switch (symbol_id) { | |
+ case BARCODE_CODE128: /* Note does not include GS1_128 or NVE18 */ | |
+ case BARCODE_CODE128B: | |
+ case BARCODE_CODE16K: | |
+ case BARCODE_CODABLOCKF: | |
+ case BARCODE_PDF417: | |
+ case BARCODE_PDF417COMP: | |
+ case BARCODE_DATAMATRIX: | |
+ case BARCODE_MICROPDF417: | |
+ case BARCODE_AZTEC: | |
+ case BARCODE_DOTCODE: | |
+ case BARCODE_GRIDMATRIX: | |
+ case BARCODE_ULTRA: | |
+ result |= ZINT_CAP_READER_INIT; | |
+ break; | |
+ } | |
+ } | |
+ if (cap_flag & ZINT_CAP_FULL_MULTIBYTE) { | |
+ switch (symbol_id) { | |
+ case BARCODE_QRCODE: | |
+ case BARCODE_MICROQR: | |
+ /* case BARCODE_HIBC_QR: Note character set restricted to ASCII subset */ | |
+ /* case BARCODE_UPNQR: Note does not use Kanji mode */ | |
+ case BARCODE_RMQR: | |
+ case BARCODE_HANXIN: | |
+ case BARCODE_GRIDMATRIX: | |
+ result |= ZINT_CAP_FULL_MULTIBYTE; | |
+ break; | |
+ } | |
+ } | |
+ if (cap_flag & ZINT_CAP_MASK) { | |
+ switch (symbol_id) { | |
+ case BARCODE_QRCODE: | |
+ case BARCODE_MICROQR: | |
+ case BARCODE_UPNQR: | |
+ case BARCODE_HANXIN: | |
+ case BARCODE_DOTCODE: | |
+ result |= ZINT_CAP_MASK; | |
+ break; | |
+ } | |
+ } | |
+ if (cap_flag & ZINT_CAP_STRUCTAPP) { | |
+ switch (symbol_id) { | |
+ case BARCODE_PDF417: | |
+ case BARCODE_PDF417COMP: | |
+ case BARCODE_MAXICODE: | |
+ case BARCODE_QRCODE: /* Note does not include MICROQR, UPNQR or rMQR */ | |
+ case BARCODE_DATAMATRIX: | |
+ case BARCODE_MICROPDF417: | |
+ case BARCODE_AZTEC: | |
+ case BARCODE_HIBC_DM: | |
+ case BARCODE_HIBC_QR: | |
+ case BARCODE_HIBC_PDF: | |
+ case BARCODE_HIBC_MICPDF: | |
+ case BARCODE_HIBC_AZTEC: | |
+ case BARCODE_DOTCODE: | |
+ case BARCODE_CODEONE: | |
+ case BARCODE_GRIDMATRIX: | |
+ case BARCODE_ULTRA: | |
+ result |= ZINT_CAP_STRUCTAPP; | |
+ break; | |
+ } | |
+ } | |
+ if ((cap_flag & ZINT_CAP_COMPLIANT_HEIGHT) && !is_fixed_ratio(symbol_id)) { | |
+ switch (symbol_id) { | |
+ /* These don't have a compliant height defined */ | |
+ case BARCODE_CODE11: /* TODO: Find doc */ | |
+ case BARCODE_C25STANDARD: /* For C25 only have doc for C25INTER */ | |
+ case BARCODE_C25IATA: | |
+ case BARCODE_C25LOGIC: | |
+ case BARCODE_C25IND: | |
+ case BARCODE_CODE128: /* Left to application */ | |
+ case BARCODE_CODE128B: | |
+ case BARCODE_DPLEIT: /* TODO: Find doc */ | |
+ case BARCODE_DPIDENT: /* TODO: Find doc */ | |
+ case BARCODE_FLAT: /* TODO: Find doc */ | |
+ case BARCODE_MSI_PLESSEY: /* TODO: Find doc */ | |
+ case BARCODE_PDF417: /* Has compliant height but already warns & uses for default */ | |
+ case BARCODE_PDF417COMP: | |
+ case BARCODE_VIN: /* Spec unlikely */ | |
+ case BARCODE_KOREAPOST: /* TODO: Find doc */ | |
+ case BARCODE_MICROPDF417: /* See PDF417 */ | |
+ case BARCODE_PLESSEY: /* TODO: Find doc */ | |
+ case BARCODE_DAFT: /* Generic */ | |
+ case BARCODE_HIBC_128: /* See CODE128 */ | |
+ case BARCODE_HIBC_PDF: /* See PDF417 */ | |
+ case BARCODE_HIBC_MICPDF: /* See PDF417 */ | |
+ break; | |
+ default: | |
+ result |= ZINT_CAP_COMPLIANT_HEIGHT; | |
+ break; | |
+ } | |
+ } | |
+ | |
+ return result; | |
+} | |
+ | |
+/* | |
+ * Rendering support, initially added by Sam Lown. | |
+ * Plot to gLabels - backported from 2.6.7 by brozkeff 2022-11-25 | |
+ */ | |
+int ZBarcode_Render(struct zint_symbol *symbol, const float width, const float height) { | |
+ // Send the request to the render_plot method | |
+ return render_plot(symbol, width, height); | |
+} | |
+ | |
+ | |
+/* Return the version of Zint linked to */ | |
+int ZBarcode_Version(void) { | |
+ if (ZINT_VERSION_BUILD) { | |
+ return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE * 10 | |
+ + ZINT_VERSION_BUILD; | |
+ } | |
+ return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE; | |
+} | |
+ | |
+/* vim: set ts=4 sw=4 et : */ | |
diff --git a/render.c b/render.c | |
new file mode 100755 | |
index 0000000..98184fb | |
--- /dev/null | |
+++ b/render.c | |
@@ -0,0 +1,859 @@ | |
+/* | |
+ * render.c - Generic Rendered Format | |
+ * | |
+ * Initiall written by Sam Lown for use in gLabels. Converts encoded | |
+ * data into a generic internal structure of lines and characters | |
+ * usable in external applications. | |
+ Backported from 2.6.7 to 2.11 by brozkeff 2022-11-25 | |
+ */ | |
+ | |
+/* | |
+ libzint - the open source barcode library | |
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com> | |
+ | |
+ Redistribution and use in source and binary forms, with or without | |
+ modification, are permitted provided that the following conditions | |
+ are met: | |
+ | |
+ 1. Redistributions of source code must retain the above copyright | |
+ notice, this list of conditions and the following disclaimer. | |
+ 2. Redistributions in binary form must reproduce the above copyright | |
+ notice, this list of conditions and the following disclaimer in the | |
+ documentation and/or other materials provided with the distribution. | |
+ 3. Neither the name of the project nor the names of its contributors | |
+ may be used to endorse or promote products derived from this software | |
+ without specific prior written permission. | |
+ | |
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | |
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
+ SUCH DAMAGE. | |
+ */ | |
+ | |
+#include <locale.h> | |
+#include <string.h> | |
+#include <stdlib.h> | |
+#include <stdio.h> | |
+#ifdef _MSC_VER | |
+#include <malloc.h> | |
+#endif | |
+#include "common.h" | |
+ | |
+#define GL_CONST 2.8346 | |
+ | |
+struct zint_render_line *render_plot_create_line(float x, float y, float width, float length); | |
+int render_plot_add_line(struct zint_symbol *symbol, struct zint_render_line *line, struct zint_render_line **last_line); | |
+struct zint_render_ring *render_plot_create_ring(float x, float y, float radius, float line_width); | |
+int render_plot_add_ring(struct zint_symbol *symbol, struct zint_render_ring *ring, struct zint_render_ring **last_ring); | |
+struct zint_render_hexagon *render_plot_create_hexagon(float x, float y, float height); | |
+int render_plot_add_hexagon(struct zint_symbol *symbol, struct zint_render_hexagon *hexagon, struct zint_render_hexagon **last_hexagon); | |
+ | |
+int render_plot_add_string(struct zint_symbol *symbol, unsigned char *text, float x, float y, float fsize, float width, struct zint_render_string **last_string); | |
+void render_free(struct zint_symbol *symbol); | |
+ | |
+int render_plot(struct zint_symbol *symbol, float width, float height) { | |
+ struct zint_render *render; | |
+ struct zint_render_line *line, *last_line = NULL; | |
+ struct zint_render_string *last_string = NULL; | |
+ struct zint_render_ring *last_ring = NULL; | |
+ struct zint_render_hexagon *last_hexagon = NULL; | |
+ | |
+ int i, r, latch; | |
+ float textpos, large_bar_height, preset_height, row_height, row_posn = 0.0; | |
+ // int error_number = 0; | |
+ int text_offset, text_height, xoffset, yoffset, textdone, main_symbol_width_x, addon_width_x; | |
+ char addon[6]; | |
+ int large_bar_count, symbol_lead_in, total_symbol_width_x, total_area_width_x; | |
+ float addon_text_posn; | |
+ float default_text_posn; | |
+ float scaler; | |
+ const char *locale = NULL; | |
+ int hide_text = 0; | |
+ float symbol_aspect = 1; | |
+ float x_dimension; | |
+ int upceanflag = 0; | |
+ | |
+ // Free any previous rendering structures | |
+ render_free(symbol); | |
+ // Allocate memory for the rendered version | |
+ render = symbol->rendered = (struct zint_render *) malloc(sizeof (struct zint_render)); | |
+ if (!symbol->rendered) return ZINT_ERROR_MEMORY; | |
+ render->lines = NULL; | |
+ render->strings = NULL; | |
+ render->rings = NULL; | |
+ render->hexagons = NULL; | |
+ | |
+ locale = setlocale(LC_ALL, "C"); | |
+ | |
+ row_height = 0; | |
+ textdone = 0; | |
+ textpos = 0.0; | |
+ main_symbol_width_x = symbol->width; | |
+ strcpy(addon, ""); | |
+ symbol_lead_in = 0; | |
+ addon_text_posn = 0.0; | |
+ addon_width_x = 0; | |
+ | |
+ /* | |
+ * Determine if there will be any addon texts and text height | |
+ */ | |
+ latch = 0; | |
+ r = 0; | |
+ /* Isolate add-on text */ | |
+ if (is_extendable(symbol->symbology)) { | |
+ for(i = 0; i < (int)ustrlen(symbol->text); i++) { | |
+ if (latch == 1) { | |
+ addon[r] = symbol->text[i]; | |
+ r++; | |
+ } | |
+ if (symbol->text[i] == '+') { | |
+ latch = 1; | |
+ } | |
+ } | |
+ } | |
+ addon[r] = '\0'; | |
+ | |
+ | |
+ /* | |
+ * Calculate the width of the barcode, especially if there are any extra | |
+ * borders or white space to add. | |
+ */ | |
+ | |
+ while (!(module_is_set(symbol, symbol->rows - 1, symbol_lead_in))) { | |
+ symbol_lead_in++; | |
+ } | |
+ | |
+ /* Certain symbols need whitespace otherwise characters get chopped off the sides */ | |
+ if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) | |
+ || (symbol->symbology == BARCODE_ISBNX)) { | |
+ switch (ustrlen(symbol->text)) { | |
+ case 13: /* EAN 13 */ | |
+ case 16: | |
+ case 19: | |
+ if (symbol->whitespace_width == 0) { | |
+ symbol->whitespace_width = 10; | |
+ } | |
+ main_symbol_width_x = 96 + symbol_lead_in; | |
+ upceanflag = 13; | |
+ break; | |
+ case 2: | |
+ main_symbol_width_x = 22 + symbol_lead_in; | |
+ upceanflag = 2; | |
+ break; | |
+ case 5: | |
+ main_symbol_width_x = 49 + symbol_lead_in; | |
+ upceanflag = 5; | |
+ break; | |
+ default: | |
+ main_symbol_width_x = 68 + symbol_lead_in; | |
+ upceanflag = 8; | |
+ } | |
+ switch (ustrlen(symbol->text)) { | |
+ case 11: | |
+ case 16: | |
+ /* EAN-2 add-on */ | |
+ addon_width_x = 31; | |
+ break; | |
+ case 14: | |
+ case 19: | |
+ /* EAN-5 add-on */ | |
+ addon_width_x = 58; | |
+ break; | |
+ } | |
+ } | |
+ else if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { | |
+ upceanflag = 12; | |
+ if (symbol->whitespace_width < 10) { | |
+ symbol->whitespace_width = 10; | |
+ main_symbol_width_x = 96 + symbol_lead_in; | |
+ } | |
+ switch (ustrlen(symbol->text)) { | |
+ case 15: | |
+ /* EAN-2 add-on */ | |
+ addon_width_x = 31; | |
+ break; | |
+ case 18: | |
+ /* EAN-5 add-on */ | |
+ addon_width_x = 58; | |
+ break; | |
+ } | |
+ } | |
+ else if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { | |
+ upceanflag = 6; | |
+ if (symbol->whitespace_width == 0) { | |
+ symbol->whitespace_width = 10; | |
+ main_symbol_width_x = 51 + symbol_lead_in; | |
+ } | |
+ switch (ustrlen(symbol->text)) { | |
+ case 11: | |
+ /* EAN-2 add-on */ | |
+ addon_width_x = 31; | |
+ break; | |
+ case 14: | |
+ /* EAN-5 add-on */ | |
+ addon_width_x = 58; | |
+ break; | |
+ } | |
+ } | |
+ | |
+ if ((!symbol->show_hrt) || (ustrlen(symbol->text) == 0)) { | |
+ hide_text = 1; | |
+ text_height = text_offset = 0.0; | |
+ } | |
+ else { | |
+ text_height = upceanflag ? 11.0 : 9.0; | |
+ text_offset = 2.0; | |
+ } | |
+ if (symbol->output_options & SMALL_TEXT) | |
+ text_height *= 0.8; | |
+ | |
+ total_symbol_width_x = 0.0 + main_symbol_width_x + addon_width_x; | |
+ total_area_width_x = total_symbol_width_x + (2 * (symbol->border_width + symbol->whitespace_width)); | |
+ | |
+ xoffset = symbol->border_width + symbol->whitespace_width; | |
+ yoffset = symbol->border_width; | |
+ | |
+ | |
+ // Determine if height should be overridden | |
+ large_bar_count = 0; | |
+ preset_height = 0.0; | |
+ for (i = 0; i < symbol->rows; i++) { | |
+ preset_height += symbol->row_height[i]; | |
+ if (symbol->row_height[i] == 0) { | |
+ large_bar_count++; | |
+ } | |
+ } | |
+ | |
+ | |
+ /* Set minimum size of symbol */ | |
+ /* Barcode must be at least 2mm high by 2mm across */ | |
+ if (width < (2.0 * GL_CONST)) { | |
+ width = (2.0 * GL_CONST); | |
+ } | |
+ x_dimension = width / total_area_width_x / GL_CONST; | |
+ if (height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST) { | |
+ height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST; | |
+ } | |
+ | |
+ if (symbol->symbology == BARCODE_CODABAR) { | |
+ /* The minimum X-dimension of Codabar is 0.191mm. The minimum bar height is 5mm */ | |
+ if (x_dimension < 0.191) { | |
+ x_dimension = 0.191; | |
+ width = 0.191 * GL_CONST * total_area_width_x; | |
+ } | |
+ if (height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST) { | |
+ height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST; | |
+ } | |
+ } | |
+ else if (symbol->symbology == BARCODE_CODE49) { | |
+ /* The minimum X-dimension of Code 49 is 0.191mm */ | |
+ if (x_dimension < 0.191) { | |
+ float encoded_symbol_aspect; | |
+ x_dimension = 0.191; | |
+ width = 0.191 * GL_CONST * total_area_width_x; | |
+ encoded_symbol_aspect = total_area_width_x; | |
+ encoded_symbol_aspect /= (preset_height + (2 * yoffset) + text_offset + text_height); | |
+ height = width / encoded_symbol_aspect; | |
+ } | |
+ } | |
+ | |
+ if (upceanflag != 0) { | |
+ /* The X-dimension of UPC/EAN symbols is fixed at 0.330mm */ | |
+ /* The phrase before is questionable. It may scale in certain percentages (80% - 200%). | |
+ see https://internationalbarcodes.com/ean-13-specifications/ */ | |
+ // Can now cope with sizes between 80% and 200%, enforces correct aspect ratio | |
+ /* NOTE: This code will need adjustment before it correctly deals with composite symbols */ | |
+ //x_dimension = 0.330; | |
+ if (x_dimension < 0.26) { | |
+ x_dimension = 0.26; | |
+ } | |
+ if (x_dimension > 0.66) { | |
+ x_dimension = 0.66; | |
+ } | |
+ width = x_dimension * GL_CONST * total_area_width_x; | |
+ | |
+ switch (upceanflag) { | |
+ case 6: | |
+ case 12: | |
+ case 13: | |
+ /* UPC-A, UPC-E and EAN-13 */ | |
+ /* Height of bars should be 22.85mm */ | |
+ height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + (22.85 * (x_dimension / 0.33))) * GL_CONST; | |
+ break; | |
+ case 8: | |
+ /* EAN-8 */ | |
+ /* Height of bars should be 18.23mm */ | |
+ height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + (18.23 * (x_dimension / 0.33))) * GL_CONST; | |
+ break; | |
+ default: | |
+ /* EAN-2 and EAN-5 */ | |
+ /* Height of bars should be 21.10mm */ | |
+ height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + (21.10 * (x_dimension / 0.33))) * GL_CONST; | |
+ } | |
+ } | |
+ | |
+ if (symbol->symbology == BARCODE_ONECODE) { | |
+ /* The size of USPS Intelligent Mail barcode is fixed */ | |
+ x_dimension = 0.508; | |
+ width = 0.508 * GL_CONST * total_area_width_x; | |
+ height = 4.064 * GL_CONST; | |
+ } | |
+ else if ((symbol->symbology == BARCODE_POSTNET) || (symbol->symbology == BARCODE_PLANET)) { | |
+ /* The size of PostNet and PLANET are fized */ | |
+ x_dimension = 0.508; | |
+ width = 0.508 * GL_CONST * total_area_width_x; | |
+ height = 2.921 * GL_CONST; | |
+ } | |
+ else if (((symbol->symbology == BARCODE_AUSPOST) || (symbol->symbology == BARCODE_AUSREPLY)) || | |
+ ((symbol->symbology == BARCODE_AUSROUTE) || (symbol->symbology == BARCODE_AUSREDIRECT))) { | |
+ /* Australia Post use the same sizes as USPS */ | |
+ x_dimension = 0.508; | |
+ width = 0.508 * GL_CONST * total_area_width_x; | |
+ height = 4.064 * GL_CONST; | |
+ } | |
+ else if ((symbol->symbology == BARCODE_RM4SCC) || (symbol->symbology == BARCODE_KIX)) { | |
+ /* Royal Mail and KIX Code uses 22 bars per inch */ | |
+ x_dimension = 0.577; | |
+ width = 0.577 * GL_CONST * total_area_width_x; | |
+ height = 5.22 * GL_CONST; | |
+ } | |
+ | |
+ | |
+ if (large_bar_count == 0) { | |
+ float required_aspect = width / height; | |
+ symbol_aspect = (total_symbol_width_x + (2 * xoffset)) / (preset_height + (2 * yoffset) + text_offset + text_height); | |
+ symbol->height = (int) preset_height; | |
+ if (required_aspect > symbol_aspect) { | |
+ /* the area is too wide */ | |
+ scaler = height / (preset_height + (2 * yoffset) + text_offset + text_height); | |
+ render->width = symbol_aspect * height; | |
+ render->height = height; | |
+ } else { | |
+ /* the area is too high */ | |
+ scaler = width / (total_symbol_width_x + (2 * xoffset)); | |
+ render->width = width; | |
+ render->height = width / symbol_aspect; | |
+ } | |
+ } else { | |
+ scaler = width / (total_symbol_width_x + (2 * xoffset)); | |
+ symbol->height = (int) ((height / scaler) - ((2 * yoffset) + text_offset + text_height)); | |
+ | |
+ render->width = width; | |
+ render->height = height; | |
+ } | |
+ large_bar_height = (symbol->height - preset_height) / large_bar_count; | |
+ | |
+ if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { | |
+ default_text_posn = (symbol->height + text_offset + symbol->border_width + symbol->border_width) * scaler; | |
+ } else { | |
+ default_text_posn = (symbol->height + text_offset + symbol->border_width) * scaler; | |
+ } | |
+ | |
+ | |
+ if (symbol->symbology == BARCODE_MAXICODE) { | |
+ struct zint_render_ring *ring; | |
+ /* Maxicode is a fixed size */ | |
+ scaler = GL_CONST; /* Converts from millimeters to the scale used by glabels */ | |
+ render->width = 28.16 * scaler; | |
+ render->height = 26.86 * scaler; | |
+ | |
+ /* Central bullseye pattern */ | |
+ ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 0.85 * scaler, 0.67 * scaler); | |
+ render_plot_add_ring(symbol, ring, &last_ring); | |
+ ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 2.20 * scaler, 0.67 * scaler); | |
+ render_plot_add_ring(symbol, ring, &last_ring); | |
+ ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 3.54 * scaler, 0.67 * scaler); | |
+ render_plot_add_ring(symbol, ring, &last_ring); | |
+ | |
+ /* Hexagons */ | |
+ for (r = 0; r < symbol->rows; r++) { | |
+ for (i = 0; i < symbol->width; i++) { | |
+ if (module_is_set(symbol, r, i)) { | |
+ struct zint_render_hexagon *hexagon = render_plot_create_hexagon(((i * 0.88) + ((r & 1) ? 1.76 : 1.32)) * scaler, ((r * 0.76) + 0.76) * scaler, 1. * scaler); | |
+ render_plot_add_hexagon(symbol, hexagon, &last_hexagon); | |
+ } | |
+ } | |
+ } | |
+ | |
+ } else { | |
+ /* everything else uses rectangles (or squares) */ | |
+ /* Works from the bottom of the symbol up */ | |
+ int addon_latch = 0; | |
+ | |
+ for (r = 0; r < symbol->rows; r++) { | |
+ int this_row = r; | |
+ if (symbol->row_height[this_row] == 0) { | |
+ row_height = large_bar_height; | |
+ } else { | |
+ row_height = symbol->row_height[this_row]; | |
+ } | |
+ row_posn = 0; | |
+ for (i = 0; i < r; i++) { | |
+ if (symbol->row_height[i] == 0) { | |
+ row_posn += large_bar_height; | |
+ } else { | |
+ row_posn += symbol->row_height[i]; | |
+ } | |
+ } | |
+ row_posn += yoffset; | |
+ | |
+ i = 0; | |
+ if (module_is_set(symbol, this_row, 0)) { | |
+ latch = 1; | |
+ } else { | |
+ latch = 0; | |
+ } | |
+ | |
+ do { | |
+ int block_width = 0; | |
+ do { | |
+ block_width++; | |
+ } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); | |
+ if ((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_symbol_width_x)) { | |
+ addon_text_posn = row_posn * scaler; | |
+ addon_latch = 1; | |
+ } | |
+ if (latch == 1) { | |
+ /* a bar */ | |
+ if (addon_latch == 0) { | |
+ line = render_plot_create_line((i + xoffset) * scaler, (row_posn) * scaler, block_width * scaler, row_height * scaler); | |
+ } else { | |
+ line = render_plot_create_line((i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler); | |
+ } | |
+ latch = 0; | |
+ | |
+ render_plot_add_line(symbol, line, &last_line); | |
+ } else { | |
+ /* a space */ | |
+ latch = 1; | |
+ } | |
+ i += block_width; | |
+ | |
+ } while (i < symbol->width); | |
+ } | |
+ } | |
+ /* That's done the actual data area, everything else is human-friendly */ | |
+ | |
+ | |
+ /* Add the text */ | |
+ xoffset -= symbol_lead_in; | |
+ row_posn = (row_posn + large_bar_height) * scaler; | |
+ | |
+ if (!hide_text) { | |
+ char textpart[10]; | |
+ float textwidth; | |
+ if (upceanflag == 8) { | |
+ /* guard bar extensions and text formatting for EAN-8 */ | |
+ i = 0; | |
+ for (line = symbol->rendered->lines; line != NULL; line = line->next) { | |
+ switch (i) { | |
+ case 0: | |
+ case 1: | |
+ case 10: | |
+ case 11: | |
+ case 20: | |
+ case 21: | |
+ line->length += (5.0 * scaler); | |
+ break; | |
+ } | |
+ i++; | |
+ } | |
+ | |
+ for (i = 0; i < 4; i++) { | |
+ textpart[i] = symbol->text[i]; | |
+ } | |
+ textpart[4] = '\0'; | |
+ textpos = 17; | |
+ textwidth = 4.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, text_height * scaler, textwidth * scaler, &last_string); | |
+ for (i = 0; i < 4; i++) { | |
+ textpart[i] = symbol->text[i + 4]; | |
+ } | |
+ textpart[4] = '\0'; | |
+ textpos = 50; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, text_height * scaler, textwidth * scaler, &last_string); | |
+ textdone = 1; | |
+ switch (strlen(addon)) { | |
+ case 2: | |
+ textpos = xoffset + 86; | |
+ textwidth = 2.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, text_height * scaler, textwidth * scaler, &last_string); | |
+ break; | |
+ case 5: | |
+ textpos = xoffset + 100; | |
+ textwidth = 5.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, text_height * scaler, textwidth * scaler, &last_string); | |
+ break; | |
+ } | |
+ | |
+ } | |
+ | |
+ if (upceanflag == 13) { | |
+ /* guard bar extensions and text formatting for EAN-13 */ | |
+ i = 0; | |
+ for (line = symbol->rendered->lines; line != NULL; line = line->next) { | |
+ switch (i) { | |
+ case 0: | |
+ case 1: | |
+ case 14: | |
+ case 15: | |
+ case 28: | |
+ case 29: | |
+ line->length += (5.0 * scaler); | |
+ break; | |
+ } | |
+ i++; | |
+ } | |
+ | |
+ textpart[0] = symbol->text[0]; | |
+ textpart[1] = '\0'; | |
+ textpos = -5; // 7 | |
+ textwidth = 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, text_height * scaler, textwidth * scaler, &last_string); | |
+ | |
+ for (i = 0; i < 6; i++) { | |
+ textpart[i] = symbol->text[i + 1]; | |
+ } | |
+ textpart[6] = '\0'; | |
+ textpos = 25; | |
+ textwidth = 6.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, text_height * scaler, textwidth * scaler, &last_string); | |
+ for (i = 0; i < 6; i++) { | |
+ textpart[i] = symbol->text[i + 7]; | |
+ } | |
+ textpart[6] = '\0'; | |
+ textpos = 72; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, text_height * scaler, textwidth * scaler, &last_string); | |
+ textdone = 1; | |
+ switch (strlen(addon)) { | |
+ case 2: | |
+ textpos = xoffset + 114; | |
+ textwidth = 2.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, text_height * scaler, textwidth * scaler, &last_string); | |
+ break; | |
+ case 5: | |
+ textpos = xoffset + 128; | |
+ textwidth = 5.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, text_height * scaler, textwidth * scaler, &last_string); | |
+ break; | |
+ } | |
+ } | |
+ | |
+ if (upceanflag == 12) { | |
+ /* guard bar extensions and text formatting for UPCA */ | |
+ i = 0; | |
+ for (line = symbol->rendered->lines; line != NULL; line = line->next) { | |
+ switch (i) { | |
+ case 0: | |
+ case 1: | |
+ case 2: | |
+ case 3: | |
+ case 14: | |
+ case 15: | |
+ case 26: | |
+ case 27: | |
+ case 28: | |
+ case 29: | |
+ line->length += (5.0 * scaler); | |
+ break; | |
+ } | |
+ i++; | |
+ } | |
+ | |
+ textpart[0] = symbol->text[0]; | |
+ textpart[1] = '\0'; | |
+ textpos = -5; | |
+ textwidth = 6.2; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), text_height * (8.0 / 11.0) * scaler, textwidth * scaler, &last_string); | |
+ for (i = 0; i < 5; i++) { | |
+ textpart[i] = symbol->text[i + 1]; | |
+ } | |
+ textpart[5] = '\0'; | |
+ textpos = 27; | |
+ textwidth = 5.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, text_height * scaler, textwidth * scaler, &last_string); | |
+ for (i = 0; i < 5; i++) { | |
+ textpart[i] = symbol->text[i + 6]; | |
+ } | |
+ textpos = 68; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, text_height * scaler, textwidth * scaler, &last_string); | |
+ textpart[0] = symbol->text[11]; | |
+ textpart[1] = '\0'; | |
+ textpos = 100; | |
+ textwidth = 6.2; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), text_height * (8.0 / 11.0) * scaler, textwidth * scaler, &last_string); | |
+ textdone = 1; | |
+ switch (strlen(addon)) { | |
+ case 2: | |
+ textpos = xoffset + 116; | |
+ textwidth = 2.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, text_height * scaler, textwidth * scaler, &last_string); | |
+ break; | |
+ case 5: | |
+ textpos = xoffset + 130; | |
+ textwidth = 5.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, text_height * scaler, textwidth * scaler, &last_string); | |
+ break; | |
+ } | |
+ } | |
+ | |
+ if (upceanflag == 6) { | |
+ /* guard bar extensions and text formatting for UPCE */ | |
+ i = 0; | |
+ for (line = symbol->rendered->lines; line != NULL; line = line->next) { | |
+ switch (i) { | |
+ case 0: | |
+ case 1: | |
+ case 14: | |
+ case 15: | |
+ case 16: | |
+ line->length += (5.0 * scaler); | |
+ break; | |
+ } | |
+ i++; | |
+ } | |
+ | |
+ textpart[0] = symbol->text[0]; | |
+ textpart[1] = '\0'; | |
+ textpos = -5; | |
+ textwidth = 6.2; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), text_height * (8.0 / 11.0) * scaler, textwidth * scaler, &last_string); | |
+ for (i = 0; i < 6; i++) { | |
+ textpart[i] = symbol->text[i + 1]; | |
+ } | |
+ textpart[6] = '\0'; | |
+ textpos = 24; | |
+ textwidth = 6.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, text_height * scaler, textwidth * scaler, &last_string); | |
+ textpart[0] = symbol->text[7]; | |
+ textpart[1] = '\0'; | |
+ textpos = 55; | |
+ textwidth = 6.2; | |
+ render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), text_height * (8.0 / 11.0) * scaler, textwidth * scaler, &last_string); | |
+ textdone = 1; | |
+ switch (strlen(addon)) { | |
+ case 2: | |
+ textpos = xoffset + 70; | |
+ textwidth = 2.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, text_height * scaler, textwidth * scaler, &last_string); | |
+ break; | |
+ case 5: | |
+ textpos = xoffset + 84; | |
+ textwidth = 5.0 * 8.5; | |
+ render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, text_height * scaler, textwidth * scaler, &last_string); | |
+ break; | |
+ } | |
+ } | |
+ | |
+ /* Put normal human readable text at the bottom (and centered) */ | |
+ if (textdone == 0) { | |
+ // caculate start xoffset to center text | |
+ render_plot_add_string(symbol, symbol->text, ((symbol->width / 2.0) + xoffset) * scaler, default_text_posn, text_height * scaler, symbol->width * scaler, &last_string); | |
+ } | |
+ } | |
+ | |
+ switch (symbol->symbology) { | |
+ case BARCODE_MAXICODE: | |
+ /* Do nothing! */ | |
+ break; | |
+ default: | |
+ if ((symbol->output_options & BARCODE_BIND) != 0) { | |
+ if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { | |
+ /* row binding */ | |
+ for (r = 1; r < symbol->rows; r++) { | |
+ line = render_plot_create_line(xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler); | |
+ render_plot_add_line(symbol, line, &last_line); | |
+ } | |
+ } | |
+ } | |
+ if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { | |
+ line = render_plot_create_line(0, 0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); | |
+ render_plot_add_line(symbol, line, &last_line); | |
+ line = render_plot_create_line(0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); | |
+ render_plot_add_line(symbol, line, &last_line); | |
+ } | |
+ if (symbol->output_options & BARCODE_BOX) { | |
+ /* side bars */ | |
+ line = render_plot_create_line(0, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); | |
+ render_plot_add_line(symbol, line, &last_line); | |
+ line = render_plot_create_line((symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); | |
+ render_plot_add_line(symbol, line, &last_line); | |
+ } | |
+ break; | |
+ } | |
+ | |
+ if (locale) | |
+ setlocale(LC_ALL, locale); | |
+ | |
+ return 1; | |
+} | |
+ | |
+/* | |
+ * Create a new line with its memory allocated ready for adding to the | |
+ * rendered structure. | |
+ * | |
+ * This is much quicker than writing out each line manually (in some cases!) | |
+ */ | |
+struct zint_render_line *render_plot_create_line(float x, float y, float width, float length) { | |
+ struct zint_render_line *line; | |
+ | |
+ line = (struct zint_render_line*) malloc(sizeof (struct zint_render_line)); | |
+ if (!line) return NULL; | |
+ | |
+ line->next = NULL; | |
+ line->x = x; | |
+ line->y = y; | |
+ line->width = width; | |
+ line->length = length; | |
+ | |
+ return line; | |
+} | |
+ | |
+/* | |
+ * Add the line to the current rendering and update the last line's | |
+ * next value. | |
+ */ | |
+int render_plot_add_line(struct zint_symbol *symbol, struct zint_render_line *line, struct zint_render_line **last_line) { | |
+ if (!line) return ZINT_ERROR_MEMORY; | |
+ if (*last_line) | |
+ (*last_line)->next = line; | |
+ else | |
+ symbol->rendered->lines = line; // first line | |
+ | |
+ *last_line = line; | |
+ return 1; | |
+} | |
+ | |
+struct zint_render_ring *render_plot_create_ring(float x, float y, float radius, float line_width) { | |
+ struct zint_render_ring *ring; | |
+ | |
+ ring = (struct zint_render_ring *) malloc(sizeof (struct zint_render_ring)); | |
+ if (!ring) return NULL; | |
+ ring->next = NULL; | |
+ ring->x = x; | |
+ ring->y = y; | |
+ ring->radius = radius; | |
+ ring->line_width = line_width; | |
+ | |
+ return ring; | |
+} | |
+ | |
+int render_plot_add_ring(struct zint_symbol *symbol, struct zint_render_ring *ring, struct zint_render_ring **last_ring) { | |
+ if (!ring) return ZINT_ERROR_MEMORY; | |
+ if (*last_ring) | |
+ (*last_ring)->next = ring; | |
+ else | |
+ symbol->rendered->rings = ring; // first ring | |
+ | |
+ *last_ring = ring; | |
+ return 1; | |
+} | |
+ | |
+struct zint_render_hexagon *render_plot_create_hexagon(float x, float y, float height) { | |
+ struct zint_render_hexagon *hexagon; | |
+ | |
+ hexagon = (struct zint_render_hexagon*) malloc(sizeof (struct zint_render_hexagon)); | |
+ if (!hexagon) return NULL; | |
+ hexagon->next = NULL; | |
+ hexagon->x = x; | |
+ hexagon->y = y; | |
+ hexagon->height = height; | |
+ | |
+ return hexagon; | |
+} | |
+ | |
+int render_plot_add_hexagon(struct zint_symbol *symbol, struct zint_render_hexagon *hexagon, struct zint_render_hexagon **last_hexagon) { | |
+ if (!hexagon) return ZINT_ERROR_MEMORY; | |
+ if (*last_hexagon) | |
+ (*last_hexagon)->next = hexagon; | |
+ else | |
+ symbol->rendered->hexagons = hexagon; // first hexagon | |
+ | |
+ *last_hexagon = hexagon; | |
+ return 1; | |
+} | |
+ | |
+/* | |
+ * Add a string structure to the symbol. | |
+ * Coordinates assumed to be from top-center. | |
+ */ | |
+int render_plot_add_string(struct zint_symbol *symbol, | |
+ unsigned char *text, float x, float y, float fsize, float width, | |
+ struct zint_render_string **last_string) { | |
+ struct zint_render_string *string; | |
+ | |
+ string = (struct zint_render_string*) malloc(sizeof (struct zint_render_string)); | |
+ string->next = NULL; | |
+ string->x = x; | |
+ string->y = y; | |
+ string->width = width; | |
+ string->fsize = fsize; | |
+ string->length = ustrlen(text); | |
+ string->text = (unsigned char*) malloc(sizeof (unsigned char) * (ustrlen(text) + 1)); | |
+ ustrcpy(string->text, text); | |
+ | |
+ if (*last_string) | |
+ (*last_string)->next = string; | |
+ else | |
+ symbol->rendered->strings = string; // First character | |
+ *last_string = string; | |
+ | |
+ return 1; | |
+} | |
+ | |
+/* | |
+ * Free the data structures created by render_plot | |
+ */ | |
+void render_free(struct zint_symbol *symbol) { | |
+ if (symbol->rendered != NULL) { | |
+ struct zint_render_line *line; | |
+ struct zint_render_string *string; | |
+ struct zint_render_ring *ring; | |
+ struct zint_render_hexagon *hexagon; | |
+ | |
+ // Free lines | |
+ line = symbol->rendered->lines; | |
+ while (line) { | |
+ struct zint_render_line *l = line; | |
+ line = line->next; | |
+ free(l); | |
+ } | |
+ // Free Strings | |
+ string = symbol->rendered->strings; | |
+ while (string) { | |
+ struct zint_render_string *s = string; | |
+ string = string->next; | |
+ free(s->text); | |
+ free(s); | |
+ } | |
+ | |
+ // Free Rings | |
+ ring = symbol->rendered->rings; | |
+ while (ring) { | |
+ struct zint_render_ring *r = ring; | |
+ ring = ring->next; | |
+ free(r); | |
+ } | |
+ | |
+ // Free Hexagons | |
+ hexagon = symbol->rendered->hexagons; | |
+ while (hexagon) { | |
+ struct zint_render_hexagon *h = hexagon; | |
+ hexagon = hexagon->next; | |
+ free(h); | |
+ } | |
+ | |
+ // Free Render | |
+ free(symbol->rendered); | |
+ symbol->rendered = NULL; | |
+ } | |
+} | |
+ | |
+ | |
diff --git a/zint.h b/zint.h | |
new file mode 100644 | |
index 0000000..41923fb | |
--- /dev/null | |
+++ b/zint.h | |
@@ -0,0 +1,454 @@ | |
+/* zint.h - definitions for libzint */ | |
+/* | |
+ libzint - the open source barcode library | |
+ Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com> | |
+ | |
+ Redistribution and use in source and binary forms, with or without | |
+ modification, are permitted provided that the following conditions | |
+ are met: | |
+ | |
+ 1. Redistributions of source code must retain the above copyright | |
+ notice, this list of conditions and the following disclaimer. | |
+ 2. Redistributions in binary form must reproduce the above copyright | |
+ notice, this list of conditions and the following disclaimer in the | |
+ documentation and/or other materials provided with the distribution. | |
+ 3. Neither the name of the project nor the names of its contributors | |
+ may be used to endorse or promote products derived from this software | |
+ without specific prior written permission. | |
+ | |
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | |
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
+ SUCH DAMAGE. | |
+ */ | |
+/* SPDX-License-Identifier: BSD-3-Clause */ | |
+ | |
+/* | |
+ * For version, see "zintconfig.h" | |
+ * For documentation, see "../docs/manual.txt" | |
+ */ | |
+ | |
+#ifndef ZINT_H | |
+#define ZINT_H | |
+ | |
+#ifdef __cplusplus | |
+extern "C" { | |
+#endif /* __cplusplus */ | |
+ | |
+ struct zint_vector_rect { | |
+ float x, y, height, width; | |
+ int colour; /* -1 for foreground, 1-8 for Cyan, Blue, Magenta, Red, Yellow, Green, Black, White */ | |
+ struct zint_vector_rect *next; /* Pointer to next rectangle */ | |
+ }; | |
+ | |
+ struct zint_vector_hexagon { | |
+ float x, y, diameter; | |
+ int rotation; /* 0, 90, 180, 270 degrees */ | |
+ struct zint_vector_hexagon *next; /* Pointer to next hexagon */ | |
+ }; | |
+ | |
+ struct zint_vector_string { | |
+ float x, y; /* x, y position relative to halign */ | |
+ float fsize; /* Font size */ | |
+ float width; /* Suggested string width, may be 0 if none recommended */ | |
+ int length; /* Number of characters */ | |
+ int rotation; /* 0, 90, 180, 270 degrees */ | |
+ int halign; /* Horizontal alignment: 0 for centre, 1 for left, 2 for right (end) */ | |
+ unsigned char *text; | |
+ struct zint_vector_string *next; /* Pointer to next string */ | |
+ }; | |
+ | |
+ struct zint_vector_circle { | |
+ float x, y; | |
+ float diameter; /* Circle diameter. Does not include width (if any) */ | |
+ float width; /* Width of circle perimeter (circumference). 0 for fill (disc) */ | |
+ int colour; /* Non-zero for draw with background colour (else draw with foreground colour) */ | |
+ struct zint_vector_circle *next; /* Pointer to next circle */ | |
+ }; | |
+ | |
+ /* Vector header */ | |
+ struct zint_vector { | |
+ float width, height; /* Width, height of barcode image (including text, whitespace) */ | |
+ struct zint_vector_rect *rectangles; /* Pointer to first rectangle */ | |
+ struct zint_vector_hexagon *hexagons; /* Pointer to first hexagon */ | |
+ struct zint_vector_string *strings; /* Pointer to first string */ | |
+ struct zint_vector_circle *circles; /* Pointer to first circle */ | |
+ }; | |
+ | |
+ /* Structured Append info - ignored unless `zint_structapp.count` is set to non-zero value */ | |
+ struct zint_structapp { | |
+ int index; /* Position in Structured Append sequence, 1-based. Must be <= `count` */ | |
+ int count; /* Number of symbols in Structured Append sequence. Set >= 2 to add SA Info */ | |
+ char id[32]; /* Optional ID to distinguish sequence, ASCII, NUL-terminated unless max 32 long */ | |
+ }; | |
+ | |
+ /* Main symbol structure */ | |
+ struct zint_symbol { | |
+ int symbology; /* Symbol to use (see BARCODE_XXX below) */ | |
+ float height; /* Barcode height in X-dimensions (ignored for fixed-width barcodes) */ | |
+ float scale; /* Scale factor when printing barcode, i.e. adjusts X-dimension. Default 1 */ | |
+ int whitespace_width; /* Width in X-dimensions of whitespace to left & right of barcode */ | |
+ int whitespace_height; /* Height in X-dimensions of whitespace above & below the barcode */ | |
+ int border_width; /* Size of border in X-dimensions */ | |
+ int output_options; /* Various output parameters (bind, box etc, see below) */ | |
+ char fgcolour[10]; /* Foreground as RGB/RGBA hexadecimal string, 6 or 8 characters, NUL-terminated */ | |
+ char bgcolour[10]; /* Background as RGB/RGBA hexadecimal string, 6 or 8 characters, NUL-terminated */ | |
+ char *fgcolor; /* Pointer to fgcolour (alternate spelling) */ | |
+ char *bgcolor; /* Pointer to bgcolour (alternate spelling) */ | |
+ char outfile[256]; /* Name of file to output to, NUL-terminated. Default "out.png" ("out.gif" if NO_PNG) */ | |
+ char primary[128]; /* Primary message data (MaxiCode, Composite), NUL-terminated */ | |
+ int option_1; /* Symbol-specific options (see "../docs/manual.txt") */ | |
+ int option_2; /* Symbol-specific options */ | |
+ int option_3; /* Symbol-specific options */ | |
+ int show_hrt; /* Show (1) or hide (0) Human Readable Text. Default 1 */ | |
+ int fontsize; /* Unused */ | |
+ int input_mode; /* Encoding of input data (see DATA_MODE etc below). Default DATA_MODE */ | |
+ int eci; /* Extended Channel Interpretation. Default 0 (none) */ | |
+ float dot_size; /* Size of dots used in BARCODE_DOTTY_MODE. Default 0.8 */ | |
+ float guard_descent; /* Height in X-dimensions that EAN/UPC guard bars descend. Default 5 */ | |
+ struct zint_structapp structapp; /* Structured Append info. Default structapp.count 0 (none) */ | |
+ int warn_level; /* Affects error/warning value returned by Zint API (see WARN_XXX below) */ | |
+ int debug; /* Debugging flags */ | |
+ unsigned char text[128]; /* Human Readable Text (if any), UTF-8, NUL-terminated (output only) */ | |
+ int rows; /* Number of rows used by the symbol (output only) */ | |
+ int width; /* Width of the generated symbol (output only) */ | |
+ unsigned char encoded_data[200][144]; /* Encoded data (output only). Allows for rows of 1152 modules */ | |
+ float row_height[200]; /* Heights of rows (output only). Allows for 200 row DotCode */ | |
+ char errtxt[100]; /* Error message if an error or warning occurs, NUL-terminated (output only) */ | |
+ unsigned char *bitmap; /* Stored bitmap image (raster output only) */ | |
+ int bitmap_width; /* Width of bitmap image (raster output only) */ | |
+ int bitmap_height; /* Height of bitmap image (raster output only) */ | |
+ unsigned char *alphamap; /* Array of alpha values used (raster output only) */ | |
+ unsigned int bitmap_byte_length; /* Size of BMP bitmap data (raster output only) */ | |
+ struct zint_vector *vector; /* Pointer to vector header (vector output only) */ | |
+ }; | |
+ | |
+ /* Segment for use with `ZBarcode_Encode_Segs()` below */ | |
+ struct zint_seg { | |
+ unsigned char *source; /* Data to encode */ | |
+ int length; /* Length of `source`. If 0, `source` must be NUL-terminated */ | |
+ int eci; /* Extended Channel Interpretation */ | |
+ }; | |
+ | |
+/* Symbologies (`symbol->symbology`) */ | |
+ /* Tbarcode 7 codes */ | |
+#define BARCODE_CODE11 1 /* Code 11 */ | |
+#define BARCODE_C25STANDARD 2 /* 2 of 5 Standard (Matrix) */ | |
+#define BARCODE_C25MATRIX 2 /* Legacy */ | |
+#define BARCODE_C25INTER 3 /* 2 of 5 Interleaved */ | |
+#define BARCODE_C25IATA 4 /* 2 of 5 IATA */ | |
+#define BARCODE_C25LOGIC 6 /* 2 of 5 Data Logic */ | |
+#define BARCODE_C25IND 7 /* 2 of 5 Industrial */ | |
+#define BARCODE_CODE39 8 /* Code 39 */ | |
+#define BARCODE_EXCODE39 9 /* Extended Code 39 */ | |
+#define BARCODE_EANX 13 /* EAN (European Article Number) */ | |
+#define BARCODE_EANX_CHK 14 /* EAN + Check Digit */ | |
+#define BARCODE_GS1_128 16 /* GS1-128 */ | |
+#define BARCODE_EAN128 16 /* Legacy */ | |
+#define BARCODE_CODABAR 18 /* Codabar */ | |
+#define BARCODE_CODE128 20 /* Code 128 */ | |
+#define BARCODE_DPLEIT 21 /* Deutsche Post Leitcode */ | |
+#define BARCODE_DPIDENT 22 /* Deutsche Post Identcode */ | |
+#define BARCODE_CODE16K 23 /* Code 16k */ | |
+#define BARCODE_CODE49 24 /* Code 49 */ | |
+#define BARCODE_CODE93 25 /* Code 93 */ | |
+#define BARCODE_FLAT 28 /* Flattermarken */ | |
+#define BARCODE_DBAR_OMN 29 /* GS1 DataBar Omnidirectional */ | |
+#define BARCODE_RSS14 29 /* Legacy */ | |
+#define BARCODE_DBAR_LTD 30 /* GS1 DataBar Limited */ | |
+#define BARCODE_RSS_LTD 30 /* Legacy */ | |
+#define BARCODE_DBAR_EXP 31 /* GS1 DataBar Expanded */ | |
+#define BARCODE_RSS_EXP 31 /* Legacy */ | |
+#define BARCODE_TELEPEN 32 /* Telepen Alpha */ | |
+#define BARCODE_UPCA 34 /* UPC-A */ | |
+#define BARCODE_UPCA_CHK 35 /* UPC-A + Check Digit */ | |
+#define BARCODE_UPCE 37 /* UPC-E */ | |
+#define BARCODE_UPCE_CHK 38 /* UPC-E + Check Digit */ | |
+#define BARCODE_POSTNET 40 /* USPS (U.S. Postal Service) POSTNET */ | |
+#define BARCODE_MSI_PLESSEY 47 /* MSI Plessey */ | |
+#define BARCODE_FIM 49 /* Facing Identification Mark */ | |
+#define BARCODE_LOGMARS 50 /* LOGMARS */ | |
+#define BARCODE_PHARMA 51 /* Pharmacode One-Track */ | |
+#define BARCODE_PZN 52 /* Pharmazentralnummer */ | |
+#define BARCODE_PHARMA_TWO 53 /* Pharmacode Two-Track */ | |
+#define BARCODE_CEPNET 54 /* Brazilian CEPNet Postal Code */ | |
+#define BARCODE_PDF417 55 /* PDF417 */ | |
+#define BARCODE_PDF417COMP 56 /* Compact PDF417 (Truncated PDF417) */ | |
+#define BARCODE_PDF417TRUNC 56 /* Legacy */ | |
+#define BARCODE_MAXICODE 57 /* MaxiCode */ | |
+#define BARCODE_QRCODE 58 /* QR Code */ | |
+#define BARCODE_CODE128B 60 /* Code 128 (Subset B) */ | |
+#define BARCODE_AUSPOST 63 /* Australia Post Standard Customer */ | |
+#define BARCODE_AUSREPLY 66 /* Australia Post Reply Paid */ | |
+#define BARCODE_AUSROUTE 67 /* Australia Post Routing */ | |
+#define BARCODE_AUSREDIRECT 68 /* Australia Post Redirection */ | |
+#define BARCODE_ISBNX 69 /* ISBN */ | |
+#define BARCODE_RM4SCC 70 /* Royal Mail 4-State Customer Code */ | |
+#define BARCODE_DATAMATRIX 71 /* Data Matrix (ECC200) */ | |
+#define BARCODE_EAN14 72 /* EAN-14 */ | |
+#define BARCODE_VIN 73 /* Vehicle Identification Number */ | |
+#define BARCODE_CODABLOCKF 74 /* Codablock-F */ | |
+#define BARCODE_NVE18 75 /* NVE-18 (SSCC-18) */ | |
+#define BARCODE_JAPANPOST 76 /* Japanese Postal Code */ | |
+#define BARCODE_KOREAPOST 77 /* Korea Post */ | |
+#define BARCODE_DBAR_STK 79 /* GS1 DataBar Stacked */ | |
+#define BARCODE_RSS14STACK 79 /* Legacy */ | |
+#define BARCODE_DBAR_OMNSTK 80 /* GS1 DataBar Stacked Omnidirectional */ | |
+#define BARCODE_RSS14STACK_OMNI 80 /* Legacy */ | |
+#define BARCODE_DBAR_EXPSTK 81 /* GS1 DataBar Expanded Stacked */ | |
+#define BARCODE_RSS_EXPSTACK 81 /* Legacy */ | |
+#define BARCODE_PLANET 82 /* USPS PLANET */ | |
+#define BARCODE_MICROPDF417 84 /* MicroPDF417 */ | |
+#define BARCODE_USPS_IMAIL 85 /* USPS Intelligent Mail (OneCode) */ | |
+#define BARCODE_ONECODE 85 /* Legacy */ | |
+#define BARCODE_PLESSEY 86 /* UK Plessey */ | |
+ | |
+ /* Tbarcode 8 codes */ | |
+#define BARCODE_TELEPEN_NUM 87 /* Telepen Numeric */ | |
+#define BARCODE_ITF14 89 /* ITF-14 */ | |
+#define BARCODE_KIX 90 /* Dutch Post KIX Code */ | |
+#define BARCODE_AZTEC 92 /* Aztec Code */ | |
+#define BARCODE_DAFT 93 /* DAFT Code */ | |
+#define BARCODE_DPD 96 /* DPD Code */ | |
+#define BARCODE_MICROQR 97 /* Micro QR Code */ | |
+ | |
+ /* Tbarcode 9 codes */ | |
+#define BARCODE_HIBC_128 98 /* HIBC (Health Industry Barcode) Code 128 */ | |
+#define BARCODE_HIBC_39 99 /* HIBC Code 39 */ | |
+#define BARCODE_HIBC_DM 102 /* HIBC Data Matrix */ | |
+#define BARCODE_HIBC_QR 104 /* HIBC QR Code */ | |
+#define BARCODE_HIBC_PDF 106 /* HIBC PDF417 */ | |
+#define BARCODE_HIBC_MICPDF 108 /* HIBC MicroPDF417 */ | |
+#define BARCODE_HIBC_BLOCKF 110 /* HIBC Codablock-F */ | |
+#define BARCODE_HIBC_AZTEC 112 /* HIBC Aztec Code */ | |
+ | |
+ /* Tbarcode 10 codes */ | |
+#define BARCODE_DOTCODE 115 /* DotCode */ | |
+#define BARCODE_HANXIN 116 /* Han Xin (Chinese Sensible) Code */ | |
+ | |
+ /* Tbarcode 11 codes */ | |
+#define BARCODE_MAILMARK 121 /* Royal Mail 4-State Mailmark */ | |
+ | |
+ /* Zint specific */ | |
+#define BARCODE_AZRUNE 128 /* Aztec Runes */ | |
+#define BARCODE_CODE32 129 /* Code 32 */ | |
+#define BARCODE_EANX_CC 130 /* EAN Composite */ | |
+#define BARCODE_GS1_128_CC 131 /* GS1-128 Composite */ | |
+#define BARCODE_EAN128_CC 131 /* Legacy */ | |
+#define BARCODE_DBAR_OMN_CC 132 /* GS1 DataBar Omnidirectional Composite */ | |
+#define BARCODE_RSS14_CC 132 /* Legacy */ | |
+#define BARCODE_DBAR_LTD_CC 133 /* GS1 DataBar Limited Composite */ | |
+#define BARCODE_RSS_LTD_CC 133 /* Legacy */ | |
+#define BARCODE_DBAR_EXP_CC 134 /* GS1 DataBar Expanded Composite */ | |
+#define BARCODE_RSS_EXP_CC 134 /* Legacy */ | |
+#define BARCODE_UPCA_CC 135 /* UPC-A Composite */ | |
+#define BARCODE_UPCE_CC 136 /* UPC-E Composite */ | |
+#define BARCODE_DBAR_STK_CC 137 /* GS1 DataBar Stacked Composite */ | |
+#define BARCODE_RSS14STACK_CC 137 /* Legacy */ | |
+#define BARCODE_DBAR_OMNSTK_CC 138 /* GS1 DataBar Stacked Omnidirectional Composite */ | |
+#define BARCODE_RSS14_OMNI_CC 138 /* Legacy */ | |
+#define BARCODE_DBAR_EXPSTK_CC 139 /* GS1 DataBar Expanded Stacked Composite */ | |
+#define BARCODE_RSS_EXPSTACK_CC 139 /* Legacy */ | |
+#define BARCODE_CHANNEL 140 /* Channel Code */ | |
+#define BARCODE_CODEONE 141 /* Code One */ | |
+#define BARCODE_GRIDMATRIX 142 /* Grid Matrix */ | |
+#define BARCODE_UPNQR 143 /* UPNQR (Univerzalnega Plačilnega Naloga QR) */ | |
+#define BARCODE_ULTRA 144 /* Ultracode */ | |
+#define BARCODE_RMQR 145 /* Rectangular Micro QR Code (rMQR) */ | |
+#define BARCODE_BC412 146 /* IBM BC412 (SEMI T1-95) */ | |
+#define BARCODE_LAST 146 /* Max barcode number marker, not barcode */ | |
+ | |
+/* Output options (`symbol->output_options`) */ | |
+#define BARCODE_NO_ASCII 0x0001 /* Legacy (no-op) */ | |
+#define BARCODE_BIND 0x0002 /* Boundary bars above & below the symbol and between stacked symbols */ | |
+#define BARCODE_BOX 0x0004 /* Box around symbol */ | |
+#define BARCODE_STDOUT 0x0008 /* Output to stdout */ | |
+#define READER_INIT 0x0010 /* Reader Initialisation (Programming) */ | |
+#define SMALL_TEXT 0x0020 /* Use smaller font */ | |
+#define BOLD_TEXT 0x0040 /* Use bold font */ | |
+#define CMYK_COLOUR 0x0080 /* CMYK colour space (Encapsulated PostScript and TIF) */ | |
+#define BARCODE_DOTTY_MODE 0x0100 /* Plot a matrix symbol using dots rather than squares */ | |
+#define GS1_GS_SEPARATOR 0x0200 /* Use GS instead of FNC1 as GS1 separator (Data Matrix) */ | |
+#define OUT_BUFFER_INTERMEDIATE 0x0400 /* Return ASCII values in bitmap buffer (OUT_BUFFER only) */ | |
+#define BARCODE_QUIET_ZONES 0x0800 /* Add compliant quiet zones (additional to any specified whitespace) */ | |
+ /* Note: CODE16K, CODE49, CODABLOCKF, ITF14, EAN/UPC have default quiet zones | |
+ */ | |
+#define BARCODE_NO_QUIET_ZONES 0x1000 /* Disable quiet zones, notably those with defaults as listed above */ | |
+#define COMPLIANT_HEIGHT 0x2000 /* Warn if height not compliant and use standard height (if any) as default */ | |
+ | |
+/* Input data types (`symbol->input_mode`) */ | |
+#define DATA_MODE 0 /* Binary */ | |
+#define UNICODE_MODE 1 /* UTF-8 */ | |
+#define GS1_MODE 2 /* GS1 */ | |
+/* The following may be OR-ed with above */ | |
+#define ESCAPE_MODE 0x0008 /* Process escape sequences */ | |
+#define GS1PARENS_MODE 0x0010 /* Process parentheses as GS1 AI delimiters (instead of square brackets) */ | |
+#define GS1NOCHECK_MODE 0x0020 /* Do not check validity of GS1 data (except that printable ASCII only) */ | |
+#define HEIGHTPERROW_MODE 0x0040 /* Interpret `height` as per-row rather than as overall height */ | |
+#define FAST_MODE 0x0080 /* Use faster if less optimal encodation for symbologies that support it */ | |
+ /* Note: only DATAMATRIX currently */ | |
+ | |
+/* Data Matrix specific options (`symbol->option_3`) */ | |
+#define DM_SQUARE 100 /* Only consider square versions on automatic symbol size selection */ | |
+#define DM_DMRE 101 /* Consider DMRE versions on automatic symbol size selection */ | |
+ | |
+/* QR, Han Xin, Grid Matrix specific options (`symbol->option_3`) */ | |
+#define ZINT_FULL_MULTIBYTE 200 /* Enable Kanji/Hanzi compression for Latin-1 & binary data */ | |
+ | |
+/* Ultracode specific option (`symbol->option_3`) */ | |
+#define ULTRA_COMPRESSION 128 /* Enable Ultracode compression (experimental) */ | |
+ | |
+/* Warning and error conditions (API return values) */ | |
+#define ZINT_WARN_INVALID_OPTION 2 /* Invalid option given but overridden by Zint */ | |
+#define ZINT_WARN_USES_ECI 3 /* Automatic ECI inserted by Zint */ | |
+#define ZINT_WARN_NONCOMPLIANT 4 /* Symbol created not compliant with standards */ | |
+#define ZINT_ERROR 5 /* Warn/error marker, not returned */ | |
+#define ZINT_ERROR_TOO_LONG 5 /* Input data wrong length */ | |
+#define ZINT_ERROR_INVALID_DATA 6 /* Input data incorrect */ | |
+#define ZINT_ERROR_INVALID_CHECK 7 /* Input check digit incorrect */ | |
+#define ZINT_ERROR_INVALID_OPTION 8 /* Incorrect option given */ | |
+#define ZINT_ERROR_ENCODING_PROBLEM 9 /* Internal error (should not happen) */ | |
+#define ZINT_ERROR_FILE_ACCESS 10 /* Error opening output file */ | |
+#define ZINT_ERROR_MEMORY 11 /* Memory allocation (malloc) failure */ | |
+#define ZINT_ERROR_FILE_WRITE 12 /* Error writing to output file */ | |
+#define ZINT_ERROR_USES_ECI 13 /* Error counterpart of warning if WARN_FAIL_ALL set (see below) */ | |
+#define ZINT_ERROR_NONCOMPLIANT 14 /* Error counterpart of warning if WARN_FAIL_ALL set */ | |
+ | |
+/* Warning warn (`symbol->warn_level`) */ | |
+#define WARN_DEFAULT 0 /* Default behaviour */ | |
+#define WARN_FAIL_ALL 2 /* Treat warning as error */ | |
+ | |
+/* Capability flags (ZBarcode_Cap() `cap_flag`) */ | |
+#define ZINT_CAP_HRT 0x0001 /* Prints Human Readable Text? */ | |
+#define ZINT_CAP_STACKABLE 0x0002 /* Is stackable? */ | |
+#define ZINT_CAP_EXTENDABLE 0x0004 /* Is extendable with add-on data? (Is EAN/UPC?) */ | |
+#define ZINT_CAP_COMPOSITE 0x0008 /* Can have composite data? */ | |
+#define ZINT_CAP_ECI 0x0010 /* Supports Extended Channel Interpretations? */ | |
+#define ZINT_CAP_GS1 0x0020 /* Supports GS1 data? */ | |
+#define ZINT_CAP_DOTTY 0x0040 /* Can be output as dots? */ | |
+#define ZINT_CAP_QUIET_ZONES 0x0080 /* Has default quiet zones? */ | |
+#define ZINT_CAP_FIXED_RATIO 0x0100 /* Has fixed width-to-height (aspect) ratio? */ | |
+#define ZINT_CAP_READER_INIT 0x0200 /* Supports Reader Initialisation? */ | |
+#define ZINT_CAP_FULL_MULTIBYTE 0x0400 /* Supports full-multibyte option? */ | |
+#define ZINT_CAP_MASK 0x0800 /* Is mask selectable? */ | |
+#define ZINT_CAP_STRUCTAPP 0x1000 /* Supports Structured Append? */ | |
+#define ZINT_CAP_COMPLIANT_HEIGHT 0x2000 /* Has compliant height? */ | |
+ | |
+/* The largest amount of data that can be encoded is 4350 4-byte UTF-8 chars in Han Xin Code */ | |
+#define ZINT_MAX_DATA_LEN 17400 | |
+/* Maximum number of segments allowed for (`seg_count`) */ | |
+#define ZINT_MAX_SEG_COUNT 256 | |
+ | |
+/* Debug flags (`symbol->debug`) */ | |
+#define ZINT_DEBUG_PRINT 0x0001 /* Print debug info (if any) to stdout */ | |
+#define ZINT_DEBUG_TEST 0x0002 /* For internal test use only */ | |
+ | |
+#ifdef _WIN32 | |
+# if defined(DLL_EXPORT) || defined(PIC) || defined(_USRDLL) | |
+# define ZINT_EXTERN __declspec(dllexport) | |
+# elif defined(ZINT_DLL) | |
+# define ZINT_EXTERN __declspec(dllimport) | |
+# else | |
+# define ZINT_EXTERN extern | |
+# endif | |
+#else | |
+# define ZINT_EXTERN extern | |
+#endif | |
+ | |
+ /* Create and initialize a symbol structure */ | |
+ ZINT_EXTERN struct zint_symbol *ZBarcode_Create(void); | |
+ | |
+ /* Free any output buffers that may have been created and initialize output fields */ | |
+ ZINT_EXTERN void ZBarcode_Clear(struct zint_symbol *symbol); | |
+ | |
+ /* Free a symbol structure, including any output buffers */ | |
+ ZINT_EXTERN void ZBarcode_Delete(struct zint_symbol *symbol); | |
+ | |
+ | |
+ /* Encode a barcode. If `length` is 0, `source` must be NUL-terminated */ | |
+ ZINT_EXTERN int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int length); | |
+ | |
+ /* Encode a barcode with multiple ECI segments */ | |
+ ZINT_EXTERN int ZBarcode_Encode_Segs(struct zint_symbol *symbol, const struct zint_seg segs[], | |
+ const int seg_count); | |
+ | |
+ /* Encode a barcode using input data from file `filename` */ | |
+ ZINT_EXTERN int ZBarcode_Encode_File(struct zint_symbol *symbol, const char *filename); | |
+ | |
+ /* Output a previously encoded symbol to file `symbol->outfile` */ | |
+ ZINT_EXTERN int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle); | |
+ | |
+ | |
+ /* Encode and output a symbol to file `symbol->outfile` */ | |
+ ZINT_EXTERN int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, const unsigned char *source, int length, | |
+ int rotate_angle); | |
+ | |
+ /* Encode a symbol with multiple ECI segments and output to file `symbol->outfile` */ | |
+ ZINT_EXTERN int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol, const struct zint_seg segs[], | |
+ const int seg_count, int rotate_angle); | |
+ | |
+ /* Encode a symbol using input data from file `filename` and output to file `symbol->outfile` */ | |
+ ZINT_EXTERN int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, const char *filename, | |
+ int rotate_angle); | |
+ | |
+ /* Plot to gLabels - backported from 2.6.7 by brozkeff 2022-11-25 */ | |
+ ZINT_EXTERN int ZBarcode_Render(struct zint_symbol *symbol, const float width, const float height); | |
+ | |
+ /* Output a previously encoded symbol to memory as raster (`symbol->bitmap`) */ | |
+ ZINT_EXTERN int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle); | |
+ | |
+ /* Encode and output a symbol to memory as raster (`symbol->bitmap`) */ | |
+ ZINT_EXTERN int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, const unsigned char *source, int length, | |
+ int rotate_angle); | |
+ | |
+ /* Encode a symbol with multiple ECI segments and output to memory as raster (`symbol->bitmap`) */ | |
+ ZINT_EXTERN int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol, const struct zint_seg segs[], | |
+ const int seg_count, int rotate_angle); | |
+ | |
+ /* Encode a symbol using input data from file `filename` and output to memory as raster (`symbol->bitmap`) */ | |
+ ZINT_EXTERN int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, const char *filename, | |
+ int rotate_angle); | |
+ | |
+ | |
+ /* Output a previously encoded symbol to memory as vector (`symbol->vector`) */ | |
+ ZINT_EXTERN int ZBarcode_Buffer_Vector(struct zint_symbol *symbol, int rotate_angle); | |
+ | |
+ /* Encode and output a symbol to memory as vector (`symbol->vector`) */ | |
+ ZINT_EXTERN int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol, const unsigned char *source, | |
+ int length, int rotate_angle); | |
+ | |
+ /* Encode a symbol with multiple ECI segments and output to memory as vector (`symbol->vector`) */ | |
+ ZINT_EXTERN int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol, const struct zint_seg segs[], | |
+ const int seg_count, int rotate_angle); | |
+ | |
+ /* Encode a symbol using input data from file `filename` and output to memory as vector (`symbol->vector`) */ | |
+ ZINT_EXTERN int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol, const char *filename, | |
+ int rotate_angle); | |
+ | |
+ | |
+ /* Is `symbol_id` a recognized symbology? */ | |
+ ZINT_EXTERN int ZBarcode_ValidID(int symbol_id); | |
+ | |
+ /* Copy BARCODE_XXX name of `symbol_id` into `name` buffer, NUL-terminated. | |
+ Returns 0 if valid, non-zero (1 or -1) if not valid */ | |
+ ZINT_EXTERN int ZBarcode_BarcodeName(int symbol_id, char name[32]); | |
+ | |
+ /* Return the capability flags for symbology `symbol_id` that match `cap_flag` */ | |
+ ZINT_EXTERN unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag); | |
+ | |
+ /* Return the version of Zint linked to */ | |
+ ZINT_EXTERN int ZBarcode_Version(void); | |
+ | |
+#ifdef __cplusplus | |
+} | |
+#endif /* __cplusplus */ | |
+ | |
+/* vim: set ts=4 sw=4 et : */ | |
+#endif /* ZINT_H */ | |
-- | |
2.17.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment