From 98f86727cc73a02dba48aa27b49a76ead68b922c Mon Sep 17 00:00:00 2001 From: gitlost Date: Wed, 27 Dec 2023 19:20:19 +0000 Subject: [PATCH] Add `BARCODE_MEMORY_FILE` to `symbol->output_options` to allow outputting to in-memory buffer `symbol->memfile` instead of to file `symbol->outfile`, ticket #301 Add "README.clang-tidy" and ".clang-tidy" options file Suppress some warnings --- .clang-tidy | 3 + ChangeLog | 6 +- README.clang-tidy | 21 + backend/CMakeLists.txt | 2 +- backend/Makefile.mingw | 2 +- backend/bmp.c | 65 +- backend/common.c | 8 + backend/common.h | 24 +- backend/emf.c | 106 ++-- backend/filemem.c | 464 ++++++++++++++ backend/filemem.h | 95 +++ backend/gif.c | 77 +-- backend/library.c | 13 +- backend/output.c | 30 - backend/output.h | 3 - backend/pcx.c | 56 +- backend/png.c | 88 ++- backend/ps.c | 228 ++++--- backend/qr.c | 6 +- backend/raster.c | 17 +- backend/svg.c | 215 ++++--- backend/tests/CMakeLists.txt | 1 + backend/tests/test_bmp.c | 20 +- backend/tests/test_codablock.c | 2 +- backend/tests/test_emf.c | 20 +- backend/tests/test_filemem.c | 477 +++++++++++++++ backend/tests/test_gif.c | 20 +- backend/tests/test_output.c | 78 --- backend/tests/test_pcx.c | 20 +- backend/tests/test_pdf417.c | 10 +- backend/tests/test_png.c | 20 +- backend/tests/test_ps.c | 25 +- backend/tests/test_svg.c | 25 +- backend/tests/test_tif.c | 20 +- backend/tests/testcommon.c | 69 +++ backend/tests/testcommon.h | 4 +- backend/tests/tools/bwipp_dump.ps.tar.xz | Bin 133956 -> 134068 bytes backend/tif.c | 111 ++-- backend/tif_lzw.h | 24 +- backend/vector.c | 8 +- backend/zint.h | 35 +- backend_qt/backend_qt.pro | 2 + backend_qt/backend_vc8.pro | 2 + backend_tcl/configure | 1 + backend_tcl/configure.ac | 1 + backend_tcl/zint_tcl.dsp | 4 + docs/manual.html | 639 +++++++++++--------- docs/manual.pmd | 121 ++-- docs/manual.txt | 139 +++-- frontend/main.c | 12 +- tools/update_version.php | 4 +- win32/libzint.vcxproj | 2 + win32/vs2008/libzint.vcproj | 94 +-- win32/vs2008/zint.sln | 29 + win32/vs2008/zint.vcproj | 91 +-- win32/vs2015/libzint.vcxproj | 2 + win32/vs2017/libzint.vcxproj | 2 + win32/vs2019/libzint.vcxproj | 2 + win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp | 4 + 59 files changed, 2407 insertions(+), 1262 deletions(-) create mode 100644 .clang-tidy create mode 100644 README.clang-tidy create mode 100644 backend/filemem.c create mode 100644 backend/filemem.h create mode 100644 backend/tests/test_filemem.c create mode 100644 win32/vs2008/zint.sln diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..d41bac60 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,3 @@ +--- +Checks: 'clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-clang-analyzer-security.insecureAPI.strcpy' +HeaderFilterRegex: '.*' diff --git a/ChangeLog b/ChangeLog index 6ee80ec8..c044ce07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,12 +3,16 @@ Version 2.13.0.9 (dev) not released yet **Incompatible changes** ------------------------ -None so far +- New `memfile` & `memfile_size` fields in `symbol` for use with new output + option `BARCODE_MEMORY_FILE` Changes ------- - BMP: lessen heap memory usage by only `malloc()`ing a row - GIF: lessen heap memory usage by paging; use standard colour char map +- Add `BARCODE_MEMORY_FILE` to `symbol->output_options` to allow outputting to + in-memory buffer `symbol->memfile` instead of to file `symbol->outfile`, + ticket #301 Bugs ---- diff --git a/README.clang-tidy b/README.clang-tidy new file mode 100644 index 00000000..23eeee0d --- /dev/null +++ b/README.clang-tidy @@ -0,0 +1,21 @@ +Current as of latest clang-tidy-18 from Ubuntu 22.04 apt package (2023-12-26) + +Requires cmake in "build" sub-directory with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON (for "build/compile_commands.json") +and -DCMAKE_BUILD_TYPE=Debug (so `assert()`s defined), and then make (for Qt generated includes). + +In project root directory (warning, slow): + +clang-tidy-18 backend/*.c frontend/*.c backend_qt/*.cpp frontend_qt/*.cpp -p build/compile_commands.json + +For "backend_tcl", which has no "compile_commands.json", specify the tcl include directory, e.g. + +clang-tidy-18 backend_tcl/*.c -- -I/usr/include/tcl8.6 + +Options are in ".clang-tidy" (in the project root directory). The excluded checks are +`clang-analyzer-security.insecureAPI.strcpy` (for `strcpy()`, `strcat()` etc), and +`clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling` (for `sprintf()`). + +The test suite (cmake given -DZINT_TEST=ON) can also be analysed with an additional check disabled: + +clang-tidy-18 backend/tests/*.c frontend/tests/*.c backend_qt/tests/*.cpp \ + -checks='-clang-analyzer-optin.performance.Padding' -p build/compile_commands.json diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index 7ab2b365..edf83d54 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -8,7 +8,7 @@ if(ZINT_USE_PNG) find_package(PNG) endif() -set(zint_COMMON_SRCS common.c library.c large.c reedsol.c gs1.c eci.c general_field.c) +set(zint_COMMON_SRCS common.c library.c large.c reedsol.c gs1.c eci.c filemem.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) diff --git a/backend/Makefile.mingw b/backend/Makefile.mingw index 8aa750c1..905b0749 100644 --- a/backend/Makefile.mingw +++ b/backend/Makefile.mingw @@ -24,7 +24,7 @@ APP:=zint DLL:=$(APP).dll STATLIB:=lib$(APP).a -COMMON_OBJ:= common.o library.o large.o reedsol.o gs1.o eci.o general_field.o sjis.o gb2312.o gb18030.o +COMMON_OBJ:= common.o library.o large.o reedsol.o gs1.o eci.o filemem.o general_field.o sjis.o gb2312.o gb18030.o ONEDIM_OBJ:= code.o code128.o 2of5.o upcean.o telepen.o medical.o plessey.o rss.o POSTAL_OBJ:= postal.o auspost.o imail.o mailmark.o TWODIM_OBJ:= code16k.o codablock.o dmatrix.o pdf417.o qr.o maxicode.o composite.o aztec.o code49.o code1.o gridmtx.o hanxin.o dotcode.o ultra.o diff --git a/backend/bmp.c b/backend/bmp.c index 4f0271e4..ef4e616d 100644 --- a/backend/bmp.c +++ b/backend/bmp.c @@ -33,11 +33,8 @@ #include #include #include -#ifdef _MSC_VER -#include -#include -#endif #include "common.h" +#include "filemem.h" #include "output.h" #include "bmp.h" /* Bitmap header structure */ @@ -47,7 +44,8 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix int colour_count; int resolution; size_t row_size, data_offset, file_size; - FILE *bmp_file; + struct filemem fm; + struct filemem *const fmp = &fm; bitmap_file_header_t file_header; bitmap_info_header_t info_header; color_ref_t bg; @@ -55,7 +53,6 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix color_ref_t palette[8]; int ultra_fg_index = 9; unsigned char map[128]; - const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; /* Suppress gcc -fanalyzer warning */ unsigned char *rowbuf; (void) out_colour_get_rgb(symbol->fgcolour, &fg.red, &fg.green, &fg.blue, NULL /*alpha*/); @@ -119,36 +116,25 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix info_header.important_colours = colour_count; /* Open output file in binary mode */ - if (output_to_stdout) { -#ifdef _MSC_VER - if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - sprintf(symbol->errtxt, "600: Could not set stdout to binary (%d: %.30s)", errno, strerror(errno)); - free(rowbuf); - return ZINT_ERROR_FILE_ACCESS; - } -#endif - bmp_file = stdout; - } else { - if (!(bmp_file = out_fopen(symbol->outfile, "wb"))) { - sprintf(symbol->errtxt, "601: Could not open output file (%d: %.30s)", errno, strerror(errno)); - free(rowbuf); - return ZINT_ERROR_FILE_ACCESS; - } + if (!fm_open(fmp, symbol, "wb")) { + sprintf(symbol->errtxt, "601: Could not open output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + free(rowbuf); + return ZINT_ERROR_FILE_ACCESS; } - fwrite(&file_header, sizeof(bitmap_file_header_t), 1, bmp_file); - fwrite(&info_header, sizeof(bitmap_info_header_t), 1, bmp_file); + fm_write(&file_header, sizeof(bitmap_file_header_t), 1, fmp); + fm_write(&info_header, sizeof(bitmap_info_header_t), 1, fmp); - fwrite(&bg, sizeof(color_ref_t), 1, bmp_file); + fm_write(&bg, sizeof(color_ref_t), 1, fmp); if (bits_per_pixel == 4) { for (i = 0; i < 8; i++) { - fwrite(&palette[i], sizeof(color_ref_t), 1, bmp_file); + fm_write(&palette[i], sizeof(color_ref_t), 1, fmp); } if (ultra_fg_index == 9) { - fwrite(&fg, sizeof(color_ref_t), 1, bmp_file); + fm_write(&fg, sizeof(color_ref_t), 1, fmp); } } else { - fwrite(&fg, sizeof(color_ref_t), 1, bmp_file); + fm_write(&fg, sizeof(color_ref_t), 1, fmp); } /* Pixel Plotting */ @@ -159,7 +145,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix for (column = 0; column < symbol->bitmap_width; column++) { rowbuf[column >> 1] |= map[pb[column]] << (!(column & 1) << 2); } - fwrite(rowbuf, 1, row_size, bmp_file); + fm_write(rowbuf, 1, row_size, fmp); } } else { /* bits_per_pixel == 1 */ for (row = 0; row < symbol->bitmap_height; row++) { @@ -168,29 +154,20 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix for (column = 0; column < symbol->bitmap_width; column++) { rowbuf[column >> 3] |= map[pb[column]] >> (column & 7); } - fwrite(rowbuf, 1, row_size, bmp_file); + fm_write(rowbuf, 1, row_size, fmp); } } free(rowbuf); - if (ferror(bmp_file)) { - sprintf(symbol->errtxt, "603: Incomplete write to output (%d: %.30s)", errno, strerror(errno)); - if (!output_to_stdout) { - (void) fclose(bmp_file); - } + if (fm_error(fmp)) { + sprintf(symbol->errtxt, "603: Incomplete write to output (%d: %.30s)", fmp->err, strerror(fmp->err)); + (void) fm_close(fmp, symbol); return ZINT_ERROR_FILE_WRITE; } - if (output_to_stdout) { - if (fflush(bmp_file) != 0) { - sprintf(symbol->errtxt, "604: Incomplete flush to output (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } - } else { - if (fclose(bmp_file) != 0) { - sprintf(symbol->errtxt, "605: Failure on closing output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } + if (!fm_close(fmp, symbol)) { + sprintf(symbol->errtxt, "605: Failure on closing output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_WRITE; } return 0; diff --git a/backend/common.c b/backend/common.c index cb6eab48..4bf6b981 100644 --- a/backend/common.c +++ b/backend/common.c @@ -606,6 +606,11 @@ INTERNAL char *debug_print_escape(const unsigned char *source, const int first_l } #ifdef ZINT_TEST +/* Suppress gcc warning null destination pointer [-Wformat-overflow=] false-positive */ +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-overflow=" +#endif /* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */ INTERNAL void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length) { int i, max = length, cnt_len = 0; @@ -655,6 +660,9 @@ INTERNAL void debug_test_codeword_dump_int(struct zint_symbol *symbol, const int } symbol->errtxt[strlen(symbol->errtxt) - 1] = '\0'; /* Zap last space */ } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop #endif +#endif /*ZINT_TEST*/ /* vim: set ts=4 sw=4 et : */ diff --git a/backend/common.h b/backend/common.h index c10d4efd..83a280e4 100644 --- a/backend/common.h +++ b/backend/common.h @@ -41,21 +41,37 @@ extern "C" { #define ARRAY_SIZE(x) ((int) (sizeof(x) / sizeof((x)[0]))) #endif -/* Determine if C89 (excluding MSVC, which doesn't define __STDC_VERSION__) */ -#if !defined(_MSC_VER) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199000L) -#define ZINT_IS_C89 +/* Determine if C89 or C99 (excluding MSVC, which doesn't define __STDC_VERSION__) */ +#ifndef _MSC_VER +# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199000L +# define ZINT_IS_C89 +# elif __STDC_VERSION__ <= 199901L /* Actually includes pseudo-standards "C94/C95" as well */ +# define ZINT_IS_C99 +# endif #endif #ifdef _MSC_VER # include # define z_alloca(nmemb) _alloca(nmemb) #else -# if defined(ZINT_IS_C89) || defined(__NuttX__) /* C89 or NuttX RTOS */ +# if defined(ZINT_IS_C89) || defined(ZINT_IS_C99) || defined(__NuttX__) /* C89 or C99 or NuttX RTOS */ # include # endif # define z_alloca(nmemb) alloca(nmemb) #endif +#ifdef _MSC_VER +# if _MSC_VER >= 1400 /* MSVC 2005 (C++ 8.0) */ +# define restrict __restrict +# else +# define restrict +# endif +#else +# ifdef ZINT_IS_C89 +# define restrict +# endif +#endif + #ifdef _MSC_VER typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; diff --git a/backend/emf.c b/backend/emf.c index 8dfe36c9..3551c6af 100644 --- a/backend/emf.c +++ b/backend/emf.c @@ -37,11 +37,8 @@ #include #include #include -#ifdef _MSC_VER -#include -#include -#endif #include "common.h" +#include "filemem.h" #include "output.h" #include "emf.h" @@ -164,7 +161,8 @@ static int emf_utfle_length(const unsigned char *input, const int length) { INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { int i; - FILE *emf_file; + struct filemem fm; + struct filemem *const fmp = &fm; unsigned char fgred, fggrn, fgblu, bgred, bggrn, bgblu, bgalpha; int error_number = 0; int rectangle_count, this_rectangle; @@ -191,7 +189,6 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { int draw_background = 1; int bold; const int upcean = is_upcean(symbol->symbology); - const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; struct zint_vector_rect *rect; struct zint_vector_circle *circ; @@ -703,66 +700,56 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { emr_header.emf_header.records = recordcount; /* Send EMF data to file */ - if (output_to_stdout) { -#ifdef _MSC_VER - if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - sprintf(symbol->errtxt, "642: Could not set stdout to binary (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } -#endif - emf_file = stdout; - } else { - if (!(emf_file = out_fopen(symbol->outfile, "wb"))) { - sprintf(symbol->errtxt, "640: Could not open output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } + if (!fm_open(fmp, symbol, "wb")) { + sprintf(symbol->errtxt, "640: Could not open output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_ACCESS; } - fwrite(&emr_header, sizeof(emr_header_t), 1, emf_file); + fm_write(&emr_header, sizeof(emr_header_t), 1, fmp); - fwrite(&emr_mapmode, sizeof(emr_mapmode_t), 1, emf_file); + fm_write(&emr_mapmode, sizeof(emr_mapmode_t), 1, fmp); if (rotate_angle) { - fwrite(&emr_setworldtransform, sizeof(emr_setworldtransform_t), 1, emf_file); + fm_write(&emr_setworldtransform, sizeof(emr_setworldtransform_t), 1, fmp); } - fwrite(&emr_createbrushindirect_bg, sizeof(emr_createbrushindirect_t), 1, emf_file); + fm_write(&emr_createbrushindirect_bg, sizeof(emr_createbrushindirect_t), 1, fmp); if (symbol->symbology == BARCODE_ULTRA) { for (i = 0; i < 9; i++) { if (rectangle_bycolour[i]) { - fwrite(&emr_createbrushindirect_colour[i], sizeof(emr_createbrushindirect_t), 1, emf_file); + fm_write(&emr_createbrushindirect_colour[i], sizeof(emr_createbrushindirect_t), 1, fmp); } } } else { - fwrite(&emr_createbrushindirect_fg, sizeof(emr_createbrushindirect_t), 1, emf_file); + fm_write(&emr_createbrushindirect_fg, sizeof(emr_createbrushindirect_t), 1, fmp); } - fwrite(&emr_createpen, sizeof(emr_createpen_t), 1, emf_file); + fm_write(&emr_createpen, sizeof(emr_createpen_t), 1, fmp); if (symbol->vector->strings) { - fwrite(&emr_extcreatefontindirectw, sizeof(emr_extcreatefontindirectw_t), 1, emf_file); + fm_write(&emr_extcreatefontindirectw, sizeof(emr_extcreatefontindirectw_t), 1, fmp); if (fsize2) { - fwrite(&emr_extcreatefontindirectw2, sizeof(emr_extcreatefontindirectw_t), 1, emf_file); + fm_write(&emr_extcreatefontindirectw2, sizeof(emr_extcreatefontindirectw_t), 1, fmp); } } - fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); - fwrite(&emr_selectobject_pen, sizeof(emr_selectobject_t), 1, emf_file); + fm_write(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, fmp); + fm_write(&emr_selectobject_pen, sizeof(emr_selectobject_t), 1, fmp); if (draw_background) { - fwrite(&background, sizeof(emr_rectangle_t), 1, emf_file); + fm_write(&background, sizeof(emr_rectangle_t), 1, fmp); } if (symbol->symbology == BARCODE_ULTRA) { for (i = 0; i < 9; i++) { if (rectangle_bycolour[i]) { - fwrite(&emr_selectobject_colour[i], sizeof(emr_selectobject_t), 1, emf_file); + fm_write(&emr_selectobject_colour[i], sizeof(emr_selectobject_t), 1, fmp); rect = symbol->vector->rectangles; this_rectangle = 0; while (rect) { if ((i == 0 && rect->colour == -1) || rect->colour == i) { - fwrite(&rectangle[this_rectangle], sizeof(emr_rectangle_t), 1, emf_file); + fm_write(&rectangle[this_rectangle], sizeof(emr_rectangle_t), 1, fmp); } this_rectangle++; rect = rect->next; @@ -770,42 +757,42 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { } } } else { - fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fm_write(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, fmp); /* Rectangles */ for (i = 0; i < rectangle_count; i++) { - fwrite(&rectangle[i], sizeof(emr_rectangle_t), 1, emf_file); + fm_write(&rectangle[i], sizeof(emr_rectangle_t), 1, fmp); } } /* Hexagons */ for (i = 0; i < hexagon_count; i++) { - fwrite(&hexagon[i], sizeof(emr_polygon_t), 1, emf_file); + fm_write(&hexagon[i], sizeof(emr_polygon_t), 1, fmp); } /* Circles */ if (symbol->symbology == BARCODE_MAXICODE) { /* Bullseye needed */ for (i = 0; i < circle_count; i++) { - fwrite(&circle[i], sizeof(emr_ellipse_t), 1, emf_file); + fm_write(&circle[i], sizeof(emr_ellipse_t), 1, fmp); if (i < circle_count - 1) { if (i % 2) { - fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fm_write(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, fmp); } else { - fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fm_write(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, fmp); } } } } else { for (i = 0; i < circle_count; i++) { - fwrite(&circle[i], sizeof(emr_ellipse_t), 1, emf_file); + fm_write(&circle[i], sizeof(emr_ellipse_t), 1, fmp); } } /* Text */ if (string_count > 0) { - fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); - fwrite(&emr_settextcolor, sizeof(emr_settextcolor_t), 1, emf_file); + fm_write(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, fmp); + fm_write(&emr_settextcolor, sizeof(emr_settextcolor_t), 1, fmp); } current_fsize = fsize; @@ -813,43 +800,34 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { for (i = 0; i < string_count; i++) { if (text_fsizes[i] != current_fsize) { current_fsize = text_fsizes[i]; - fwrite(&emr_selectobject_font2, sizeof(emr_selectobject_t), 1, emf_file); + fm_write(&emr_selectobject_font2, sizeof(emr_selectobject_t), 1, fmp); } if (text_haligns[i] != current_halign) { current_halign = text_haligns[i]; if (current_halign == 0) { - fwrite(&emr_settextalign_centre, sizeof(emr_settextalign_t), 1, emf_file); + fm_write(&emr_settextalign_centre, sizeof(emr_settextalign_t), 1, fmp); } else if (current_halign == 1) { - fwrite(&emr_settextalign_left, sizeof(emr_settextalign_t), 1, emf_file); + fm_write(&emr_settextalign_left, sizeof(emr_settextalign_t), 1, fmp); } else { - fwrite(&emr_settextalign_right, sizeof(emr_settextalign_t), 1, emf_file); + fm_write(&emr_settextalign_right, sizeof(emr_settextalign_t), 1, fmp); } } - fwrite(&text[i], sizeof(emr_exttextoutw_t), 1, emf_file); - fwrite(this_string[i], emf_bump_up(text[i].w_emr_text.chars), 1, emf_file); + fm_write(&text[i], sizeof(emr_exttextoutw_t), 1, fmp); + fm_write(this_string[i], emf_bump_up(text[i].w_emr_text.chars), 1, fmp); free(this_string[i]); } - fwrite(&emr_eof, sizeof(emr_eof_t), 1, emf_file); + fm_write(&emr_eof, sizeof(emr_eof_t), 1, fmp); - if (ferror(emf_file)) { - sprintf(symbol->errtxt, "644: Incomplete write to output (%d: %.30s)", errno, strerror(errno)); - if (!output_to_stdout) { - (void) fclose(emf_file); - } + if (fm_error(fmp)) { + sprintf(symbol->errtxt, "644: Incomplete write to output (%d: %.30s)", fmp->err, strerror(fmp->err)); + (void) fm_close(fmp, symbol); return ZINT_ERROR_FILE_WRITE; } - if (output_to_stdout) { - if (fflush(emf_file) != 0) { - sprintf(symbol->errtxt, "940: Incomplete flush to output (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } - } else { - if (fclose(emf_file) != 0) { - sprintf(symbol->errtxt, "941: Failure on closing output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } + if (!fm_close(fmp, symbol)) { + sprintf(symbol->errtxt, "941: Failure on closing output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_WRITE; } return error_number; } diff --git a/backend/filemem.c b/backend/filemem.c new file mode 100644 index 00000000..c6e2175a --- /dev/null +++ b/backend/filemem.c @@ -0,0 +1,464 @@ +/* filemem.c - write to file/memory abstraction */ +/* + libzint - the open source barcode library + Copyright (C) 2023 Robin Stuart + + 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 +#include +#include +#include +#ifdef _MSC_VER +#include +#include +#endif + +#include "filemem.h" +#include "output.h" + +#define FM_PAGE_SIZE 0x8000 /* 32k */ + +#ifndef EOVERFLOW +#define EOVERFLOW EINVAL +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1800 /* `va_copy()` not before MSVC 2013 (C++ 12.0) */ +# define va_copy(dest, src) (dest = src) +#else +# if defined(ZINT_IS_C89) && !defined(va_copy) +# ifdef __GNUC__ +# define va_copy __va_copy /* Available with clang as well */ +# else +# define va_copy(dest, src) (dest = src) /* Will fail if array (need `*dest = *src`) or something else */ +# endif +# endif +#endif + +/* Helper to set `err` only if not already set, returning 0 always for convenience */ +static int fm_seterr(struct filemem *restrict const fmp, const int err) { + if (fmp->err == 0) { + fmp->err = err; + } + return 0; +} + +/* Helper to set position, syncing end marker */ +static void fm_setpos(struct filemem *restrict const fmp, const size_t pos) { + assert(pos <= fmp->memsize); + fmp->mempos = pos; + if (fmp->mempos > fmp->memend) { + fmp->memend = fmp->mempos; + } +} + +/* Helper to clear memory buffer and associates */ +static void fm_clear_mem(struct filemem *restrict const fmp) { + if (fmp->mem) { + free(fmp->mem); + fmp->mem = NULL; + } + fmp->memsize = fmp->mempos = fmp->memend = 0; +#ifdef FM_NO_VSNPRINTF + if (fmp->fp_null) { + (void) fclose(fmp->fp_null); + fmp->fp_null = NULL; + } +#endif +} + +/* `fopen()` if file, setup memory buffer if BARCODE_MEMORY_FILE, returning 1 on success, 0 on failure */ +INTERNAL int fm_open(struct filemem *restrict const fmp, struct zint_symbol *symbol, const char *mode) { + assert(fmp && symbol && mode); + fmp->fp = NULL; + fmp->mem = NULL; + fmp->memsize = fmp->mempos = fmp->memend = 0; + fmp->flags = symbol->output_options & (BARCODE_STDOUT | BARCODE_MEMORY_FILE); + fmp->err = 0; +#ifdef FM_NO_VSNPRINTF + fmp->fp_null = NULL; +#endif + + if (fmp->flags & BARCODE_MEMORY_FILE) { + if (!(fmp->mem = (unsigned char *) malloc(FM_PAGE_SIZE))) { + return fm_seterr(fmp, ENOMEM); + } + fmp->memsize = FM_PAGE_SIZE; + if (symbol->memfile) { + free(symbol->memfile); + symbol->memfile = NULL; + } + symbol->memfile_size = 0; + return 1; + } + if (fmp->flags & BARCODE_STDOUT) { +#ifdef _MSC_VER + if (strchr(mode, 'b') != NULL && _setmode(_fileno(stdout), _O_BINARY) == -1) { + return fm_seterr(fmp, errno); + } +#endif + fmp->fp = stdout; + return 1; + } + if (!(fmp->fp = out_fopen(symbol->outfile, mode))) { + return fm_seterr(fmp, errno); + } + return 1; +} + +/* Expand memory buffer, returning 1 on success, 0 on failure */ +static int fm_mem_expand(struct filemem *restrict const fmp, const size_t size) { + unsigned char *new_mem; + size_t new_size; + + assert(fmp); + if (!fmp->mem) { + return fm_seterr(fmp, EINVAL); + } + if (size == 0) { + return 1; + } + if (fmp->mempos + size < fmp->memsize) { /* Fits? */ + if (fmp->mempos + size <= fmp->mempos) { /* Check for overflow */ + fm_clear_mem(fmp); + return fm_seterr(fmp, EOVERFLOW); + } + return 1; + } + new_size = fmp->memsize + (size < FM_PAGE_SIZE ? FM_PAGE_SIZE : size); + if (new_size <= fmp->memsize) { /* Check for overflow */ + fm_clear_mem(fmp); + return fm_seterr(fmp, EOVERFLOW); + } + /* Protect against very large files & (Linux) OOM killer - cf `raster_malloc()` in "raster.c" */ + if (new_size > 0x40000000 /*1GB*/ || !(new_mem = (unsigned char *) realloc(fmp->mem, new_size))) { + fm_clear_mem(fmp); + return fm_seterr(fmp, new_size > 0x40000000 ? EINVAL : ENOMEM); + } + fmp->mem = new_mem; + fmp->memsize = new_size; + return 1; +} + +/* `fwrite()` to file or memory, returning 1 on success, 0 on failure */ +INTERNAL int fm_write(const void *restrict ptr, const size_t size, const size_t nitems, + struct filemem *restrict const fmp) { + assert(fmp && ptr); + if (fmp->err) { + return 0; + } + if (size == 0 || nitems == 0) { + return 1; + } + if (fmp->flags & BARCODE_MEMORY_FILE) { + const size_t tot_size = size * nitems; + if (tot_size / size != nitems) { + return fm_seterr(fmp, EOVERFLOW); + } + if (!fm_mem_expand(fmp, tot_size)) { + return 0; + } + memcpy(fmp->mem + fmp->mempos, ptr, tot_size); + fm_setpos(fmp, fmp->mempos + tot_size); + return 1; + } + if (fwrite(ptr, size, nitems, fmp->fp) == 0) { + return fm_seterr(fmp, errno); + } + return 1; +} + +/* `fputc()` to file or memory, returning 1 on success, 0 on failure */ +INTERNAL int fm_putc(const int ch, struct filemem *restrict const fmp) { + assert(fmp); + if (fmp->err) { + return 0; + } + if (fmp->flags & BARCODE_MEMORY_FILE) { + if (!fm_mem_expand(fmp, 1)) { + return 0; + } + fmp->mem[fmp->mempos] = (unsigned char) ch; + fm_setpos(fmp, fmp->mempos + 1); + return 1; + } + if (fputc(ch, fmp->fp) == EOF) { + return fm_seterr(fmp, errno); + } + return 1; +} + +/* `fputs()` to file or memory, returning 1 on success, 0 on failure */ +INTERNAL int fm_puts(const char *str, struct filemem *restrict const fmp) { + assert(fmp); + if (fmp->err) { + return 0; + } + if (fmp->flags & BARCODE_MEMORY_FILE) { + const size_t len = strlen(str); + if (!fm_mem_expand(fmp, len)) { + return 0; + } + memcpy(fmp->mem + fmp->mempos, str, len); + fm_setpos(fmp, fmp->mempos + len); + return 1; + } + if (fputs(str, fmp->fp) == EOF) { + return fm_seterr(fmp, errno); + } + return 1; +} + +#ifdef FM_NO_VSNPRINTF +# ifdef _WIN32 +# define DEV_NULL "NUL" +# else +# define DEV_NULL "/dev/null" +# endif +#endif + +/* Helper to `printf()` into mem buffer */ +static int fm_vprintf(struct filemem *restrict const fmp, const char *fmt, va_list ap) { + va_list cpy; + int size, check; + + /* Adapted from https://stackoverflow.com/a/52558247/664741 */ +#ifdef FM_NO_VSNPRINTF + if (!fmp->fp_null && !(fmp->fp_null = fopen(DEV_NULL, "wb"))) { + return fm_seterr(fmp, errno); + } +#endif + + va_copy(cpy, ap); + /* The clang-tidy warning is a bug https://github.com/llvm/llvm-project/issues/40656 */ +#ifdef FM_NO_VSNPRINTF + size = vfprintf(fmp->fp_null, fmt, cpy); /* NOLINT(clang-analyzer-valist.Uninitialized) */ +#else + size = vsnprintf(NULL, 0, fmt, cpy); /* NOLINT(clang-analyzer-valist.Uninitialized) */ +#endif + va_end(cpy); + + if (size < 0) { + return fm_seterr(fmp, errno); + } + + if (!fm_mem_expand(fmp, size + 1)) { + return 0; + } + +#ifdef FM_NO_VSNPRINTF + /* NOLINTNEXTLINE(clang-analyzer-valist.Uninitialized) - see above */ + check = vsprintf((char *) fmp->mem + fmp->mempos, fmt, ap); +#else + /* NOLINTNEXTLINE(clang-analyzer-valist.Uninitialized) - see above */ + check = vsnprintf((char *) fmp->mem + fmp->mempos, size + 1, fmt, ap); +#endif + + (void)check; + assert(check == size); + + fm_setpos(fmp, fmp->mempos + size); + + return 1; +} + +/* `fprintf()` to memory or file, returning 1 on success, 0 on failure */ +INTERNAL int fm_printf(struct filemem *restrict const fmp, const char *fmt, ...) { + va_list ap; + int ret; + + assert(fmp && fmt); + if (fmp->err) { + return 0; + } + if (fmp->flags & BARCODE_MEMORY_FILE) { + va_start(ap, fmt); + ret = fm_vprintf(fmp, fmt, ap); + va_end(ap); + return ret; + } + va_start(ap, fmt); + ret = vfprintf(fmp->fp, fmt, ap) >= 0; /* NOLINT(clang-analyzer-valist.Uninitialized) - see above */ + if (!ret) { + (void) fm_seterr(fmp, errno); + } + va_end(ap); + return ret != 0; +} + +/* Output float without trailing zeroes to `fmp` with decimal pts `dp` (precision), returning 1 on success, 0 on + failure */ +INTERNAL int fm_putsf(const char *prefix, const int dp, const float arg, struct filemem *restrict const fmp) { + int i, end; + char buf[256]; /* Assuming `dp` reasonable */ + const int len = sprintf(buf, "%.*f", dp, arg); + + assert(fmp); + if (fmp->err) { + return 0; + } + if (prefix && *prefix) { + if (!fm_puts(prefix, fmp)) { + return 0; + } + } + + /* Adapted from https://stackoverflow.com/a/36202854/664741 */ + for (i = len - 1, end = len; i >= 0; i--) { + if (buf[i] == '0') { + if (end == i + 1) { + end = i; + } + } else if (!z_isdigit(buf[i]) && buf[i] != '-') { /* If not digit or minus then decimal point */ + if (end == i + 1) { + end = i; + } else { + buf[i] = '.'; /* Overwrite any locale-specific setting for decimal point */ + } + buf[end] = '\0'; + break; + } + } + + return fm_puts(buf, fmp); +} + +/* `fclose()` if file, set `symbol->memfile` & `symbol->memfile_size` if memory, returning 1 on success, 0 on + failure */ +INTERNAL int fm_close(struct filemem *restrict const fmp, struct zint_symbol *symbol) { + assert(fmp && symbol); + if (fmp->flags & BARCODE_MEMORY_FILE) { + if (fmp->err || !fmp->mem) { + fm_clear_mem(fmp); + return fm_seterr(fmp, EINVAL); + } + symbol->memfile_size = (int) fmp->mempos; + if ((size_t) symbol->memfile_size != fmp->mempos) { + fm_clear_mem(fmp); + symbol->memfile_size = 0; + return fm_seterr(fmp, EINVAL); + } + symbol->memfile = fmp->mem; + fmp->mem = NULL; /* Now belongs to `symbol` */ + fm_clear_mem(fmp); + return 1; + } + if (fmp->err || !fmp->fp) { + if (!(fmp->flags & BARCODE_STDOUT) && fmp->fp) { + (void) fclose(fmp->fp); + } + return fm_seterr(fmp, EINVAL); + } + if (fmp->flags & BARCODE_STDOUT) { + if (fflush(fmp->fp) != 0) { + fmp->fp = NULL; + return fm_seterr(fmp, errno); + } + } else { + if (fclose(fmp->fp) != 0) { + fmp->fp = NULL; + return fm_seterr(fmp, errno); + } + } + fmp->fp = NULL; + return 1; +} + +/* `fseek()` to file/memory offset, returning 1 if successful, 0 on failure */ +INTERNAL int fm_seek(struct filemem *restrict const fmp, const long offset, const int whence) { + assert(fmp); + if (fmp->err) { + return 0; + } + if (fmp->flags & BARCODE_MEMORY_FILE) { + const size_t start = whence == SEEK_SET ? 0 : whence == SEEK_CUR ? fmp->mempos : fmp->memend; + const size_t new_pos = start + offset; + if ((offset > 0 && new_pos <= start) || (offset < 0 && new_pos >= start)) { /* Check for over/underflow */ + return fm_seterr(fmp, EINVAL); + } + if (!fm_mem_expand(fmp, new_pos)) { + return 0; + } + fm_setpos(fmp, new_pos); + return 1; + } + if (fseek(fmp->fp, offset, whence) != 0) { + return fm_seterr(fmp, errno); + } + return 1; +} + +/* `ftell()` returns current file/memory offset if successful, -1 on failure */ +INTERNAL long fm_tell(struct filemem *restrict const fmp) { + long ret; + assert(fmp); + if (fmp->err) { + return -1; + } + if (fmp->flags & BARCODE_MEMORY_FILE) { + if (!fmp->mem) { + (void) fm_seterr(fmp, ENOMEM); + return -1; + } + return (long) fmp->mempos; + } + ret = ftell(fmp->fp); + /* On many Linux distros `ftell()` returns LONG_MAX not -1 on error */ + if (ret < 0 || ret == LONG_MAX) { + (void) fm_seterr(fmp, errno); + return -1; + } + return ret; +} + +/* Return `err`, which uses `errno` values */ +INTERNAL int fm_error(struct filemem *restrict const fmp) { + assert(fmp); + return fmp->err; +} + +/* `fflush()` if file, no-op (apart from error checking) if memory, returning 1 on success, 0 on failure + NOTE: don't use, included only for libpng compatibility */ +INTERNAL int fm_flush(struct filemem *restrict const fmp) { + assert(fmp); + if (fmp->err) { + return 0; + } + if (fmp->flags & BARCODE_MEMORY_FILE) { + if (!fmp->mem) { + return fm_seterr(fmp, EINVAL); + } + return 1; + } + if (fflush(fmp->fp) == EOF) { + return fm_seterr(fmp, errno); + } + return 1; +} + +/* vim: set ts=4 sw=4 et : */ diff --git a/backend/filemem.h b/backend/filemem.h new file mode 100644 index 00000000..e79e1647 --- /dev/null +++ b/backend/filemem.h @@ -0,0 +1,95 @@ +/* filemem.h - write to file/memory abstraction */ +/* + libzint - the open source barcode library + Copyright (C) 2023 Robin Stuart + + 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 */ + +#ifndef Z_FILEMEM_H +#define Z_FILEMEM_H + +#include +#include "common.h" + +/* Whether `vsnprintf()` available */ +#if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(ZINT_IS_C89) /* Pre-MSVC 2015 (C++ 14.0) or C89 */ +#define FM_NO_VSNPRINTF +#endif + +struct filemem { + FILE *fp; + unsigned char *mem; + size_t memsize; /* Size of `mem` buffer (capacity) */ + size_t mempos; /* Current position */ + size_t memend; /* For use by `fm_seek()`, points to highest `mempos` reached */ + int flags; /* BARCODE_MEMORY_FILE or BARCODE_STDOUT */ + int err; /* `errno` values, reset only on `fm_open()` */ +#ifdef FM_NO_VSNPRINTF + FILE *fp_null; /* Only used for BARCODE_MEMORY_FILE */ +#endif +}; + +/* `fopen()` if file, setup memory buffer if BARCODE_MEMORY_FILE, returning 1 on success, 0 on failure */ +INTERNAL int fm_open(struct filemem *restrict const fmp, struct zint_symbol *symbol, const char *mode); + +/* `fwrite()` to file or memory, returning 1 on success, 0 on failure */ +INTERNAL int fm_write(const void *restrict ptr, const size_t size, const size_t nitems, + struct filemem *restrict const fmp); + +/* `fputc()` to file or memory, returning 1 on success, 0 on failure */ +INTERNAL int fm_putc(const int ch, struct filemem *restrict const fmp); + +/* `fputs()` to file or memory, returning 1 on success, 0 on failure */ +INTERNAL int fm_puts(const char *str, struct filemem *restrict const fmp); + +/* `fprintf()` to memory or file, returning 1 on success, 0 on failure */ +INTERNAL int fm_printf(struct filemem *restrict const fmp, const char *format, ...); + +/* Output float without trailing zeroes to `fmp` with decimal pts `dp` (precision), returning 1 on success, 0 on + failure */ +INTERNAL int fm_putsf(const char *prefix, const int dp, const float arg, struct filemem *restrict const fmp); + +/* `fclose()` if file, set `symbol->memfile` & `symbol->memfile_size` if memory, returning 1 on success, 0 on + failure */ +INTERNAL int fm_close(struct filemem *restrict const fmp, struct zint_symbol *symbol); + +/* `fseek()` to file/memory offset, returning 1 on success, 0 on failure */ +INTERNAL int fm_seek(struct filemem *restrict const fmp, const long offset, const int whence); + +/* `ftell()` returns current file/memory offset if successful, -1 on failure */ +INTERNAL long fm_tell(struct filemem *restrict const fmp); + +/* Return `err`, which uses `errno` values */ +INTERNAL int fm_error(struct filemem *restrict const fmp); + +/* `fflush()` if file, no-op if memory, returning 1 on success, 0 on failure + NOTE: don't use, included only for libpng compatibility */ +INTERNAL int fm_flush(struct filemem *restrict const fmp); + +/* vim: set ts=4 sw=4 et : */ +#endif /* Z_FILEMEM_H */ diff --git a/backend/gif.c b/backend/gif.c index 245e15ce..f892398b 100644 --- a/backend/gif.c +++ b/backend/gif.c @@ -32,18 +32,15 @@ #include #include -#ifdef _MSC_VER -#include -#include -#endif #include "common.h" +#include "filemem.h" #include "output.h" /* Limit initial LZW buffer size to this in expectation that compressed data will fit for typical scalings */ #define GIF_LZW_PAGE_SIZE 0x100000 /* Megabyte */ typedef struct s_statestruct { - FILE *file; + struct filemem *fmp; unsigned char *pOut; const unsigned char *pIn; const unsigned char *pInEnd; @@ -65,7 +62,7 @@ static void BufferNextByte(statestruct *pState) { (pState->OutPosCur)++; if (pState->fOutPaged && pState->OutPosCur + 2 >= pState->OutLength) { /* Keep last 256 bytes so `OutByteCountPos` within range */ - fwrite(pState->pOut, 1, pState->OutPosCur - 256, pState->file); + fm_write(pState->pOut, 1, pState->OutPosCur - 256, pState->fmp); memmove(pState->pOut, pState->pOut + pState->OutPosCur - 256, 256); pState->OutByteCountPos -= pState->OutPosCur - 256; pState->OutPosCur = 256; @@ -241,6 +238,7 @@ static int gif_lzw(statestruct *pState, int paletteBitSize) { * Called function to save in gif format */ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) { + struct filemem fm; unsigned char outbuf[10]; unsigned short usTemp; unsigned char paletteRGB[10][3]; @@ -250,7 +248,6 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) statestruct State; int transparent_index; int bgindex = -1, fgindex = -1; - const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; static const unsigned char RGBUnused[3] = {0,0,0}; unsigned char RGBfg[3]; @@ -277,22 +274,14 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) return ZINT_ERROR_MEMORY; } + State.fmp = &fm; + /* Open output file in binary mode */ - if (output_to_stdout) { -#ifdef _MSC_VER - if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - sprintf(symbol->errtxt, "610: Could not set stdout to binary (%d: %.30s)", errno, strerror(errno)); - free(State.pOut); - return ZINT_ERROR_FILE_ACCESS; - } -#endif - State.file = stdout; - } else { - if (!(State.file = out_fopen(symbol->outfile, "wb"))) { - sprintf(symbol->errtxt, "611: Could not open output file (%d: %.30s)", errno, strerror(errno)); - free(State.pOut); - return ZINT_ERROR_FILE_ACCESS; - } + if (!fm_open(State.fmp, symbol, "wb")) { + sprintf(symbol->errtxt, "611: Could not open output file (%d: %.30s)", State.fmp->err, + strerror(State.fmp->err)); + free(State.pOut); + return ZINT_ERROR_FILE_ACCESS; } /* @@ -310,7 +299,6 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) * 'K': black * '0' and '1' may be identical to one of the other values */ - paletteCount = 0; memset(State.map, 0, sizeof(State.map)); if (symbol->symbology == BARCODE_ULTRA) { static const unsigned char ultra_chars[8] = { 'W', 'C', 'B', 'M', 'R', 'Y', 'G', 'K' }; @@ -375,7 +363,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) if (transparent_index != -1) outbuf[4] = '9'; - fwrite(outbuf, 1, 6, State.file); + fm_write(outbuf, 1, 6, State.fmp); /* Screen Descriptor (7) */ /* Screen Width */ usTemp = (unsigned short) symbol->bitmap_width; @@ -402,12 +390,12 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) outbuf[5] = bgindex == -1 ? 0 : bgindex; /* Byte 7 must be 0x00 */ outbuf[6] = 0x00; - fwrite(outbuf, 1, 7, State.file); + fm_write(outbuf, 1, 7, State.fmp); /* Global Color Table (paletteSize*3) */ - fwrite(paletteRGB, 1, 3*paletteCount, State.file); + fm_write(paletteRGB, 1, 3*paletteCount, State.fmp); /* add unused palette items to fill palette size */ for (i = paletteCount; i < paletteSize; i++) { - fwrite(RGBUnused, 1, 3, State.file); + fm_write(RGBUnused, 1, 3, State.fmp); } /* Graphic control extension (8) */ @@ -435,7 +423,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) outbuf[6] = (unsigned char) transparent_index; /* Block Terminator */ outbuf[7] = 0; - fwrite(outbuf, 1, 8, State.file); + fm_write(outbuf, 1, 8, State.fmp); } /* Image Descriptor */ /* Image separator character = ',' */ @@ -458,41 +446,32 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) * There is no local color table if its most significant bit is reset. */ outbuf[9] = 0x00; - fwrite(outbuf, 1, 10, State.file); + fm_write(outbuf, 1, 10, State.fmp); /* call lzw encoding */ if (!gif_lzw(&State, paletteBitSize)) { free(State.pOut); - if (!output_to_stdout) { - (void) fclose(State.file); - } + (void) fm_close(State.fmp, symbol); strcpy(symbol->errtxt, "613: Insufficient memory for LZW buffer"); return ZINT_ERROR_MEMORY; } - fwrite((const char *) State.pOut, 1, State.OutPosCur, State.file); + fm_write((const char *) State.pOut, 1, State.OutPosCur, State.fmp); free(State.pOut); /* GIF terminator */ - fputc('\x3b', State.file); + fm_putc('\x3b', State.fmp); - if (ferror(State.file)) { - sprintf(symbol->errtxt, "615: Incomplete write to output (%d: %.30s)", errno, strerror(errno)); - if (!output_to_stdout) { - (void) fclose(State.file); - } + if (fm_error(State.fmp)) { + sprintf(symbol->errtxt, "615: Incomplete write to output (%d: %.30s)", State.fmp->err, + strerror(State.fmp->err)); + (void) fm_close(State.fmp, symbol); return ZINT_ERROR_FILE_WRITE; } - if (output_to_stdout) { - if (fflush(State.file) != 0) { - sprintf(symbol->errtxt, "616: Incomplete flush to output (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } - } else { - if (fclose(State.file) != 0) { - sprintf(symbol->errtxt, "617: Failure on closing output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } + if (!fm_close(State.fmp, symbol)) { + sprintf(symbol->errtxt, "617: Failure on closing output file (%d: %.30s)", State.fmp->err, + strerror(State.fmp->err)); + return ZINT_ERROR_FILE_WRITE; } return 0; diff --git a/backend/library.c b/backend/library.c index 08221d42..c4283c40 100644 --- a/backend/library.c +++ b/backend/library.c @@ -75,6 +75,7 @@ static void set_symbol_defaults(struct zint_symbol *symbol) { symbol->bitmap = NULL; symbol->alphamap = NULL; symbol->vector = NULL; + symbol->memfile = NULL; } /* Create and initialize a symbol structure */ @@ -115,6 +116,11 @@ void ZBarcode_Clear(struct zint_symbol *symbol) { } symbol->bitmap_width = 0; symbol->bitmap_height = 0; + if (symbol->memfile != NULL) { + free(symbol->memfile); + symbol->memfile = NULL; + } + symbol->memfile_size = 0; /* If there is a rendered version, ensure its memory is released */ vector_free(symbol); @@ -130,6 +136,9 @@ void ZBarcode_Reset(struct zint_symbol *symbol) { if (symbol->alphamap != NULL) { free(symbol->alphamap); } + if (symbol->memfile != NULL) { + free(symbol->memfile); + } vector_free(symbol); memset(symbol, 0, sizeof(*symbol)); @@ -144,6 +153,8 @@ void ZBarcode_Delete(struct zint_symbol *symbol) { free(symbol->bitmap); if (symbol->alphamap != NULL) free(symbol->alphamap); + if (symbol->memfile != NULL) + free(symbol->memfile); /* If there is a rendered version, ensure its memory is released */ vector_free(symbol); @@ -1556,7 +1567,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, const char *filename) { fileLen = ftell(file); - /* On many Linux distros ftell() returns LONG_MAX not -1 on error */ + /* On many Linux distros `ftell()` returns LONG_MAX not -1 on error */ if (fileLen <= 0 || fileLen == LONG_MAX) { (void) fclose(file); return error_tag(symbol, ZINT_ERROR_INVALID_DATA, "235: Input file empty or unseekable"); diff --git a/backend/output.c b/backend/output.c index 79ef9309..3f7c80b0 100644 --- a/backend/output.c +++ b/backend/output.c @@ -997,34 +997,4 @@ INTERNAL FILE *out_fopen(const char filename[256], const char *mode) { return outfile; } -/* Output float without trailing zeroes to `fp` with decimal pts `dp` (precision) */ -INTERNAL void out_putsf(const char *const prefix, const int dp, const float arg, FILE *fp) { - int i, end; - char buf[256]; /* Assuming `dp` reasonable */ - const int len = sprintf(buf, "%.*f", dp, arg); - - if (*prefix) { - fputs(prefix, fp); - } - - /* Adapted from https://stackoverflow.com/a/36202854/664741 */ - for (i = len - 1, end = len; i >= 0; i--) { - if (buf[i] == '0') { - if (end == i + 1) { - end = i; - } - } else if (!z_isdigit(buf[i]) && buf[i] != '-') { /* If not digit or minus then decimal point */ - if (end == i + 1) { - end = i; - } else { - buf[i] = '.'; /* Overwrite any locale-specific setting for decimal point */ - } - buf[end] = '\0'; - break; - } - } - - fputs(buf, fp); -} - /* vim: set ts=4 sw=4 et : */ diff --git a/backend/output.h b/backend/output.h index 03080b43..6be9e158 100644 --- a/backend/output.h +++ b/backend/output.h @@ -77,9 +77,6 @@ INTERNAL FILE *out_fopen(const char filename[256], const char *mode); INTERNAL FILE *out_win_fopen(const char *filename, const char *mode); #endif -/* Output float without trailing zeroes to `fp` with decimal pts `dp` (precision) */ -INTERNAL void out_putsf(const char *const prefix, const int dp, const float arg, FILE *fp); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/backend/pcx.c b/backend/pcx.c index 4e6825ea..099deaba 100644 --- a/backend/pcx.c +++ b/backend/pcx.c @@ -33,11 +33,8 @@ #include #include #include -#ifdef _MSC_VER -#include -#include -#endif #include "common.h" +#include "filemem.h" #include "output.h" #include "pcx.h" /* PCX header structure */ @@ -46,11 +43,11 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix unsigned char fgred, fggrn, fgblu, fgalpha, bgred, bggrn, bgblu, bgalpha; int row, column, i, colour; int run_count; - FILE *pcx_file; + struct filemem fm; + struct filemem *const fmp = &fm; pcx_header_t header; unsigned char previous; const unsigned char *pb; - const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; /* Suppress gcc -fanalyzer warning */ const int bytes_per_line = symbol->bitmap_width + (symbol->bitmap_width & 1); /* Must be even */ unsigned char *rle_row = (unsigned char *) z_alloca(bytes_per_line); @@ -88,22 +85,12 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix } /* Open output file in binary mode */ - if (output_to_stdout) { -#ifdef _MSC_VER - if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - sprintf(symbol->errtxt, "620: Could not set stdout to binary (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } -#endif - pcx_file = stdout; - } else { - if (!(pcx_file = out_fopen(symbol->outfile, "wb"))) { - sprintf(symbol->errtxt, "621: Could not open output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } + if (!fm_open(fmp, symbol, "wb")) { + sprintf(symbol->errtxt, "621: Could not open output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_ACCESS; } - fwrite(&header, sizeof(pcx_header_t), 1, pcx_file); + fm_write(&header, sizeof(pcx_header_t), 1, fmp); for (row = 0, pb = pixelbuf; row < symbol->bitmap_height; row++, pb += symbol->bitmap_width) { for (colour = 0; colour < header.number_of_planes; colour++) { @@ -147,9 +134,9 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix } else { if (run_count > 1 || (previous & 0xc0) == 0xc0) { run_count += 0xc0; - fputc(run_count, pcx_file); + fm_putc(run_count, fmp); } - fputc(previous, pcx_file); + fm_putc(previous, fmp); previous = rle_row[column]; run_count = 1; } @@ -157,30 +144,21 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix if (run_count > 1 || (previous & 0xc0) == 0xc0) { run_count += 0xc0; - fputc(run_count, pcx_file); + fm_putc(run_count, fmp); } - fputc(previous, pcx_file); + fm_putc(previous, fmp); } } - if (ferror(pcx_file)) { - sprintf(symbol->errtxt, "622: Incomplete write to output (%d: %.30s)", errno, strerror(errno)); - if (!output_to_stdout) { - (void) fclose(pcx_file); - } + if (fm_error(fmp)) { + sprintf(symbol->errtxt, "622: Incomplete write to output (%d: %.30s)", fmp->err, strerror(fmp->err)); + (void) fm_close(fmp, symbol); return ZINT_ERROR_FILE_WRITE; } - if (output_to_stdout) { - if (fflush(pcx_file) != 0) { - sprintf(symbol->errtxt, "623: Incomplete flush to output (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } - } else { - if (fclose(pcx_file) != 0) { - sprintf(symbol->errtxt, "624: Failure on closing output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } + if (!fm_close(fmp, symbol)) { + sprintf(symbol->errtxt, "624: Failure on closing output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_WRITE; } return 0; diff --git a/backend/png.c b/backend/png.c index f028a72e..68e2c248 100644 --- a/backend/png.c +++ b/backend/png.c @@ -35,16 +35,15 @@ #include #include #include -#ifdef _MSC_VER -#include -#include -#endif #include #include #include #include "common.h" +#include "filemem.h" #include "output.h" +/* Note using "wpng_" prefix not "png_" (except for `png_pixel_plot()`) to avoid clashing with libpng */ + /* Note if change this need to change "backend/tests/test_png.c" definition also */ struct wpng_error_type { struct zint_symbol *symbol; @@ -72,8 +71,20 @@ INTERNAL void wpng_error_handler_test(png_structp png_ptr, png_const_charp msg) } #endif +/* libpng write callback */ +static void wpng_write(png_structp png_ptr, png_bytep ptr, size_t size) { + struct filemem *fmp = (struct filemem *) png_get_io_ptr(png_ptr); + (void) fm_write(ptr, 1, size, fmp); +} + +/* libpng flush callback */ +static void wpng_flush(png_structp png_ptr) { + struct filemem *fmp = (struct filemem *) png_get_io_ptr(png_ptr); + (void) fm_flush(fmp); +} + /* Guestimate best compression strategy */ -static int guess_compression_strategy(struct zint_symbol *symbol, const unsigned char *pixelbuf) { +static int wpng_guess_compression_strategy(struct zint_symbol *symbol, const unsigned char *pixelbuf) { (void)pixelbuf; /* TODO: Do properly */ @@ -94,7 +105,8 @@ static int guess_compression_strategy(struct zint_symbol *symbol, const unsigned INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf) { struct wpng_error_type wpng_error; - FILE *outfile; + struct filemem fm; + struct filemem *const fmp = &fm; png_structp png_ptr; png_infop info_ptr; int i; @@ -105,11 +117,10 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix png_color palette[32]; int num_palette; unsigned char trans_alpha[32]; - int num_trans = 0; + int num_trans; /* Note initialize below to avoid gcc -Wclobbered warning due to `longjmp()` */ int bit_depth; int compression_strategy; const unsigned char *pb; - const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; unsigned char *outdata = (unsigned char *) z_alloca(symbol->bitmap_width); wpng_error.symbol = symbol; @@ -117,6 +128,7 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix (void) out_colour_get_rgb(symbol->fgcolour, &fg.red, &fg.green, &fg.blue, &fg_alpha); (void) out_colour_get_rgb(symbol->bgcolour, &bg.red, &bg.green, &bg.blue, &bg_alpha); + num_trans = 0; if (symbol->symbology == BARCODE_ULTRA) { static const unsigned char ultra_chars[8] = { 'W', 'C', 'B', 'M', 'R', 'Y', 'G', 'K' }; for (i = 0; i < 8; i++) { @@ -199,28 +211,16 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix } /* Open output file in binary mode */ - if (output_to_stdout) { -#ifdef _MSC_VER - if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - sprintf(symbol->errtxt, "631: Could not set stdout to binary (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } -#endif - outfile = stdout; - } else { - if (!(outfile = out_fopen(symbol->outfile, "wb"))) { - sprintf(symbol->errtxt, "632: Could not open output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } + if (!fm_open(fmp, symbol, "wb")) { + sprintf(symbol->errtxt, "632: Could not open output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_ACCESS; } /* Set up error handling routine as proc() above */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &wpng_error, wpng_error_handler, NULL); if (!png_ptr) { strcpy(symbol->errtxt, "633: Insufficient memory for PNG write structure buffer"); - if (!output_to_stdout) { - (void) fclose(outfile); - } + (void) fm_close(fmp, symbol); return ZINT_ERROR_MEMORY; } @@ -228,29 +228,25 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix if (!info_ptr) { png_destroy_write_struct(&png_ptr, NULL); strcpy(symbol->errtxt, "634: Insufficient memory for PNG info structure buffer"); - if (!output_to_stdout) { - (void) fclose(outfile); - } + (void) fm_close(fmp, symbol); return ZINT_ERROR_MEMORY; } /* catch jumping here */ if (setjmp(wpng_error.jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); - if (!output_to_stdout) { - (void) fclose(outfile); - } + (void) fm_close(fmp, symbol); return ZINT_ERROR_MEMORY; } - /* open output file with libpng */ - png_init_io(png_ptr, outfile); + /* Set our output functions */ + png_set_write_fn(png_ptr, fmp, wpng_write, wpng_flush); /* set compression */ png_set_compression_level(png_ptr, 9); /* Compression strategy can make a difference */ - compression_strategy = guess_compression_strategy(symbol, pixelbuf); + compression_strategy = wpng_guess_compression_strategy(symbol, pixelbuf); if (compression_strategy != Z_DEFAULT_STRATEGY) { png_set_compression_strategy(png_ptr, compression_strategy); } @@ -317,27 +313,23 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix /* make sure we have disengaged */ png_destroy_write_struct(&png_ptr, &info_ptr); - if (ferror(outfile)) { - sprintf(symbol->errtxt, "638: Incomplete write to output (%d: %.30s)", errno, strerror(errno)); - if (!output_to_stdout) { - (void) fclose(outfile); - } + if (fm_error(fmp)) { + sprintf(symbol->errtxt, "638: Incomplete write to output (%d: %.30s)", fmp->err, strerror(fmp->err)); + (void) fm_close(fmp, symbol); return ZINT_ERROR_FILE_WRITE; } - if (output_to_stdout) { - if (fflush(outfile) != 0) { - sprintf(symbol->errtxt, "639: Incomplete flush to output (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } - } else { - if (fclose(outfile) != 0) { - sprintf(symbol->errtxt, "960: Failure on closing output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } + if (!fm_close(fmp, symbol)) { + sprintf(symbol->errtxt, "960: Failure on closing output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_WRITE; } return 0; } /* vim: set ts=4 sw=4 et : */ +#else +#if defined(__clang__) +/* Suppresses clang-tidy-18 "clang-diagnostic-empty-translation-unit" */ +typedef int wpng_make_clang_tidy_compilers_happy; +#endif #endif /* ZINT_NO_PNG */ diff --git a/backend/ps.c b/backend/ps.c index b6500792..834b18ed 100644 --- a/backend/ps.c +++ b/backend/ps.c @@ -35,10 +35,11 @@ #include #include #include "common.h" +#include "filemem.h" #include "output.h" /* Output Ultracode rectangle colour as PostScript setrgbcolor/setcmykcolor */ -static void ps_put_colour(const int is_rgb, const int colour, FILE *feps) { +static void ps_put_colour(const int is_rgb, const int colour, struct filemem *const fmp) { const int idx = colour >= 1 && colour <= 8 ? colour - 1 : 6 /*black*/; if (is_rgb) { /* Use RGB colour space */ @@ -52,8 +53,8 @@ static void ps_put_colour(const int is_rgb, const int colour, FILE *feps) { "0 0 0", /* 6: Black (7) */ "1 1 1", /* 7: White (8) */ }; - fputs(ps_rgbs[idx], feps); - fputs(" setrgbcolor\n", feps); + fm_puts(ps_rgbs[idx], fmp); + fm_puts(" setrgbcolor\n", fmp); } else { static const char ps_cmyks[8][8] = { "1 0 0 0", /* 0: Cyan (1) */ @@ -65,8 +66,8 @@ static void ps_put_colour(const int is_rgb, const int colour, FILE *feps) { "0 0 0 1", /* 6: Black (7) */ "0 0 0 0", /* 7: White (8) */ }; - fputs(ps_cmyks[idx], feps); - fputs(" setcmykcolor\n", feps); + fm_puts(ps_cmyks[idx], fmp); + fm_puts(" setcmykcolor\n", fmp); } } @@ -107,51 +108,52 @@ INTERNAL void ps_convert_test(const unsigned char *string, unsigned char *ps_str #endif /* Helper to output RGB colour */ -static void ps_put_rgbcolor(const float red, const float green, const float blue, FILE *feps) { - out_putsf("", 2, red, feps); - out_putsf(" ", 2, green, feps); - out_putsf(" ", 2, blue, feps); - fputs(" setrgbcolor\n", feps); +static void ps_put_rgbcolor(const float red, const float green, const float blue, + struct filemem *const fmp) { + fm_putsf("", 2, red, fmp); + fm_putsf(" ", 2, green, fmp); + fm_putsf(" ", 2, blue, fmp); + fm_puts(" setrgbcolor\n", fmp); } /* Helper to output CMYK colour */ static void ps_put_cmykcolor(const float cyan, const float magenta, const float yellow, const float black, - FILE *feps) { - out_putsf("", 2, cyan, feps); - out_putsf(" ", 2, magenta, feps); - out_putsf(" ", 2, yellow, feps); - out_putsf(" ", 2, black, feps); - fputs(" setcmykcolor\n", feps); + struct filemem *const fmp) { + fm_putsf("", 2, cyan, fmp); + fm_putsf(" ", 2, magenta, fmp); + fm_putsf(" ", 2, yellow, fmp); + fm_putsf(" ", 2, black, fmp); + fm_puts(" setcmykcolor\n", fmp); } /* Helper to output rectangle */ static void ps_put_rect(const struct zint_symbol *symbol, const struct zint_vector_rect *rect, const int type, - FILE *feps) { + struct filemem *const fmp) { if (type == 0 || type == 1) { - out_putsf("", 2, rect->height, feps); - out_putsf(" ", 2, (symbol->vector->height - rect->y) - rect->height, feps); + fm_putsf("", 2, rect->height, fmp); + fm_putsf(" ", 2, (symbol->vector->height - rect->y) - rect->height, fmp); } - out_putsf(type == 0 ? " " : type == 1 ? " I " : type == 2 ? "I " : "", 2, rect->x, feps); - out_putsf(" ", 2, rect->width, feps); - fputs(" R\n", feps); + fm_putsf(type == 0 ? " " : type == 1 ? " I " : type == 2 ? "I " : "", 2, rect->x, fmp); + fm_putsf(" ", 2, rect->width, fmp); + fm_puts(" R\n", fmp); } /* Helper to output circle/disc */ static void ps_put_circle(const struct zint_symbol *symbol, const struct zint_vector_circle *circle, - const float radius, const int type, FILE *feps) { + const float radius, const int type, struct filemem *const fmp) { if (circle->width) { - out_putsf("", 2, circle->x, feps); - out_putsf(" ", 2, symbol->vector->height - circle->y, feps); - out_putsf(" ", 4, radius, feps); - out_putsf(" ", 4, circle->width, feps); - fputs(" C\n", feps); + fm_putsf("", 2, circle->x, fmp); + fm_putsf(" ", 2, symbol->vector->height - circle->y, fmp); + fm_putsf(" ", 4, radius, fmp); + fm_putsf(" ", 4, circle->width, fmp); + fm_puts(" C\n", fmp); } else { if (type == 0 || type == 1) { - out_putsf("", 2, symbol->vector->height - circle->y, feps); - out_putsf(" ", 4, radius, feps); + fm_putsf("", 2, symbol->vector->height - circle->y, fmp); + fm_putsf(" ", 4, radius, fmp); } - out_putsf(type == 0 ? " " : type == 1 ? " I " : type == 2 ? "I " : "", 2, circle->x, feps); - fputs(" D\n", feps); + fm_putsf(type == 0 ? " " : type == 1 ? " I " : type == 2 ? "I " : "", 2, circle->x, fmp); + fm_puts(" D\n", fmp); } } @@ -168,7 +170,8 @@ static int ps_count_rectangles(const struct zint_symbol *symbol) { } INTERNAL int ps_plot(struct zint_symbol *symbol) { - FILE *feps; + struct filemem fm; + struct filemem *const fmp = &fm; unsigned char fgred, fggrn, fgblu, bgred, bggrn, bgblu, bgalpha; int fgcyan, fgmagenta, fgyellow, fgblack, bgcyan, bgmagenta, bgyellow, bgblack; float red_ink = 0.0f, green_ink = 0.0f, blue_ink = 0.0f; /* Suppress `-Wmaybe-uninitialized` */ @@ -190,21 +193,15 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { int iso_latin1 = 0; int have_circles_with_width = 0, have_circles_without_width = 0; const int upcean = is_upcean(symbol->symbology); - const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; const int is_rgb = (symbol->output_options & CMYK_COLOUR) == 0; if (symbol->vector == NULL) { strcpy(symbol->errtxt, "646: Vector header NULL"); return ZINT_ERROR_INVALID_DATA; } - - if (output_to_stdout) { - feps = stdout; - } else { - if (!(feps = out_fopen(symbol->outfile, "w"))) { - sprintf(symbol->errtxt, "645: Could not open output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } + if (!fm_open(fmp, symbol, "w")) { + sprintf(symbol->errtxt, "645: Could not open output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_ACCESS; } if (is_rgb) { @@ -266,52 +263,52 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { } /* Start writing the header */ - fputs("%!PS-Adobe-3.0 EPSF-3.0\n", feps); + fm_puts("%!PS-Adobe-3.0 EPSF-3.0\n", fmp); if (ZINT_VERSION_BUILD) { - fprintf(feps, "%%%%Creator: Zint %d.%d.%d.%d\n", + fm_printf(fmp, "%%%%Creator: Zint %d.%d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE, ZINT_VERSION_BUILD); } else { - fprintf(feps, "%%%%Creator: Zint %d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE); + fm_printf(fmp, "%%%%Creator: Zint %d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE); } - fputs("%%Title: Zint Generated Symbol\n" - "%%Pages: 0\n", feps); - fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", + fm_puts("%%Title: Zint Generated Symbol\n" + "%%Pages: 0\n", fmp); + fm_printf(fmp, "%%%%BoundingBox: 0 0 %d %d\n", (int) ceilf(symbol->vector->width), (int) ceilf(symbol->vector->height)); - fputs("%%EndComments\n", feps); + fm_puts("%%EndComments\n", fmp); /* Definitions */ if (have_circles_without_width) { /* Disc: y radius x D */ - fputs("/D { newpath 3 1 roll 0 360 arc fill } bind def\n", feps); + fm_puts("/D { newpath 3 1 roll 0 360 arc fill } bind def\n", fmp); } if (have_circles_with_width) { /* Circle (ring): x y radius width C (adapted from BWIPP renmaxicode.ps) */ - fputs("/C { newpath 4 1 roll 3 copy 0 360 arc closepath 4 -1 roll add 360 0 arcn closepath fill }" - " bind def\n", feps); + fm_puts("/C { newpath 4 1 roll 3 copy 0 360 arc closepath 4 -1 roll add 360 0 arcn closepath fill }" + " bind def\n", fmp); } if (symbol->vector->hexagons) { /* Hexagon: radius half_radius half_sqrt3_radius x y */ if (symbol->vector->hexagons->rotation == 0 || symbol->vector->hexagons->rotation == 180) { - fputs("/H { newpath moveto 2 copy exch neg exch rmoveto 2 index neg 0 exch rlineto 2 copy neg rlineto" + fm_puts("/H { newpath moveto 2 copy exch neg exch rmoveto 2 index neg 0 exch rlineto 2 copy neg rlineto" " 2 copy rlineto 3 -1 roll 0 exch rlineto exch neg exch rlineto closepath fill }" - " bind def\n", feps); + " bind def\n", fmp); } else { - fputs("/H { newpath moveto 2 copy neg exch neg rmoveto 2 index 0 rlineto 2 copy exch rlineto" + fm_puts("/H { newpath moveto 2 copy neg exch neg rmoveto 2 index 0 rlineto 2 copy exch rlineto" " 2 copy neg exch rlineto 3 -1 roll neg 0 rlineto neg exch neg rlineto closepath fill }" - " bind def\n", feps); + " bind def\n", fmp); } /* Copy r hr hsr for repeat use without having to specify them subsequently */ - fputs("/J { 3 copy } bind def\n", feps); + fm_puts("/J { 3 copy } bind def\n", fmp); /* TODO: Save repeating x also */ } if (symbol->vector->rectangles || draw_background) { /* Rectangle: h y x w */ - fputs("/R { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill }" - " bind def\n", feps); + fm_puts("/R { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill }" + " bind def\n", fmp); } if (symbol->vector->rectangles || have_circles_without_width) { /* Copy h y (rect) or y r (disc) for repeat use without having to specify them subsequently */ - fputs("/I { 2 copy } bind def\n", feps); + fm_puts("/I { 2 copy } bind def\n", fmp); } /* Now the actual representation */ @@ -319,21 +316,21 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { /* Background */ if (draw_background) { if (is_rgb) { - ps_put_rgbcolor(red_paper, green_paper, blue_paper, feps); + ps_put_rgbcolor(red_paper, green_paper, blue_paper, fmp); } else { - ps_put_cmykcolor(cyan_paper, magenta_paper, yellow_paper, black_paper, feps); + ps_put_cmykcolor(cyan_paper, magenta_paper, yellow_paper, black_paper, fmp); } - out_putsf("", 2, symbol->vector->height, feps); - out_putsf(" 0 0 ", 2, symbol->vector->width, feps); /* y x w */ - fputs(" R\n", feps); + fm_putsf("", 2, symbol->vector->height, fmp); + fm_putsf(" 0 0 ", 2, symbol->vector->width, fmp); /* y x w */ + fm_puts(" R\n", fmp); } if (symbol->symbology != BARCODE_ULTRA) { if (is_rgb) { - ps_put_rgbcolor(red_ink, green_ink, blue_ink, feps); + ps_put_rgbcolor(red_ink, green_ink, blue_ink, fmp); } else { - ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, feps); + ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, fmp); } } @@ -362,22 +359,22 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { if (colour_rect_flag == 0) { /* Set foreground colour */ if (is_rgb) { - ps_put_rgbcolor(red_ink, green_ink, blue_ink, feps); + ps_put_rgbcolor(red_ink, green_ink, blue_ink, fmp); } else { - ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, feps); + ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, fmp); } colour_rect_flag = 1; } } else { /* Set new colour */ - ps_put_colour(is_rgb, rect->colour, feps); + ps_put_colour(is_rgb, rect->colour, fmp); } } if (i + 1 < u_i && rect->height == ultra_rects[i + 1]->height && rect->y == ultra_rects[i + 1]->y) { - ps_put_rect(symbol, rect, type_latch ? 2 : 1, feps); + ps_put_rect(symbol, rect, type_latch ? 2 : 1, fmp); type_latch = 1; } else { - ps_put_rect(symbol, rect, type_latch ? 3 : 0, feps); + ps_put_rect(symbol, rect, type_latch ? 3 : 0, fmp); type_latch = 0; } } @@ -385,10 +382,10 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { type_latch = 0; for (rect = symbol->vector->rectangles; rect; rect = rect->next) { if (rect->next && rect->height == rect->next->height && rect->y == rect->next->y) { - ps_put_rect(symbol, rect, type_latch ? 2 : 1, feps); + ps_put_rect(symbol, rect, type_latch ? 2 : 1, fmp); type_latch = 1; } else { - ps_put_rect(symbol, rect, type_latch ? 3 : 0, feps); + ps_put_rect(symbol, rect, type_latch ? 3 : 0, fmp); type_latch = 0; } } @@ -400,18 +397,18 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { float hy = symbol->vector->height - hex->y; if (previous_diameter != hex->diameter) { previous_diameter = hex->diameter; - out_putsf("", 4, 0.5f * previous_diameter /*radius*/, feps); - out_putsf(" ", 4, 0.43301270189221932338f * previous_diameter /*half_sqrt3_radius*/, feps); - out_putsf(" ", 4, 0.25f * previous_diameter /*half_radius*/, feps); - fputc('\n', feps); + fm_putsf("", 4, 0.5f * previous_diameter /*radius*/, fmp); + fm_putsf(" ", 4, 0.43301270189221932338f * previous_diameter /*half_sqrt3_radius*/, fmp); + fm_putsf(" ", 4, 0.25f * previous_diameter /*half_radius*/, fmp); + fm_putc('\n', fmp); } if (hex->next) { - out_putsf("J ", 2, hex->x, feps); + fm_putsf("J ", 2, hex->x, fmp); } else { - out_putsf("", 2, hex->x, feps); + fm_putsf("", 2, hex->x, fmp); } - out_putsf(" ", 2, hy, feps); - fputs(" H\n", feps); + fm_putsf(" ", 2, hy, fmp); + fm_puts(" H\n", fmp); } /* Circles */ @@ -425,25 +422,25 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { if (circle->colour) { /* Legacy - no longer used */ /* A 'white' circle */ if (is_rgb) { - ps_put_rgbcolor(red_paper, green_paper, blue_paper, feps); + ps_put_rgbcolor(red_paper, green_paper, blue_paper, fmp); } else { - ps_put_cmykcolor(cyan_paper, magenta_paper, yellow_paper, black_paper, feps); + ps_put_cmykcolor(cyan_paper, magenta_paper, yellow_paper, black_paper, fmp); } - ps_put_circle(symbol, circle, radius, 0 /*type*/, feps); + ps_put_circle(symbol, circle, radius, 0 /*type*/, fmp); if (circle->next) { if (is_rgb) { - ps_put_rgbcolor(red_ink, green_ink, blue_ink, feps); + ps_put_rgbcolor(red_ink, green_ink, blue_ink, fmp); } else { - ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, feps); + ps_put_cmykcolor(cyan_ink, magenta_ink, yellow_ink, black_ink, fmp); } } } else { /* A 'black' circle */ if (circle->next && circle->y == circle->next->y && circle->diameter == circle->next->diameter) { - ps_put_circle(symbol, circle, radius, type_latch ? 2 : 1, feps); + ps_put_circle(symbol, circle, radius, type_latch ? 2 : 1, fmp); type_latch = 1; } else { - ps_put_circle(symbol, circle, radius, type_latch ? 3 : 0, feps); + ps_put_circle(symbol, circle, radius, type_latch ? 3 : 0, fmp); type_latch = 0; } } @@ -465,70 +462,61 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { } if (iso_latin1) { /* Change encoding to ISO 8859-1, see Postscript Language Reference Manual 2nd Edition Example 5.6 */ - fprintf(feps, "/%s findfont\n", font); - fputs("dup length dict begin\n" + fm_printf(fmp, "/%s findfont\n", font); + fm_puts("dup length dict begin\n" "{1 index /FID ne {def} {pop pop} ifelse} forall\n" "/Encoding ISOLatin1Encoding def\n" "currentdict\n" "end\n" - "/Helvetica-ISOLatin1 exch definefont pop\n", feps); + "/Helvetica-ISOLatin1 exch definefont pop\n", fmp); font = "Helvetica-ISOLatin1"; } do { ps_convert(string->text, ps_string); if (string->fsize != previous_fsize) { - fprintf(feps, "/%s findfont", font); + fm_printf(fmp, "/%s findfont", font); /* Compensate for Helvetica being smaller than Zint's OCR-B */ - out_putsf( " ", 2, upcean ? string->fsize * 1.07f : string->fsize, feps); - fputs(" scalefont setfont\n", feps); + fm_putsf( " ", 2, upcean ? string->fsize * 1.07f : string->fsize, fmp); + fm_puts(" scalefont setfont\n", fmp); previous_fsize = string->fsize; } /* Unhack the guard whitespace `gws_left_fudge`/`gws_right_fudge` hack */ if (upcean && string->halign == 1 && string->text[0] == '<') { const float gws_left_fudge = symbol->scale < 0.1f ? 0.1f : symbol->scale; /* 0.5 * 2 * scale */ - out_putsf(" ", 2, string->x + gws_left_fudge, feps); + fm_putsf(" ", 2, string->x + gws_left_fudge, fmp); } else if (upcean && string->halign == 2 && string->text[0] == '>') { const float gws_right_fudge = symbol->scale < 0.1f ? 0.1f : symbol->scale; /* 0.5 * 2 * scale */ - out_putsf(" ", 2, string->x - gws_right_fudge, feps); + fm_putsf(" ", 2, string->x - gws_right_fudge, fmp); } else { - out_putsf(" ", 2, string->x, feps); + fm_putsf(" ", 2, string->x, fmp); } - out_putsf(" ", 2, symbol->vector->height - string->y, feps); - fputs(" moveto\n", feps); + fm_putsf(" ", 2, symbol->vector->height - string->y, fmp); + fm_puts(" moveto\n", fmp); if (string->rotation != 0) { - fputs(" gsave\n", feps); - fprintf(feps, " %d rotate\n", 360 - string->rotation); + fm_puts(" gsave\n", fmp); + fm_printf(fmp, " %d rotate\n", 360 - string->rotation); } if (string->halign == 0 || string->halign == 2) { /* Need width for middle or right align */ - fprintf(feps, " (%s) stringwidth pop" /* Returns "width height" - discard "height" */ + fm_printf(fmp, " (%s) stringwidth pop" /* Returns "width height" - discard "height" */ " %s 0 rmoveto\n", ps_string, string->halign == 2 ? "neg" : "-2 div"); } - fprintf(feps, " (%s) show\n", ps_string); + fm_printf(fmp, " (%s) show\n", ps_string); if (string->rotation != 0) { - fputs(" grestore\n", feps); + fm_puts(" grestore\n", fmp); } string = string->next; } while (string); } - if (ferror(feps)) { - sprintf(symbol->errtxt, "647: Incomplete write to output (%d: %.30s)", errno, strerror(errno)); - if (!output_to_stdout) { - (void) fclose(feps); - } + if (fm_error(fmp)) { + sprintf(symbol->errtxt, "647: Incomplete write to output (%d: %.30s)", fmp->err, strerror(fmp->err)); + (void) fm_close(fmp, symbol); return ZINT_ERROR_FILE_WRITE; } - if (output_to_stdout) { - if (fflush(feps) != 0) { - sprintf(symbol->errtxt, "648: Incomplete flush to output (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } - } else { - if (fclose(feps) != 0) { - sprintf(symbol->errtxt, "649: Failure on closing output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } + if (!fm_close(fmp, symbol)) { + sprintf(symbol->errtxt, "649: Failure on closing output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_WRITE; } return error_number; diff --git a/backend/qr.c b/backend/qr.c index 68f8251d..49a6f647 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -827,7 +827,8 @@ static void qr_add_ecc(unsigned char fullstream[], const unsigned char datastrea } for (j = 0; j < length_this_block; j++) { - data_block[j] = datastream[in_posn + j]; /* NOLINT false-positive popped up with clang-tidy 14.0.1 */ + /* This false-positive popped up with clang-tidy 14.0.1 */ + data_block[j] = datastream[in_posn + j]; /* NOLINT(clang-analyzer-core.uninitialized.Assign) */ } rs_encode(&rs, length_this_block, data_block, ecc_block); @@ -848,7 +849,8 @@ static void qr_add_ecc(unsigned char fullstream[], const unsigned char datastrea } for (j = 0; j < short_data_block_length; j++) { - interleaved_data[(j * blocks) + i] = data_block[j]; /* NOLINT and another with clang-tidy 14.0.6 */ + /* And another with clang-tidy 14.0.6 */ + interleaved_data[(j * blocks) + i] = data_block[j]; /* NOLINT(clang-analyzer-core.uninitialized.Assign) */ } if (i >= qty_short_blocks) { diff --git a/backend/raster.c b/backend/raster.c index c30bb8df..74f4ba18 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -244,12 +244,14 @@ static int save_raster_image_to_file(struct zint_symbol *symbol, const int image #ifndef ZINT_NO_PNG error_number = png_pixel_plot(symbol, rotated_pixbuf); #else - if (rotate_angle) { - free(rotated_pixbuf); - } - return ZINT_ERROR_INVALID_OPTION; + error_number = ZINT_ERROR_INVALID_OPTION; #endif break; +#if defined(__GNUC__) && !defined(__clang__) && defined(NDEBUG) && defined(ZINT_NO_PNG) +/* Suppress gcc warning ‘’ may be used uninitialized - only when Release and ZINT_NO_PNG */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif case OUT_PCX_FILE: error_number = pcx_pixel_plot(symbol, rotated_pixbuf); break; @@ -262,6 +264,9 @@ static int save_raster_image_to_file(struct zint_symbol *symbol, const int image default: error_number = bmp_pixel_plot(symbol, rotated_pixbuf); break; +#if defined(__GNUC__) && !defined(__clang__) && defined(NDEBUG) && defined(ZINT_NO_PNG) +#pragma GCC diagnostic pop +#endif } if (rotate_angle) { @@ -1417,6 +1422,10 @@ INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_ if (error != 0) { return error; } + if (symbol->rows <= 0) { + strcpy(symbol->errtxt, "664: No rows"); + return ZINT_ERROR_INVALID_OPTION; + } if (symbol->symbology == BARCODE_MAXICODE) { error = plot_raster_maxicode(symbol, rotate_angle, file_type); diff --git a/backend/svg.c b/backend/svg.c index ebd396f7..57329e74 100644 --- a/backend/svg.c +++ b/backend/svg.c @@ -35,6 +35,7 @@ #include #include "common.h" +#include "filemem.h" #include "output.h" #include "fonts/normal_woff2.h" #include "fonts/upcean_woff2.h" @@ -95,26 +96,27 @@ static void svg_make_html_friendly(const unsigned char *string, char *html_versi } /* Helper to output floating point attribute */ -static void svg_put_fattrib(const char *prefix, const int dp, const float val, FILE *fsvg) { - out_putsf(prefix, dp, val, fsvg); - fputc('"', fsvg); +static void svg_put_fattrib(const char *prefix, const int dp, const float val, struct filemem *fmp) { + fm_putsf(prefix, dp, val, fmp); + fm_putc('"', fmp); } /* Helper to output opacity attribute attribute and close tag (maybe) */ -static void svg_put_opacity_close(const unsigned char alpha, const float val, const int close, FILE *fsvg) { +static void svg_put_opacity_close(const unsigned char alpha, const float val, const int close, struct filemem *fmp) { if (alpha != 0xff) { - svg_put_fattrib(" opacity=\"", 3, val, fsvg); + svg_put_fattrib(" opacity=\"", 3, val, fmp); } if (close) { - fputc('/', fsvg); + fm_putc('/', fmp); } - fputs(">\n", fsvg); + fm_puts(">\n", fmp); } INTERNAL int svg_plot(struct zint_symbol *symbol) { static const char normal_font_family[] = "Arimo"; static const char upcean_font_family[] = "OCRB"; - FILE *fsvg; + struct filemem fm; + struct filemem *const fmp = &fm; int error_number = 0; float previous_diameter; float radius, half_radius, half_sqrt3_radius; @@ -135,7 +137,6 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { int len, html_len; const int upcean = is_upcean(symbol->symbology); - const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; char *html_string; (void) out_colour_get_rgb(symbol->fgcolour, &fgred, &fggreen, &fgblue, &fg_alpha); @@ -175,69 +176,68 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { strcpy(symbol->errtxt, "681: Vector header NULL"); return ZINT_ERROR_INVALID_DATA; } - if (output_to_stdout) { - fsvg = stdout; - } else { - if (!(fsvg = out_fopen(symbol->outfile, "w"))) { - sprintf(symbol->errtxt, "680: Could not open output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } + if (!fm_open(fmp, symbol, "w")) { + sprintf(symbol->errtxt, "680: Could not open output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_ACCESS; } /* Start writing the header */ - fputs("\n" + fm_puts("\n" "\n", - fsvg); - fprintf(fsvg, "\n", + fmp); + fm_printf(fmp, "\n", (int) ceilf(symbol->vector->width), (int) ceilf(symbol->vector->height)); - fputs(" Zint Generated Symbol\n", fsvg); + fm_puts(" Zint Generated Symbol\n", fmp); if ((symbol->output_options & EMBED_VECTOR_FONT) && symbol->vector->strings) { - fprintf(fsvg, " \n", - upcean ? "OCRB" : "Arimo", upcean ? upcean_woff2 : normal_woff2); + /* Split into `puts()` rather than one very large `printf()` */ + fm_printf(fmp, " \n", fmp); } - fprintf(fsvg, " \n", fgcolour_string); + fm_printf(fmp, " \n", fgcolour_string); if (bg_alpha != 0) { - fprintf(fsvg, " vector->width), (int) ceilf(symbol->vector->height), bgcolour_string); - svg_put_opacity_close(bg_alpha, bg_alpha_opacity, 1 /*close*/, fsvg); + svg_put_opacity_close(bg_alpha, bg_alpha_opacity, 1 /*close*/, fmp); } if (symbol->vector->rectangles) { int current_colour = 0; rect = symbol->vector->rectangles; - fputs(" colour != current_colour) { - fputc('"', fsvg); + fm_putc('"', fmp); if (current_colour != -1) { svg_pick_colour(current_colour, colour_code); - fprintf(fsvg, " fill=\"#%s\"", colour_code); + fm_printf(fmp, " fill=\"#%s\"", colour_code); } - svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fsvg); - fputs(" colour; - out_putsf("M", 2, rect->x, fsvg); - out_putsf(" ", 2, rect->y, fsvg); - out_putsf("h", 2, rect->width, fsvg); - out_putsf("v", 2, rect->height, fsvg); - out_putsf("h-", 2, rect->width, fsvg); - fputs("Z", fsvg); + fm_putsf("M", 2, rect->x, fmp); + fm_putsf(" ", 2, rect->y, fmp); + fm_putsf("h", 2, rect->width, fmp); + fm_putsf("v", 2, rect->height, fmp); + fm_putsf("h-", 2, rect->width, fmp); + fm_puts("Z", fmp); rect = rect->next; } - fputc('"', fsvg); + fm_putc('"', fmp); if (current_colour != -1) { svg_pick_colour(current_colour, colour_code); - fprintf(fsvg, " fill=\"#%s\"", colour_code); + fm_printf(fmp, " fill=\"#%s\"", colour_code); } - svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fsvg); + svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fmp); } if (symbol->vector->hexagons) { previous_diameter = radius = half_radius = half_sqrt3_radius = 0.0f; hex = symbol->vector->hexagons; - fputs(" diameter) { previous_diameter = hex->diameter; @@ -246,37 +246,37 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { half_sqrt3_radius = 0.43301270189221932338f * previous_diameter; } if ((hex->rotation == 0) || (hex->rotation == 180)) { - out_putsf("M", 2, hex->x, fsvg); - out_putsf(" ", 2, hex->y + radius, fsvg); - out_putsf("L", 2, hex->x + half_sqrt3_radius, fsvg); - out_putsf(" ", 2, hex->y + half_radius, fsvg); - out_putsf("L", 2, hex->x + half_sqrt3_radius, fsvg); - out_putsf(" ", 2, hex->y - half_radius, fsvg); - out_putsf("L", 2, hex->x, fsvg); - out_putsf(" ", 2, hex->y - radius, fsvg); - out_putsf("L", 2, hex->x - half_sqrt3_radius, fsvg); - out_putsf(" ", 2, hex->y - half_radius, fsvg); - out_putsf("L", 2, hex->x - half_sqrt3_radius, fsvg); - out_putsf(" ", 2, hex->y + half_radius, fsvg); + fm_putsf("M", 2, hex->x, fmp); + fm_putsf(" ", 2, hex->y + radius, fmp); + fm_putsf("L", 2, hex->x + half_sqrt3_radius, fmp); + fm_putsf(" ", 2, hex->y + half_radius, fmp); + fm_putsf("L", 2, hex->x + half_sqrt3_radius, fmp); + fm_putsf(" ", 2, hex->y - half_radius, fmp); + fm_putsf("L", 2, hex->x, fmp); + fm_putsf(" ", 2, hex->y - radius, fmp); + fm_putsf("L", 2, hex->x - half_sqrt3_radius, fmp); + fm_putsf(" ", 2, hex->y - half_radius, fmp); + fm_putsf("L", 2, hex->x - half_sqrt3_radius, fmp); + fm_putsf(" ", 2, hex->y + half_radius, fmp); } else { - out_putsf("M", 2, hex->x - radius, fsvg); - out_putsf(" ", 2, hex->y, fsvg); - out_putsf("L", 2, hex->x - half_radius, fsvg); - out_putsf(" ", 2, hex->y + half_sqrt3_radius, fsvg); - out_putsf("L", 2, hex->x + half_radius, fsvg); - out_putsf(" ", 2, hex->y + half_sqrt3_radius, fsvg); - out_putsf("L", 2, hex->x + radius, fsvg); - out_putsf(" ", 2, hex->y, fsvg); - out_putsf("L", 2, hex->x + half_radius, fsvg); - out_putsf(" ", 2, hex->y - half_sqrt3_radius, fsvg); - out_putsf("L", 2, hex->x - half_radius, fsvg); - out_putsf(" ", 2, hex->y - half_sqrt3_radius, fsvg); + fm_putsf("M", 2, hex->x - radius, fmp); + fm_putsf(" ", 2, hex->y, fmp); + fm_putsf("L", 2, hex->x - half_radius, fmp); + fm_putsf(" ", 2, hex->y + half_sqrt3_radius, fmp); + fm_putsf("L", 2, hex->x + half_radius, fmp); + fm_putsf(" ", 2, hex->y + half_sqrt3_radius, fmp); + fm_putsf("L", 2, hex->x + radius, fmp); + fm_putsf(" ", 2, hex->y, fmp); + fm_putsf("L", 2, hex->x + half_radius, fmp); + fm_putsf(" ", 2, hex->y - half_sqrt3_radius, fmp); + fm_putsf("L", 2, hex->x - half_radius, fmp); + fm_putsf(" ", 2, hex->y - half_sqrt3_radius, fmp); } - fputc('Z', fsvg); + fm_putc('Z', fmp); hex = hex->next; } - fputc('"', fsvg); - svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fsvg); + fm_putc('"', fmp); + svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fmp); } previous_diameter = radius = 0.0f; @@ -286,28 +286,28 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { previous_diameter = circle->diameter; radius = 0.5f * previous_diameter; } - fputs(" x, fsvg); - svg_put_fattrib(" cy=\"", 2, circle->y, fsvg); - svg_put_fattrib(" r=\"", circle->width ? 3 : 2, radius, fsvg); + fm_puts(" x, fmp); + svg_put_fattrib(" cy=\"", 2, circle->y, fmp); + svg_put_fattrib(" r=\"", circle->width ? 3 : 2, radius, fmp); if (circle->colour) { /* Legacy - no longer used */ if (circle->width) { - fprintf(fsvg, " stroke=\"#%s\"", bgcolour_string); - svg_put_fattrib(" stroke-width=\"", 3, circle->width, fsvg); - fputs(" fill=\"none\"", fsvg); + fm_printf(fmp, " stroke=\"#%s\"", bgcolour_string); + svg_put_fattrib(" stroke-width=\"", 3, circle->width, fmp); + fm_puts(" fill=\"none\"", fmp); } else { - fprintf(fsvg, " fill=\"#%s\"", bgcolour_string); + fm_printf(fmp, " fill=\"#%s\"", bgcolour_string); } /* This doesn't work how the user is likely to expect - more work needed! */ - svg_put_opacity_close(bg_alpha, bg_alpha_opacity, 1 /*close*/, fsvg); + svg_put_opacity_close(bg_alpha, bg_alpha_opacity, 1 /*close*/, fmp); } else { if (circle->width) { - fprintf(fsvg, " stroke=\"#%s\"", fgcolour_string); - svg_put_fattrib(" stroke-width=\"", 3, circle->width, fsvg); - fputs(" fill=\"none\"", fsvg); + fm_printf(fmp, " stroke=\"#%s\"", fgcolour_string); + svg_put_fattrib(" stroke-width=\"", 3, circle->width, fmp); + fm_puts(" fill=\"none\"", fmp); } - svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fsvg); + svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fmp); } circle = circle->next; } @@ -316,53 +316,44 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { string = symbol->vector->strings; while (string) { const char *const halign = string->halign == 2 ? "end" : string->halign == 1 ? "start" : "middle"; - fputs(" x, fsvg); - svg_put_fattrib(" y=\"", 2, string->y, fsvg); - fprintf(fsvg, " text-anchor=\"%s\"", halign); + fm_puts(" x, fmp); + svg_put_fattrib(" y=\"", 2, string->y, fmp); + fm_printf(fmp, " text-anchor=\"%s\"", halign); if (upcean) { - fprintf(fsvg, " font-family=\"%s, monospace\"", upcean_font_family); + fm_printf(fmp, " font-family=\"%s, monospace\"", upcean_font_family); } else { - fprintf(fsvg, " font-family=\"%s, Arial, sans-serif\"", normal_font_family); + fm_printf(fmp, " font-family=\"%s, Arial, sans-serif\"", normal_font_family); } - svg_put_fattrib(" font-size=\"", 1, string->fsize, fsvg); + svg_put_fattrib(" font-size=\"", 1, string->fsize, fmp); if (bold) { - fputs(" font-weight=\"bold\"", fsvg); + fm_puts(" font-weight=\"bold\"", fmp); } if (string->rotation != 0) { - fprintf(fsvg, " transform=\"rotate(%d", string->rotation); - out_putsf(",", 2, string->x, fsvg); - out_putsf(",", 2, string->y, fsvg); - fputs(")\"", fsvg); + fm_printf(fmp, " transform=\"rotate(%d", string->rotation); + fm_putsf(",", 2, string->x, fmp); + fm_putsf(",", 2, string->y, fmp); + fm_puts(")\"", fmp); } - svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 0 /*close*/, fsvg); + svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 0 /*close*/, fmp); svg_make_html_friendly(string->text, html_string); - fprintf(fsvg, " %s\n", html_string); - fputs(" \n", fsvg); + fm_printf(fmp, " %s\n", html_string); + fm_puts(" \n", fmp); string = string->next; } - fputs(" \n" - "\n", fsvg); + fm_puts(" \n" + "\n", fmp); - if (ferror(fsvg)) { - sprintf(symbol->errtxt, "682: Incomplete write to output (%d: %.30s)", errno, strerror(errno)); - if (!output_to_stdout) { - (void) fclose(fsvg); - } + if (fm_error(fmp)) { + sprintf(symbol->errtxt, "682: Incomplete write to output (%d: %.30s)", fmp->err, strerror(fmp->err)); + (void) fm_close(fmp, symbol); return ZINT_ERROR_FILE_WRITE; } - if (output_to_stdout) { - if (fflush(fsvg) != 0) { - sprintf(symbol->errtxt, "683: Incomplete flush to output (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } - } else { - if (fclose(fsvg) != 0) { - sprintf(symbol->errtxt, "684: Failure on closing output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } + if (!fm_close(fmp, symbol)) { + sprintf(symbol->errtxt, "684: Failure on closing output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_WRITE; } return error_number; diff --git a/backend/tests/CMakeLists.txt b/backend/tests/CMakeLists.txt index 1ab1b02a..94c4204f 100644 --- a/backend/tests/CMakeLists.txt +++ b/backend/tests/CMakeLists.txt @@ -58,6 +58,7 @@ zint_add_test(dmatrix test_dmatrix) zint_add_test(dotcode test_dotcode) zint_add_test(eci test_eci) zint_add_test(emf test_emf) +zint_add_test(filemem test_filemem) zint_add_test(gb18030 test_gb18030) zint_add_test(gb2312 test_gb2312) zint_add_test(gif test_gif) diff --git a/backend/tests/test_bmp.c b/backend/tests/test_bmp.c index c63262c4..b98f015a 100644 --- a/backend/tests/test_bmp.c +++ b/backend/tests/test_bmp.c @@ -155,6 +155,8 @@ static void test_print(const testCtx *const p_ctx) { char expected_file[4096]; char escaped[1024]; int escaped_size = 1024; + unsigned char filebuf[32768]; + int filebuf_size; const char *const have_identify = testUtilHaveIdentify(); @@ -220,7 +222,23 @@ static void test_print(const testCtx *const p_ctx) { ret = testUtilCmpBins(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpBins(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + + ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size); /* For BARCODE_MEMORY_FILE */ + assert_zero(ret, "i:%d %s testUtilReadFile(%s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret); + + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + } + + symbol->output_options |= BARCODE_MEMORY_FILE; + ret = ZBarcode_Print(symbol, 0); + assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0 (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret, symbol->errtxt); + assert_nonnull(symbol->memfile, "i:%d %s memfile NULL\n", i, testUtilBarcodeName(data[i].symbology)); + assert_equal(symbol->memfile_size, filebuf_size, "i:%d %s memfile_size %d != %d\n", + i, testUtilBarcodeName(data[i].symbology), symbol->memfile_size, filebuf_size); + assert_zero(memcmp(symbol->memfile, filebuf, symbol->memfile_size), "i:%d %s memcmp(memfile, filebuf) != 0\n", + i, testUtilBarcodeName(data[i].symbology)); } ZBarcode_Delete(symbol); diff --git a/backend/tests/test_codablock.c b/backend/tests/test_codablock.c index a8cf4e57..eafd921a 100644 --- a/backend/tests/test_codablock.c +++ b/backend/tests/test_codablock.c @@ -590,7 +590,7 @@ static void test_fuzz(const testCtx *const p_ctx) { }; struct item data[] = { /* 0*/ { -1, -1, "\034\034I", 3, 0, 1, "" }, - /* 1*/ { 6, -2147483648, + /* 1*/ { 6, -2147483647 - 1 /*Suppress MSVC warning C4146*/, "\134\000\377\153\143\163\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061\061" "\071\065\062\000\000\000\000\061\061\061\061\061\061\366\366\366\366\366\366\366\366\366\366\007\366\366\366\366\366\366\366\061\061\061\061\061\061\061\061\061" "\061\061\061\061\061\061\061\323\323\323\323\000\200\135\000\362\000\000\000\000\000\050\000\000\000\000\162\162\162\162\034\153\143\163\061\061\061\061\061\061" diff --git a/backend/tests/test_emf.c b/backend/tests/test_emf.c index ad590579..d96f9063 100644 --- a/backend/tests/test_emf.c +++ b/backend/tests/test_emf.c @@ -104,6 +104,8 @@ static void test_print(const testCtx *const p_ctx) { char expected_file[1024]; char escaped[1024]; int escaped_size = 1024; + unsigned char filebuf[32768]; + int filebuf_size; int have_libreoffice = 0; if (p_ctx->generate) { @@ -182,7 +184,23 @@ static void test_print(const testCtx *const p_ctx) { ret = testUtilCmpBins(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpBins(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); - if (p_ctx->index == -1) assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + + ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size); /* For BARCODE_MEMORY_FILE */ + assert_zero(ret, "i:%d %s testUtilReadFile(%s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret); + + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + } + + symbol->output_options |= BARCODE_MEMORY_FILE; + ret = ZBarcode_Print(symbol, data[i].rotate_angle); + assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0 (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret, symbol->errtxt); + assert_nonnull(symbol->memfile, "i:%d %s memfile NULL\n", i, testUtilBarcodeName(data[i].symbology)); + assert_equal(symbol->memfile_size, filebuf_size, "i:%d %s memfile_size %d != %d\n", + i, testUtilBarcodeName(data[i].symbology), symbol->memfile_size, filebuf_size); + assert_zero(memcmp(symbol->memfile, filebuf, symbol->memfile_size), "i:%d %s memcmp(memfile, filebuf) != 0\n", + i, testUtilBarcodeName(data[i].symbology)); } ZBarcode_Delete(symbol); diff --git a/backend/tests/test_filemem.c b/backend/tests/test_filemem.c new file mode 100644 index 00000000..96d4a331 --- /dev/null +++ b/backend/tests/test_filemem.c @@ -0,0 +1,477 @@ +/* + libzint - the open source barcode library + Copyright (C) 2023 Robin Stuart + + 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 +#include +#include +#include +#include +#include +#include "testcommon.h" +#include "../common.h" +#include "../filemem.h" + +static void test_svg(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int output_options; + char *outfile; + char *data; + int length; + int ret; + + char *expected; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + struct item data[] = { + /* 0*/ { BARCODE_CODE128, BARCODE_MEMORY_FILE, "out.svg", "ABCDEF", -1, 0, + "\n" + "\n" + "\n" + " Zint Generated Symbol\n" + " \n" + " \n" + " \n" + " \n" + " ABCDEF\n" + " \n" + " \n" + "\n" + }, + }; + int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + testStartSymbol("test_svg", &symbol); + + for (i = 0; i < data_size; i++) { + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, data[i].output_options, data[i].data, data[i].length, debug); + strcpy(symbol->outfile, data[i].outfile); + + ret = ZBarcode_Encode_and_Print(symbol, TU(data[i].data), length, 0); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_and_Print(%d) ret %d != %d (%s)\n", + i, data[i].symbology, ret, data[i].ret, symbol->errtxt); + + if (ret < ZINT_ERROR) { + const int expected_size = (int) strlen(data[i].expected); + + assert_nonnull(symbol->memfile, "i:%d memfile NULL (%s)\n", i, symbol->errtxt); + + assert_equal(symbol->memfile_size, expected_size, "i:%d memfile_size %d != %d (%s)\n", + i, symbol->memfile_size, expected_size, symbol->errtxt); + ret = memcmp(symbol->memfile, data[i].expected, symbol->memfile_size); + assert_zero(ret, "i:%d memcmp() %d != 0\n", i, ret); + } else { + assert_null(symbol->memfile, "i:%d memfile != NULL (%s)\n", i, symbol->errtxt); + assert_zero(symbol->memfile_size, "i:%d memfile_size != 0 (%s)\n", i, symbol->errtxt); + } + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + +#ifndef _WIN32 +extern FILE *fmemopen(void *buf, size_t size, const char *mode); +#endif + +static void test_putsf(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + const char *prefix; + int dp; + float arg; + const char *locale; + const char *expected; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + struct item data[] = { + /* 0*/ { "", 2, 1234.123, "", "1234.12" }, + /* 1*/ { "", 3, 1234.123, "", "1234.123" }, + /* 2*/ { "prefix ", 4, 1234.123, "", "prefix 1234.123" }, + /* 3*/ { "", 2, -1234.126, "", "-1234.13" }, + /* 4*/ { "", 2, 1234.1, "", "1234.1" }, + /* 5*/ { "", 3, 1234.1, "", "1234.1" }, + /* 6*/ { "", 4, 1234.1, "", "1234.1" }, + /* 7*/ { "", 2, 1234.0, "", "1234" }, + /* 8*/ { "", 2, -1234.0, "", "-1234" }, + /* 9*/ { "", 3, 1234.1234, "de_DE.UTF-8", "1234.123" }, + /* 10*/ { "", 4, -1234.1234, "de_DE.UTF-8", "-1234.1234" }, + /* 11*/ { "prefix ", 4, -1234.1234, "de_DE.UTF-8", "prefix -1234.1234" }, + }; + int data_size = ARRAY_SIZE(data); + int i, j; + + struct zint_symbol symbol_data = {0}; + struct zint_symbol *const symbol = &symbol_data; + struct filemem fm; + struct filemem *const fmp = &fm; +#ifndef _WIN32 + FILE *fp; + char buf[512] = {0}; /* Suppress clang-16/17 run-time exception MemorySanitizer: use-of-uninitialized-value */ +#endif + + testStart("test_putsf"); + + for (j = 0; j < 2; j++) { /* 1st `memfile`, then file */ +#ifdef _WIN32 + if (j == 1) break; /* Skip file test on Windows */ +#endif + for (i = 0; i < data_size; i++) { + const char *locale = NULL; + int expected_size; + + if (testContinue(p_ctx, i)) continue; + + ZBarcode_Reset(symbol); + if (j == 1) { +#ifndef _WIN32 + buf[0] = '\0'; + fp = fmemopen(buf, sizeof(buf), "w"); + assert_nonnull(fp, "%d: fmemopen fail (%d, %s)\n", i, errno, strerror(errno)); +#endif + } else { + symbol->output_options |= BARCODE_MEMORY_FILE; + } + assert_nonzero(fm_open(fmp, symbol, "w"), "i:%d: fm_open fail (%d, %s)\n", i, fmp->err, strerror(fmp->err)); + if (j == 1) { +#ifndef _WIN32 + /* Hack in `fmemopen()` fp */ + assert_zero(fclose(fmp->fp), "i:%d fclose(fmp->fp) fail (%d, %s)\n", i, errno, strerror(errno)); + fmp->fp = fp; +#endif + } + + if (data[i].locale && data[i].locale[0]) { + locale = setlocale(LC_ALL, data[i].locale); + if (!locale) { /* May not be available - warn unless quiet mode */ + if (!(debug & ZINT_DEBUG_TEST_LESS_NOISY)) { + printf("i:%d: Warning: locale \"%s\" not available\n", i, data[i].locale); + } + } + } + + fm_putsf(data[i].prefix, data[i].dp, data[i].arg, fmp); + + assert_nonzero(fm_close(fmp, symbol), "i:%d: fm_close fail (%d, %s)\n", i, fmp->err, strerror(fmp->err)); + + if (locale) { + assert_nonnull(setlocale(LC_ALL, locale), "i:%d: setlocale(%s) restore fail (%d, %s)\n", + i, locale, errno, strerror(errno)); + } + + if (j == 1) { +#ifndef _WIN32 + assert_zero(strcmp(buf, data[i].expected), "%d: strcmp(%s, %s) != 0\n", i, buf, data[i].expected); +#endif + } else { + expected_size = (int) strlen(data[i].expected); + assert_equal(symbol->memfile_size, expected_size, "i:%d: memfile_size %d != expected_size %d\n", + i, symbol->memfile_size, expected_size); + assert_nonnull(symbol->memfile, "i:%d memfile NULL\n", i); + assert_zero(memcmp(symbol->memfile, data[i].expected, expected_size), "i:%d: memcmp(%.*s, %.*s) != 0\n", + i, symbol->memfile_size, symbol->memfile, expected_size, data[i].expected); + } + + ZBarcode_Clear(symbol); + } + } + + testFinish(); +} + +static void test_printf(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + int ret; + int j; + struct zint_symbol symbol_data = {0}; + struct zint_symbol *const symbol = &symbol_data; + struct filemem fm; + struct filemem *const fmp = &fm; + const char outfile[] = "test_printf.tst"; + unsigned char filebuf[32768]; + int filebuf_size; + + const char fmt1[] = "\n%s%04d\n\032\nwow\n\r\n%.2s\n"; /* '\032' SUB (^Z) */ + const char expected1[] = "\ngosh0123\n\032\nwow\n\r\nge\n"; +#ifdef _WIN32 + /* On Windows, non-binary (i.e. text) files, LF -> LF+CR (note, actual files only, not memfiles) */ + const char expected1_text_file[] = "\r\ngosh0123\r\n\032\r\nwow\r\n\r\r\nge\r\n"; +#endif + const char *expected; + int expected_size; + + (void)debug; + + testStart("test_printf"); + + for (j = 0; j < 2; j++) { /* 1st memfile, then file */ + ZBarcode_Reset(symbol); + + /* Binary */ + expected = expected1; + if (j == 1) { + strcpy(symbol->outfile, outfile); + } else { + symbol->output_options |= BARCODE_MEMORY_FILE; + } + ret = fm_open(fmp, symbol, "wb"); + assert_equal(ret, 1, "fm_open ret %d != 1\n", ret); + + ret = fm_printf(fmp, fmt1, "gosh", 123, "gee"); + assert_equal(ret, 1, "fm_printf ret %d != 1\n", ret); + + ret = fm_close(fmp, symbol); + assert_equal(ret, 1, "fm_close ret %d != 1\n", ret); + + expected_size = (int) strlen(expected); + + if (j == 1) { + ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size); + assert_zero(ret, "testUtilReadFile(%s) %d != 0\n", symbol->outfile, ret); + assert_equal((int) filebuf_size, expected_size, "filebuf_size %d != %d\n", filebuf_size, expected_size); + assert_zero(memcmp(filebuf, expected, filebuf_size), "memcmp(%.*s, %s) != 0\n", + filebuf_size, filebuf, expected); + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile); + } + } else { + assert_nonnull(symbol->memfile, "memfile NULL (%d: %s)\n", fmp->err, strerror(fmp->err)); + assert_equal(symbol->memfile_size, expected_size, "mempos %d != %d\n", + symbol->memfile_size, expected_size); + assert_zero(memcmp(symbol->memfile, expected, symbol->memfile_size), "memcmp(%.*s, %s) != 0\n", + symbol->memfile_size, symbol->memfile, expected); + } + + /* Non-binary */ + expected = expected1; + if (j == 1) { + strcpy(symbol->outfile, outfile); +#ifdef _WIN32 + expected = expected1_text_file; +#endif + } else { + symbol->output_options |= BARCODE_MEMORY_FILE; + } + ret = fm_open(fmp, symbol, "w"); + assert_equal(ret, 1, "fm_open ret %d != 1\n", ret); + + ret = fm_printf(fmp, fmt1, "gosh", 123, "gee"); + assert_equal(ret, 1, "fm_printf ret %d != 1\n", ret); + + ret = fm_close(fmp, symbol); + assert_equal(ret, 1, "fm_close ret %d != 1\n", ret); + + expected_size = (int) strlen(expected); + + if (j == 1) { + ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size); + assert_zero(ret, "testUtilReadFile(%s) %d != 0\n", symbol->outfile, ret); + assert_equal((int) filebuf_size, expected_size, "filebuf_size %d != %d\n", filebuf_size, expected_size); + assert_zero(memcmp(filebuf, expected, filebuf_size), "memcmp(%.*s, %s) != 0\n", + filebuf_size, filebuf, expected); + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile); + } + } else { + assert_nonnull(symbol->memfile, "mem NULL (%d: %s)\n", fmp->err, strerror(fmp->err)); + assert_equal(symbol->memfile_size, expected_size, "mempos %d != %d\n", + symbol->memfile_size, expected_size); + assert_zero(memcmp(symbol->memfile, expected, symbol->memfile_size), "memcmp(%.*s, %s) != 0\n", + symbol->memfile_size, symbol->memfile, expected); + } + + ZBarcode_Clear(symbol); + } + + testFinish(); +} + +static void test_seek(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + int ret; + int j; + struct zint_symbol symbol_data = {0}; + struct zint_symbol *const symbol = &symbol_data; + struct filemem fm; + struct filemem *const fmp = &fm; + const char outfile[] = "test_seek.tst"; + + (void)debug; + + testStart("test_seek"); + + for (j = 0; j < 2; j++) { /* 1st memfile, then file */ + ZBarcode_Reset(symbol); + + if (j == 1) { + strcpy(symbol->outfile, outfile); + } else { + symbol->output_options |= BARCODE_MEMORY_FILE; + } + ret = fm_open(fmp, symbol, "wb"); + assert_equal(ret, 1, "j:%d fm_open ret %d != 1\n", j, ret); + + ret = fm_puts("1234567890", fmp); + assert_equal(ret, 1, "j:%d fm_puts ret %d != 1\n", j, ret); + if (j != 1) { + assert_nonnull(fmp->mem, "mem NULL (%d: %s)\n", fmp->err, strerror(fmp->err)); + assert_equal(fmp->mempos, 10, "mempos %d != 10\n", (int) fmp->mempos); + assert_zero(memcmp(fmp->mem, "1234567890", fmp->mempos), "memcmp fail\n"); + } + + ret = fm_seek(fmp, -10, SEEK_CUR); + assert_equal(ret, 1, "j:%d fm_seek ret %d != 1 (%d: %s)\n", j, ret, fmp->err, strerror(fmp->err)); + ret = fm_error(fmp); + assert_zero(ret, "j:%d fm_error ret %d != 0\n", j, ret); + ret = (int) fm_tell(fmp); + assert_zero(ret, "j:%d fm_tell ret %d != 0\n", j, ret); + + ret = fm_seek(fmp, 0, SEEK_END); + assert_equal(ret, 1, "j:%d fm_seek ret %d != 1\n", j, ret); + ret = fm_error(fmp); + assert_zero(ret, "j:%d fm_error ret %d != 0\n", j, ret); + ret = (int) fm_tell(fmp); + assert_equal(ret, 10, "j:%d fm_tell ret %d != 10\n", j, ret); + + ret = fm_seek(fmp, -1, SEEK_SET); + assert_zero(ret, "j:%d fm_seek ret %d != 1\n", j, ret); + assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err)); + + ret = fm_close(fmp, symbol); + assert_zero(ret, "j:%d fm_close ret %d != 0\n", j, ret); + assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err)); + + if (j == 1) { + assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile); + } + + ret = fm_open(fmp, symbol, "wb"); + assert_equal(ret, 1, "j:%d fm_open ret %d != 1\n", j, ret); + + ret = fm_seek(fmp, LONG_MAX, SEEK_CUR); + if (j == 1) { /* May work on some file systems */ + if (ret == 0) { + assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err)); + } + } else { + assert_zero(ret, "j:%d fm_seek ret %d != 0\n", j, ret); + assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err)); + } + + ret = fm_close(fmp, symbol); + if (j == 1) { /* See above */ + if (ret == 0) { + assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err)); + } + } else { + assert_zero(ret, "j:%d fm_close ret %d != 0\n", j, ret); + assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err)); + } + + if (j == 1) { + assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile); + } + + ZBarcode_Clear(symbol); + } + + testFinish(); +} + +static void test_large(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + int ret; + struct zint_symbol *symbol = NULL; + char data[] = "1"; + int expected_size = 354879; + + (void)debug; + + testStart("test_large"); + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + symbol->symbology = BARCODE_HANXIN; + symbol->output_options |= BARCODE_MEMORY_FILE; + strcpy(symbol->outfile, "out.gif"); /* Use GIF in case ZINT_NO_PNG */ + symbol->option_2 = 84; + symbol->scale = 10.0f; /* Could go up to 86.5 (pixel buffer 0x3FB913B1, file size 8868579) but very very slow */ + + ret = ZBarcode_Encode_and_Print(symbol, TU(data), -1, 0); + assert_zero(ret, "ZBarcode_Encode_and_Print ret %d != 0 (%s)\n", ret, symbol->errtxt); + assert_nonnull(symbol->memfile, "memfile NULL (%s)\n", symbol->errtxt); + assert_equal(symbol->memfile_size, expected_size, "memfile_size %d != expected %d\n", + symbol->memfile_size, expected_size); + + symbol->scale = 87.0f; /* Too large (pixel buffer > 1GB) */ + ret = ZBarcode_Print(symbol, 0); + assert_equal(ret, ZINT_ERROR_MEMORY, "ZBarcode_Print ret %d != ZINT_ERROR_MEMORY (%s)\n", ret, symbol->errtxt); + + ZBarcode_Delete(symbol); + + testFinish(); +} + +int main(int argc, char *argv[]) { + + testFunction funcs[] = { /* name, func */ + { "test_svg", test_svg }, + { "test_putsf", test_putsf }, + { "test_printf", test_printf }, + { "test_seek", test_seek }, + { "test_large", test_large }, + }; + + testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); + + testReport(); + + return 0; +} + +/* vim: set ts=4 sw=4 et : */ + diff --git a/backend/tests/test_gif.c b/backend/tests/test_gif.c index 9b0578c1..3a351d3d 100644 --- a/backend/tests/test_gif.c +++ b/backend/tests/test_gif.c @@ -191,6 +191,8 @@ static void test_print(const testCtx *const p_ctx) { char expected_file[4096]; char escaped[1024]; int escaped_size = 1024; + unsigned char filebuf[32768]; + int filebuf_size; const char *const have_identify = testUtilHaveIdentify(); @@ -268,7 +270,23 @@ static void test_print(const testCtx *const p_ctx) { ret = testUtilCmpBins(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpBins(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + + ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size); /* For BARCODE_MEMORY_FILE */ + assert_zero(ret, "i:%d %s testUtilReadFile(%s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret); + + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + } + + symbol->output_options |= BARCODE_MEMORY_FILE; + ret = ZBarcode_Print(symbol, 0); + assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0 (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret, symbol->errtxt); + assert_nonnull(symbol->memfile, "i:%d %s memfile NULL\n", i, testUtilBarcodeName(data[i].symbology)); + assert_equal(symbol->memfile_size, filebuf_size, "i:%d %s memfile_size %d != %d\n", + i, testUtilBarcodeName(data[i].symbology), symbol->memfile_size, filebuf_size); + assert_zero(memcmp(symbol->memfile, filebuf, symbol->memfile_size), "i:%d %s memcmp(memfile, filebuf) != 0\n", + i, testUtilBarcodeName(data[i].symbology)); } ZBarcode_Delete(symbol); diff --git a/backend/tests/test_output.c b/backend/tests/test_output.c index 0e855e85..18159337 100644 --- a/backend/tests/test_output.c +++ b/backend/tests/test_output.c @@ -31,7 +31,6 @@ #include "testcommon.h" #include "../output.h" -#include #ifdef _WIN32 #include #include @@ -411,82 +410,6 @@ static void test_fopen(const testCtx *const p_ctx) { testFinish(); } -#ifndef _WIN32 -extern FILE *fmemopen(void *buf, size_t size, const char *mode); -#endif - -static void test_out_putsf(const testCtx *const p_ctx) { - int debug = p_ctx->debug; - - struct item { - const char *prefix; - int dp; - float arg; - const char *locale; - const char *expected; - }; - /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ - struct item data[] = { - /* 0*/ { "", 2, 1234.123, "", "1234.12" }, - /* 1*/ { "", 3, 1234.123, "", "1234.123" }, - /* 2*/ { "prefix ", 4, 1234.123, "", "prefix 1234.123" }, - /* 3*/ { "", 2, -1234.126, "", "-1234.13" }, - /* 4*/ { "", 2, 1234.1, "", "1234.1" }, - /* 5*/ { "", 3, 1234.1, "", "1234.1" }, - /* 6*/ { "", 4, 1234.1, "", "1234.1" }, - /* 7*/ { "", 2, 1234.0, "", "1234" }, - /* 8*/ { "", 2, -1234.0, "", "-1234" }, - /* 9*/ { "", 3, 1234.1234, "de_DE.UTF-8", "1234.123" }, - /* 10*/ { "", 4, -1234.1234, "de_DE.UTF-8", "-1234.1234" }, - /* 11*/ { "prefix ", 4, -1234.1234, "de_DE.UTF-8", "prefix -1234.1234" }, - }; - int data_size = ARRAY_SIZE(data); - int i; - - FILE *fp; - char buf[512] = {0}; /* Suppress clang-16/17 run-time exception MemorySanitizer: use-of-uninitialized-value */ - - testStart("test_out_putsf"); - -#ifdef _WIN32 - (void)i; (void)fp; (void)buf; - testSkip("Test not implemented on Windows"); -#else - - for (i = 0; i < data_size; i++) { - const char *locale = NULL; - - if (testContinue(p_ctx, i)) continue; - - buf[0] = '\0'; - fp = fmemopen(buf, sizeof(buf), "w"); - assert_nonnull(fp, "%d: fmemopen fail (%d, %s)\n", i, errno, strerror(errno)); - - if (data[i].locale && data[i].locale[0]) { - locale = setlocale(LC_ALL, data[i].locale); - if (!locale) { /* May not be available - warn unless quiet mode */ - if (!(debug & ZINT_DEBUG_TEST_LESS_NOISY)) { - printf("%d: Warning: locale \"%s\" not available\n", i, data[i].locale); - } - } - } - - out_putsf(data[i].prefix, data[i].dp, data[i].arg, fp); - - assert_zero(fclose(fp), "%d: fclose fail (%d, %s)\n", i, errno, strerror(errno)); - - if (locale) { - assert_nonnull(setlocale(LC_ALL, locale), "%d: setlocale(%s) restore fail (%d, %s)\n", - i, locale, errno, strerror(errno)); - } - - assert_zero(strcmp(buf, data[i].expected), "%d: strcmp(%s, %s) != 0\n", i, buf, data[i].expected); - } - - testFinish(); -#endif /* _WIN32 */ -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -496,7 +419,6 @@ int main(int argc, char *argv[]) { { "test_quiet_zones", test_quiet_zones }, { "test_set_whitespace_offsets", test_set_whitespace_offsets }, { "test_fopen", test_fopen }, - { "test_out_putsf", test_out_putsf }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/test_pcx.c b/backend/tests/test_pcx.c index c75edf8b..bf4eaa60 100644 --- a/backend/tests/test_pcx.c +++ b/backend/tests/test_pcx.c @@ -65,6 +65,8 @@ static void test_print(const testCtx *const p_ctx) { char expected_file[4096]; char escaped[1024]; int escaped_size = 1024; + unsigned char filebuf[36864]; + int filebuf_size; const char *const have_identify = testUtilHaveIdentify(); @@ -134,7 +136,23 @@ static void test_print(const testCtx *const p_ctx) { ret = testUtilCmpBins(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpBins(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + + ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size); /* For BARCODE_MEMORY_FILE */ + assert_zero(ret, "i:%d %s testUtilReadFile(%s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret); + + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + } + + symbol->output_options |= BARCODE_MEMORY_FILE; + ret = ZBarcode_Print(symbol, 0); + assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0 (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret, symbol->errtxt); + assert_nonnull(symbol->memfile, "i:%d %s memfile NULL\n", i, testUtilBarcodeName(data[i].symbology)); + assert_equal(symbol->memfile_size, filebuf_size, "i:%d %s memfile_size %d != %d\n", + i, testUtilBarcodeName(data[i].symbology), symbol->memfile_size, filebuf_size); + assert_zero(memcmp(symbol->memfile, filebuf, symbol->memfile_size), "i:%d %s memcmp(memfile, filebuf) != 0\n", + i, testUtilBarcodeName(data[i].symbology)); } ZBarcode_Delete(symbol); diff --git a/backend/tests/test_pdf417.c b/backend/tests/test_pdf417.c index bd6532b9..ba1803db 100644 --- a/backend/tests/test_pdf417.c +++ b/backend/tests/test_pdf417.c @@ -144,8 +144,8 @@ static void test_options(const testCtx *const p_ctx) { /* 9*/ { BARCODE_PDF417, -1, 10, -1, 0, { 0, 0, "" }, "12345", 0, 0, 3, 239, "", -1 }, /* ECC auto-set to 2, cols 10 */ /* 10*/ { BARCODE_PDF417, 9, -1, -1, 0, { 0, 0, "" }, "12345", ZINT_WARN_INVALID_OPTION, 0, 6, 103, "Warning 460: Security value out of range", -1 }, /* Invalid ECC, auto-set */ /* 11*/ { BARCODE_PDF417, -1, 31, -1, 0, { 0, 0, "" }, "12345", ZINT_WARN_INVALID_OPTION, 0, 6, 103, "Warning 461: Number of columns out of range (1 to 30)", 0 }, /* Invalid cols, auto-set */ - /* 12*/ { BARCODE_PDF417, -1, -1, 2, 0, { 0, 0, "" }, "12345", ZINT_ERROR_INVALID_OPTION, 0, 0, 0, "Error 466: Number of rows out of range (3 to 90)", -1 }, /* Invalid rows, error */ - /* 13*/ { BARCODE_PDF417, -1, -1, 91, 0, { 0, 0, "" }, "12345", ZINT_ERROR_INVALID_OPTION, 0, 0, 0, "Error 466: Number of rows out of range (3 to 90)", -1 }, /* Invalid rows, error */ + /* 12*/ { BARCODE_PDF417, -1, -1, 2, 0, { 0, 0, "" }, "12345", ZINT_ERROR_INVALID_OPTION, ZINT_ERROR_INVALID_OPTION, 0, 0, "Error 466: Number of rows out of range (3 to 90)", -1 }, /* Invalid rows, error */ + /* 13*/ { BARCODE_PDF417, -1, -1, 91, 0, { 0, 0, "" }, "12345", ZINT_ERROR_INVALID_OPTION, ZINT_ERROR_INVALID_OPTION, 0, 0, "Error 466: Number of rows out of range (3 to 90)", -1 }, /* Invalid rows, error */ /* 14*/ { BARCODE_PDF417, 9, -1, -1, WARN_FAIL_ALL, { 0, 0, "" }, "12345", ZINT_ERROR_INVALID_OPTION, -1, 0, 0, "Error 460: Security value out of range", -1 }, /* Invalid ECC */ /* 15*/ { BARCODE_PDF417, -1, 31, -1, WARN_FAIL_ALL, { 0, 0, "" }, "12345", ZINT_ERROR_INVALID_OPTION, -1, 0, 0, "Error 461: Number of columns out of range (1 to 30)", -1 }, /* Invalid cols */ /* 16*/ { BARCODE_PDF417, -1, 30, 31, 0, { 0, 0, "" }, "12345", ZINT_ERROR_INVALID_OPTION, -1, 0, 0, "Error 475: Columns x rows out of range (1 to 928)", -1 }, /* Rows * cols (930) > 928 */ @@ -160,11 +160,11 @@ static void test_options(const testCtx *const p_ctx) { /* 25*/ { BARCODE_MICROPDF417, -1, 5, -1, WARN_FAIL_ALL, { 0, 0, "" }, "12345", ZINT_ERROR_INVALID_OPTION, -1, 0, 0, "Error 468: Specified width out of range", -1 }, /* Invalid cols */ /* 26*/ { BARCODE_MICROPDF417, -1, 5, 3, 0, { 0, 0, "" }, "12345", ZINT_ERROR_INVALID_OPTION, -1, 0, 0, "Error 476: Cannot specify rows for MicroPDF417", -1 }, /* Rows option not available */ /* 27*/ { BARCODE_MICROPDF417, -1, 1, -1, 0, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLM", ZINT_WARN_INVALID_OPTION, 0, 17, 55, "Warning 469: Specified symbol size too small for data", -1 }, /* Cols 1 too small, auto-upped to 2 with warning */ - /* 28*/ { BARCODE_MICROPDF417, -1, 1, -1, WARN_FAIL_ALL, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLM", ZINT_ERROR_INVALID_OPTION, 0, 0, 0, "Error 469: Specified symbol size too small for data", -1 }, /* Cols 1 too small */ + /* 28*/ { BARCODE_MICROPDF417, -1, 1, -1, WARN_FAIL_ALL, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLM", ZINT_ERROR_INVALID_OPTION, ZINT_ERROR_INVALID_OPTION, 0, 0, "Error 469: Specified symbol size too small for data", -1 }, /* Cols 1 too small */ /* 29*/ { BARCODE_MICROPDF417, -1, 2, -1, 0, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWX", ZINT_WARN_INVALID_OPTION, 0, 15, 99, "Warning 470: Specified symbol size too small for data", -1 }, /* Cols 2 too small, auto-upped to 4 with warning */ - /* 30*/ { BARCODE_MICROPDF417, -1, 2, -1, WARN_FAIL_ALL, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWX", ZINT_ERROR_INVALID_OPTION, 0, 0, 0, "Error 470: Specified symbol size too small for data", -1 }, /* Cols 2 too small */ + /* 30*/ { BARCODE_MICROPDF417, -1, 2, -1, WARN_FAIL_ALL, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWX", ZINT_ERROR_INVALID_OPTION, ZINT_ERROR_INVALID_OPTION, 0, 0, "Error 470: Specified symbol size too small for data", -1 }, /* Cols 2 too small */ /* 31*/ { BARCODE_MICROPDF417, -1, 3, -1, 0, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKL", ZINT_WARN_INVALID_OPTION, 0, 32, 99, "Warning 471: Specified symbol size too small for data", -1 }, /* Cols 3 too small, auto-upped to 4 with warning */ - /* 32*/ { BARCODE_MICROPDF417, -1, 3, -1, WARN_FAIL_ALL, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKL", ZINT_ERROR_INVALID_OPTION, 0, 0, 0, "Error 471: Specified symbol size too small for data", -1 }, /* Cols 3 too small */ + /* 32*/ { BARCODE_MICROPDF417, -1, 3, -1, WARN_FAIL_ALL, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKL", ZINT_ERROR_INVALID_OPTION, ZINT_ERROR_INVALID_OPTION, 0, 0, "Error 471: Specified symbol size too small for data", -1 }, /* Cols 3 too small */ /* 33*/ { BARCODE_PDF417, -1, 1, -1, 0, { 0, 0, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGH", ZINT_WARN_INVALID_OPTION, 0, 89, 103, "Warning 748: Columns increased from 1 to 2", -1 }, /* Cols 1 auto-upped to 2 just fits, now with warning */ /* 34*/ { BARCODE_PDF417, -1, 1, -1, 0, { 1, 2, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGH", ZINT_WARN_INVALID_OPTION, 0, 67, 120, "Warning 748: Columns increased from 1 to 3", -1 }, /* Cols 1 too small with Structured Append, used to fail, now auto-upped to 3 with warning */ /* 35*/ { BARCODE_PDF417, -1, 1, -1, 0, { 1, 2, "" }, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRST", ZINT_WARN_INVALID_OPTION, 0, 89, 103, "Warning 748: Columns increased from 1 to 2", -1 }, /* Cols 1 with Structured Append auto-upped to 2 just fits, now with warning */ diff --git a/backend/tests/test_png.c b/backend/tests/test_png.c index 5a8ecac7..b8f5f497 100644 --- a/backend/tests/test_png.c +++ b/backend/tests/test_png.c @@ -239,6 +239,8 @@ static void test_print(const testCtx *const p_ctx) { char expected_file[1024]; char escaped[1024]; int escaped_size = 1024; + unsigned char filebuf[32768]; + int filebuf_size; char *text; const char *const have_identify = testUtilHaveIdentify(); @@ -330,7 +332,23 @@ static void test_print(const testCtx *const p_ctx) { assert_zero(ret, "i:%d %s testUtilCmpPngs(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); ret = testUtilCmpBins(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpBins(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + + ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size); /* For BARCODE_MEMORY_FILE */ + assert_zero(ret, "i:%d %s testUtilReadFile(%s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret); + + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + } + + symbol->output_options |= BARCODE_MEMORY_FILE; + ret = ZBarcode_Print(symbol, 0); + assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0 (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret, symbol->errtxt); + assert_nonnull(symbol->memfile, "i:%d %s memfile NULL\n", i, testUtilBarcodeName(data[i].symbology)); + assert_equal(symbol->memfile_size, filebuf_size, "i:%d %s memfile_size %d != %d\n", + i, testUtilBarcodeName(data[i].symbology), symbol->memfile_size, filebuf_size); + assert_zero(memcmp(symbol->memfile, filebuf, symbol->memfile_size), "i:%d %s memcmp(memfile, filebuf) != 0\n", + i, testUtilBarcodeName(data[i].symbology)); } ZBarcode_Delete(symbol); diff --git a/backend/tests/test_ps.c b/backend/tests/test_ps.c index 927a076a..cd7fd801 100644 --- a/backend/tests/test_ps.c +++ b/backend/tests/test_ps.c @@ -117,8 +117,9 @@ static void test_print(const testCtx *const p_ctx) { int i, length, ret; struct zint_symbol *symbol = NULL; - const char *data_dir = "/backend/tests/data/eps"; - const char *eps = "out.eps"; + const char data_dir[] = "/backend/tests/data/eps"; + const char eps[] = "out.eps"; + const char memfile[] = "mem.eps"; char expected_file[1024]; char escaped[1024]; int escaped_size = 1024; @@ -193,7 +194,25 @@ static void test_print(const testCtx *const p_ctx) { ret = testUtilCmpEpss(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpEpss(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + + symbol->output_options |= BARCODE_MEMORY_FILE; + ret = ZBarcode_Print(symbol, data[i].rotate_angle); + assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0 (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret, symbol->errtxt); + assert_nonnull(symbol->memfile, "i:%d %s memfile NULL\n", i, testUtilBarcodeName(data[i].symbology)); + assert_nonzero(symbol->memfile_size, "i:%d %s memfile_size 0\n", i, testUtilBarcodeName(data[i].symbology)); + + ret = testUtilWriteFile(memfile, symbol->memfile, symbol->memfile_size, "wb"); + assert_zero(ret, "%d: testUtilWriteFile(%s) fail ret %d != 0\n", i, memfile, ret); + + ret = testUtilCmpEpss(symbol->outfile, memfile); + assert_zero(ret, "i:%d %s testUtilCmpEpss(%s, %s) %d != 0\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, memfile, ret); + + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + assert_zero(testUtilRemove(memfile), "i:%d testUtilRemove(%s) != 0\n", i, memfile); + } } ZBarcode_Delete(symbol); diff --git a/backend/tests/test_svg.c b/backend/tests/test_svg.c index 523d42c9..b5944d52 100644 --- a/backend/tests/test_svg.c +++ b/backend/tests/test_svg.c @@ -144,8 +144,9 @@ static void test_print(const testCtx *const p_ctx) { int i, length, ret; struct zint_symbol *symbol = NULL; - const char *data_dir = "/backend/tests/data/svg"; - const char *svg = "out.svg"; + const char data_dir[] = "/backend/tests/data/svg"; + const char svg[] = "out.svg"; + const char memfile[] = "mem.eps"; char expected_file[1024]; char escaped[1024]; int escaped_size = 1024; @@ -240,7 +241,25 @@ static void test_print(const testCtx *const p_ctx) { ret = testUtilCmpSvgs(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpSvgs(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + + symbol->output_options |= BARCODE_MEMORY_FILE; + ret = ZBarcode_Print(symbol, data[i].rotate_angle); + assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0 (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret, symbol->errtxt); + assert_nonnull(symbol->memfile, "i:%d %s memfile NULL\n", i, testUtilBarcodeName(data[i].symbology)); + assert_nonzero(symbol->memfile_size, "i:%d %s memfile_size 0\n", i, testUtilBarcodeName(data[i].symbology)); + + ret = testUtilWriteFile(memfile, symbol->memfile, symbol->memfile_size, "wb"); + assert_zero(ret, "%d: testUtilWriteFile(%s) fail ret %d != 0\n", i, memfile, ret); + + ret = testUtilCmpSvgs(symbol->outfile, memfile); + assert_zero(ret, "i:%d %s testUtilCmpSvgs(%s, %s) %d != 0\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, memfile, ret); + + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + assert_zero(testUtilRemove(memfile), "i:%d testUtilRemove(%s) != 0\n", i, memfile); + } } ZBarcode_Delete(symbol); diff --git a/backend/tests/test_tif.c b/backend/tests/test_tif.c index 9382aec1..ff1b8ec6 100644 --- a/backend/tests/test_tif.c +++ b/backend/tests/test_tif.c @@ -214,6 +214,8 @@ static void test_print(const testCtx *const p_ctx) { char expected_file[1024]; char escaped[1024]; int escaped_size = 1024; + unsigned char filebuf[32768]; + int filebuf_size; char *text; int have_tiffinfo = testUtilHaveTiffInfo(); @@ -301,7 +303,23 @@ static void test_print(const testCtx *const p_ctx) { ret = testUtilCmpBins(symbol->outfile, expected_file); assert_zero(ret, "i:%d %s testUtilCmpBins(%s, %s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, expected_file, ret); - assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + + ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size); /* For BARCODE_MEMORY_FILE */ + assert_zero(ret, "i:%d %s testUtilReadFile(%s) %d != 0\n", i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret); + + if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) { + assert_zero(testUtilRemove(symbol->outfile), "i:%d testUtilRemove(%s) != 0\n", i, symbol->outfile); + } + + symbol->output_options |= BARCODE_MEMORY_FILE; + ret = ZBarcode_Print(symbol, 0); + assert_zero(ret, "i:%d %s ZBarcode_Print %s ret %d != 0 (%s)\n", + i, testUtilBarcodeName(data[i].symbology), symbol->outfile, ret, symbol->errtxt); + assert_nonnull(symbol->memfile, "i:%d %s memfile NULL\n", i, testUtilBarcodeName(data[i].symbology)); + assert_equal(symbol->memfile_size, filebuf_size, "i:%d %s memfile_size %d != %d\n", + i, testUtilBarcodeName(data[i].symbology), symbol->memfile_size, filebuf_size); + assert_zero(memcmp(symbol->memfile, filebuf, symbol->memfile_size), "i:%d %s memcmp(memfile, filebuf) != 0\n", + i, testUtilBarcodeName(data[i].symbology)); } ZBarcode_Delete(symbol); diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index 868e0afe..4876c0d9 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -1516,6 +1516,67 @@ int testUtilRmROFile(const char *filename) { return testUtilRemove(filename); } +/* Read file into buffer */ +int testUtilReadFile(const char *filename, unsigned char *buffer, int buffer_size, int *p_size) { + long fileLen; + size_t n; + size_t nRead = 0; + FILE *fp = testUtilOpen(filename, "rb"); + if (!fp) { + return 1; + } + if (fseek(fp, 0, SEEK_END) != 0) { + (void) fclose(fp); + return 2; + } + fileLen = ftell(fp); + if (fileLen <= 0 || fileLen == LONG_MAX) { + (void) fclose(fp); + return 3; + } + if (fseek(fp, 0, SEEK_SET) != 0) { + (void) fclose(fp); + return 4; + } + if (fileLen > (long) buffer_size) { + (void) fclose(fp); + return 5; + } + do { + n = fread(buffer + nRead, 1, fileLen - nRead, fp); + if (ferror(fp)) { + (void) fclose(fp); + return 6; + } + nRead += n; + } while (!feof(fp) && (0 < n) && ((long) nRead < fileLen)); + + if (fclose(fp) != 0) { + return 7; + } + + *p_size = (int) nRead; + + return 0; +} + +/* Write file from buffer */ +int testUtilWriteFile(const char *filename, const unsigned char *buffer, const int buffer_size, const char *mode) { + FILE *fp = testUtilOpen(filename, mode); + if (!fp) { + return 1; + } + if (fwrite(buffer, 1, buffer_size, fp) == 0) { + (void) fclose(fp); + return 2; + } + if (fclose(fp) != 0) { + return 3; + } + + return 0; +} + /* Compare 2 PNG files */ int testUtilCmpPngs(const char *png1, const char *png2) { int ret = -1; @@ -3945,7 +4006,15 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in int primary_len = (int) strlen(primary); int maxi_len = 0; if (symbol->option_2 >= 1 && symbol->option_2 <= 100) { +/* Suppress gcc warning null destination pointer [-Wformat-overflow=] false-positive */ +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-overflow=" +#endif sprintf(maxi, "[)>\03601\035%02d", symbol->option_2 - 1); +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif maxi_len = (int) strlen(maxi); } #if 1 diff --git a/backend/tests/testcommon.h b/backend/tests/testcommon.h index 13adfa81..a3be8c8e 100644 --- a/backend/tests/testcommon.h +++ b/backend/tests/testcommon.h @@ -57,7 +57,7 @@ extern "C" { #define testutil_pclose(stream) _pclose(stream) #else #include -# if defined(ZINT_IS_C89) +# if defined(ZINT_IS_C89) || defined(ZINT_IS_C99) extern FILE *popen(const char *command, const char *type); extern int pclose(FILE *stream); # endif @@ -174,6 +174,8 @@ int testUtilRmDir(const char *dirname); int testUtilRename(const char *oldpath, const char *newpath); int testUtilCreateROFile(const char *filename); int testUtilRmROFile(const char *filename); +int testUtilReadFile(const char *filename, unsigned char *buffer, int buffer_size, int *p_size); +int testUtilWriteFile(const char *filename, const unsigned char *buffer, const int buffer_size, const char *mode); int testUtilCmpPngs(const char *file1, const char *file2); int testUtilCmpTxts(const char *txt1, const char *txt2); diff --git a/backend/tests/tools/bwipp_dump.ps.tar.xz b/backend/tests/tools/bwipp_dump.ps.tar.xz index c6e9dd36ad7006a4decac13fb4182c5ba51c4a6d..439006b7c254a34b150ec3b395cd1b4fd6780198 100644 GIT binary patch literal 134068 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

*;di>FmXK$I{vAJ$qT6DBD)Urq4wZcgQ`zxZ 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

&wuKy)DmW*JO{^}%e`~u# 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≠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 #include #include -#ifdef _MSC_VER -#include -#include -#endif #include "common.h" +#include "filemem.h" #include "output.h" #include "tif.h" #include "tif_lzw.h" @@ -97,7 +94,8 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix int strip_row; unsigned int bytes_put; long total_bytes_put; - FILE *tif_file; + struct filemem fm; + struct filemem *const fmp = &fm; const unsigned char *pb; int compression = TIF_NO_COMPRESSION; tif_lzw_state lzw_state; @@ -315,19 +313,11 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix } /* Open output file in binary mode */ - if (output_to_stdout) { -#ifdef _MSC_VER - if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - sprintf(symbol->errtxt, "671: Could not set stdout to binary (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } -#endif - tif_file = stdout; - } else { - if (!(tif_file = out_fopen(symbol->outfile, "wb+"))) { /* '+' as use fseek/ftell() */ - sprintf(symbol->errtxt, "672: Could not open output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_ACCESS; - } + if (!fm_open(fmp, symbol, "wb")) { + sprintf(symbol->errtxt, "672: Could not open output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_ACCESS; + } + if (!output_to_stdout) { compression = TIF_LZW; tif_lzw_init(&lzw_state); } @@ -341,7 +331,7 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix header.identity = 42; header.offset = (uint32_t) free_memory; - fwrite(&header, sizeof(tiff_header_t), 1, tif_file); + fm_write(&header, sizeof(tiff_header_t), 1, fmp); total_bytes_put = sizeof(tiff_header_t); /* Pixel data */ @@ -387,14 +377,14 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix if (strip_row == rows_per_strip || (strip == strip_count - 1 && strip_row == rows_last_strip)) { /* End of strip */ if (compression == TIF_LZW) { - file_pos = ftell(tif_file); - if (!tif_lzw_encode(&lzw_state, tif_file, strip_buf, bytes_put)) { /* Only fails if can't malloc */ + file_pos = fm_tell(fmp); + if (!tif_lzw_encode(&lzw_state, fmp, strip_buf, bytes_put)) { /* Only fails if can't malloc */ tif_lzw_cleanup(&lzw_state); - (void) fclose(tif_file); /* Only use LZW if not STDOUT, so ok to close */ + (void) fm_close(fmp, symbol); strcpy(symbol->errtxt, "673: Failed to malloc LZW hash table"); return ZINT_ERROR_MEMORY; } - bytes_put = ftell(tif_file) - file_pos; + bytes_put = fm_tell(fmp) - file_pos; if (bytes_put != strip_bytes[strip]) { const int diff = bytes_put - strip_bytes[strip]; strip_bytes[strip] = bytes_put; @@ -403,7 +393,7 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix } } } else { - fwrite(strip_buf, 1, bytes_put, tif_file); + fm_write(strip_buf, 1, bytes_put, fmp); } strip++; total_bytes_put += bytes_put; @@ -415,27 +405,25 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix } if (total_bytes_put & 1) { - putc(0, tif_file); /* IFD must be on word boundary */ + fm_putc(0, fmp); /* IFD must be on word boundary */ total_bytes_put++; } if (compression == TIF_LZW) { tif_lzw_cleanup(&lzw_state); - file_pos = ftell(tif_file); - fseek(tif_file, 4, SEEK_SET); + file_pos = fm_tell(fmp); + fm_seek(fmp, 4, SEEK_SET); free_memory = file_pos; temp32 = (uint32_t) free_memory; /* Shouldn't happen as `free_memory` checked above to be <= 0xffff0000 & should only decrease */ if (free_memory != temp32 || (long) free_memory != file_pos) { strcpy(symbol->errtxt, "982: Output file size too big"); - if (!output_to_stdout) { - (void) fclose(tif_file); - } + (void) fm_close(fmp, symbol); return ZINT_ERROR_MEMORY; } - fwrite(&temp32, 4, 1, tif_file); - fseek(tif_file, file_pos, SEEK_SET); + fm_write(&temp32, 4, 1, fmp); + fm_seek(fmp, file_pos, SEEK_SET); } /* Image File Directory */ @@ -504,7 +492,7 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix tags[entries++].offset = strip_bytes[0]; } else { update_offsets[offsets++] = entries; - tags[entries++].offset = free_memory; + tags[entries++].offset = (uint32_t) free_memory; free_memory += strip_count * 4; } @@ -512,14 +500,14 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix tags[entries].type = 5; /* RATIONAL */ tags[entries].count = 1; update_offsets[offsets++] = entries; - tags[entries++].offset = free_memory; + tags[entries++].offset = (uint32_t) free_memory; free_memory += 8; tags[entries].tag = 0x011b; /* YResolution */ tags[entries].type = 5; /* RATIONAL */ tags[entries].count = 1; update_offsets[offsets++] = entries; - tags[entries++].offset = free_memory; + tags[entries++].offset = (uint32_t) free_memory; free_memory += 8; tags[entries].tag = 0x0128; /* ResolutionUnit */ @@ -552,14 +540,14 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix tags[update_offsets[i]].offset += ifd_size; } - fwrite(&entries, sizeof(entries), 1, tif_file); - fwrite(&tags, sizeof(tiff_tag_t), entries, tif_file); - fwrite(&offset, sizeof(offset), 1, tif_file); + fm_write(&entries, sizeof(entries), 1, fmp); + fm_write(&tags, sizeof(tiff_tag_t), entries, fmp); + fm_write(&offset, sizeof(offset), 1, fmp); total_bytes_put += ifd_size; if (samples_per_pixel > 2) { for (i = 0; i < samples_per_pixel; i++) { - fwrite(&bits_per_sample, sizeof(bits_per_sample), 1, tif_file); + fm_write(&bits_per_sample, sizeof(bits_per_sample), 1, fmp); } total_bytes_put += sizeof(bits_per_sample) * samples_per_pixel; } @@ -567,66 +555,59 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix if (strip_count != 1) { /* Strip offsets */ for (i = 0; i < strip_count; i++) { - fwrite(&strip_offset[i], 4, 1, tif_file); + fm_write(&strip_offset[i], 4, 1, fmp); } /* Strip byte lengths */ for (i = 0; i < strip_count; i++) { - fwrite(&strip_bytes[i], 4, 1, tif_file); + fm_write(&strip_bytes[i], 4, 1, fmp); } total_bytes_put += strip_count * 8; } /* XResolution */ temp32 = symbol->dpmm ? symbol->dpmm : 72; - fwrite(&temp32, 4, 1, tif_file); + fm_write(&temp32, 4, 1, fmp); temp32 = symbol->dpmm ? 10 /*cm*/ : 1; - fwrite(&temp32, 4, 1, tif_file); + fm_write(&temp32, 4, 1, fmp); total_bytes_put += 8; /* YResolution */ temp32 = symbol->dpmm ? symbol->dpmm : 72; - fwrite(&temp32, 4, 1, tif_file); + fm_write(&temp32, 4, 1, fmp); temp32 = symbol->dpmm ? 10 /*cm*/ : 1; - fwrite(&temp32, 4, 1, tif_file); + fm_write(&temp32, 4, 1, fmp); total_bytes_put += 8; if (color_map_size) { for (i = 0; i < color_map_size; i++) { - fwrite(&color_map[i].red, 2, 1, tif_file); + fm_write(&color_map[i].red, 2, 1, fmp); } for (i = 0; i < color_map_size; i++) { - fwrite(&color_map[i].green, 2, 1, tif_file); + fm_write(&color_map[i].green, 2, 1, fmp); } for (i = 0; i < color_map_size; i++) { - fwrite(&color_map[i].blue, 2, 1, tif_file); + fm_write(&color_map[i].blue, 2, 1, fmp); } total_bytes_put += 6 * color_map_size; } - if (ferror(tif_file)) { - sprintf(symbol->errtxt, "679: Incomplete write to output (%d: %.30s)", errno, strerror(errno)); - if (!output_to_stdout) { - (void) fclose(tif_file); - } + if (fm_error(fmp)) { + sprintf(symbol->errtxt, "679: Incomplete write to output (%d: %.30s)", fmp->err, strerror(fmp->err)); + (void) fm_close(fmp, symbol); return ZINT_ERROR_FILE_WRITE; } - if (output_to_stdout) { - if (fflush(tif_file) != 0) { - sprintf(symbol->errtxt, "980: Incomplete flush to output (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } - } else { - if (ftell(tif_file) != total_bytes_put) { - (void) fclose(tif_file); + if (!output_to_stdout) { + if (fm_tell(fmp) != total_bytes_put) { + (void) fm_close(fmp, symbol); strcpy(symbol->errtxt, "674: Failed to write all output"); return ZINT_ERROR_FILE_WRITE; } - if (fclose(tif_file) != 0) { - sprintf(symbol->errtxt, "981: Failure on closing output file (%d: %.30s)", errno, strerror(errno)); - return ZINT_ERROR_FILE_WRITE; - } + } + if (!fm_close(fmp, symbol)) { + sprintf(symbol->errtxt, "981: Failure on closing output file (%d: %.30s)", fmp->err, strerror(fmp->err)); + return ZINT_ERROR_FILE_WRITE; } return 0; diff --git a/backend/tif_lzw.h b/backend/tif_lzw.h index 06ce722a..75b73f3c 100644 --- a/backend/tif_lzw.h +++ b/backend/tif_lzw.h @@ -161,13 +161,13 @@ static void tif_lzw_cl_hash(tif_lzw_state *sp) { } /* Explicit 0xff masking to make icc -check=conversions happy */ -#define PutNextCode(op_file, c) { \ +#define PutNextCode(op_fmp, c) { \ nextdata = (nextdata << nbits) | c; \ nextbits += nbits; \ - putc((nextdata >> (nextbits - 8)) & 0xff, op_file); \ + fm_putc((nextdata >> (nextbits - 8)) & 0xff, op_fmp); \ nextbits -= 8; \ if (nextbits >= 8) { \ - putc((nextdata >> (nextbits - 8)) & 0xff, op_file); \ + fm_putc((nextdata >> (nextbits - 8)) & 0xff, op_fmp); \ nextbits -= 8; \ } \ outcount += nbits; \ @@ -187,7 +187,7 @@ static void tif_lzw_cl_hash(tif_lzw_state *sp) { * are re-sized at this point, and a CODE_CLEAR is generated * for the decoder. */ -static int tif_lzw_encode(tif_lzw_state *sp, FILE *op_file, const unsigned char *bp, int cc) { +static int tif_lzw_encode(tif_lzw_state *sp, struct filemem *op_fmp, const unsigned char *bp, int cc) { register long fcode; register tif_lzw_hash *hp; register int h, c; @@ -229,7 +229,7 @@ static int tif_lzw_encode(tif_lzw_state *sp, FILE *op_file, const unsigned char ent = (tif_lzw_hcode) -1; if (cc > 0) { - PutNextCode(op_file, CODE_CLEAR); + PutNextCode(op_fmp, CODE_CLEAR); ent = *bp++; cc--; incount++; } while (cc > 0) { @@ -275,7 +275,7 @@ static int tif_lzw_encode(tif_lzw_state *sp, FILE *op_file, const unsigned char /* * New entry, emit code and add to table. */ - PutNextCode(op_file, ent); + PutNextCode(op_fmp, ent); ent = (tif_lzw_hcode) c; hp->code = (tif_lzw_hcode) (free_ent++); hp->hash = fcode; @@ -286,7 +286,7 @@ static int tif_lzw_encode(tif_lzw_state *sp, FILE *op_file, const unsigned char incount = 0; outcount = 0; free_ent = CODE_FIRST; - PutNextCode(op_file, CODE_CLEAR); + PutNextCode(op_fmp, CODE_CLEAR); nbits = BITS_MIN; maxcode = MAXCODE(BITS_MIN); } else { @@ -314,7 +314,7 @@ static int tif_lzw_encode(tif_lzw_state *sp, FILE *op_file, const unsigned char incount = 0; outcount = 0; free_ent = CODE_FIRST; - PutNextCode(op_file, CODE_CLEAR); + PutNextCode(op_fmp, CODE_CLEAR); nbits = BITS_MIN; maxcode = MAXCODE(BITS_MIN); } else { @@ -332,13 +332,13 @@ static int tif_lzw_encode(tif_lzw_state *sp, FILE *op_file, const unsigned char */ if (ent != (tif_lzw_hcode) -1) { - PutNextCode(op_file, ent); + PutNextCode(op_fmp, ent); free_ent++; if (free_ent == CODE_MAX - 1) { /* table is full, emit clear code and reset */ outcount = 0; - PutNextCode(op_file, CODE_CLEAR); + PutNextCode(op_fmp, CODE_CLEAR); nbits = BITS_MIN; } else { /* @@ -351,10 +351,10 @@ static int tif_lzw_encode(tif_lzw_state *sp, FILE *op_file, const unsigned char } } } - PutNextCode(op_file, CODE_EOI); + PutNextCode(op_fmp, CODE_EOI); /* Explicit 0xff masking to make icc -check=conversions happy */ if (nextbits > 0) { - putc((nextdata << (8 - nextbits)) & 0xff, op_file); + fm_putc((nextdata << (8 - nextbits)) & 0xff, op_fmp); } return 1; diff --git a/backend/vector.c b/backend/vector.c index 71396d12..b95f4d54 100644 --- a/backend/vector.c +++ b/backend/vector.c @@ -409,8 +409,8 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ const float descent_small = 0.948426545f; /* Arimo value for SMALL_TEXT (font height 5) */ /* For UPC/EAN only */ - float addon_row_yposn; - float addon_row_height; + float addon_row_yposn = 0.0f; /* Suppress gcc -Wmaybe-uninitialized false positive */ + float addon_row_height = 0.0f; /* Ditto */ int upcae_outside_font_height = 0; /* UPC-A/E outside digits font size */ const float gws_left_fudge = 0.5f; /* These make the guard whitespaces appear closer to the edge for SVG/qzint */ const float gws_right_fudge = 0.5f; /* (undone by EMF/EPS) */ @@ -443,6 +443,10 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ if (error_number != 0) { return error_number; } + if (symbol->rows <= 0) { + strcpy(symbol->errtxt, "697: No rows"); + return ZINT_ERROR_INVALID_OPTION; + } /* Allocate memory */ vector = symbol->vector = (struct zint_vector *) malloc(sizeof(struct zint_vector)); diff --git a/backend/zint.h b/backend/zint.h index a564fe59..e974eba0 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -131,6 +131,8 @@ extern "C" { int bitmap_height; /* Height of bitmap image (raster output only) */ unsigned char *alphamap; /* Array of alpha values used (raster output only) */ struct zint_vector *vector; /* Pointer to vector header (vector output only) */ + unsigned char *memfile; /* Pointer to in-memory file buffer if BARCODE_MEMORY_FILE (output only) */ + int memfile_size; /* Length of in-memory file buffer (output only) */ }; /* Segment for use with `ZBarcode_Encode_Segs()` below */ @@ -273,25 +275,26 @@ extern "C" { #define BARCODE_LAST 146 /* Max barcode number marker, not barcode */ /* Output options (`symbol->output_options`) */ -#define BARCODE_BIND_TOP 0x0001 /* Boundary bar above the symbol only (not below), does not affect stacking */ +#define BARCODE_BIND_TOP 0x00001 /* Boundary bar above the symbol only (not below), does not affect stacking */ /* Note: value was once used by the legacy (never-used) BARCODE_NO_ASCII */ -#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) */ +#define BARCODE_BIND 0x00002 /* Boundary bars above & below the symbol and between stacked symbols */ +#define BARCODE_BOX 0x00004 /* Box around symbol */ +#define BARCODE_STDOUT 0x00008 /* Output to stdout */ +#define READER_INIT 0x00010 /* Reader Initialisation (Programming) */ +#define SMALL_TEXT 0x00020 /* Use smaller font */ +#define BOLD_TEXT 0x00040 /* Use bold font */ +#define CMYK_COLOUR 0x00080 /* CMYK colour space (Encapsulated PostScript and TIF) */ +#define BARCODE_DOTTY_MODE 0x00100 /* Plot a matrix symbol using dots rather than squares */ +#define GS1_GS_SEPARATOR 0x00200 /* Use GS instead of FNC1 as GS1 separator (Data Matrix) */ +#define OUT_BUFFER_INTERMEDIATE 0x00400 /* Return ASCII values in bitmap buffer (OUT_BUFFER only) */ +#define BARCODE_QUIET_ZONES 0x00800 /* 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, or use standard height (if any) as default */ -#define EANUPC_GUARD_WHITESPACE 0x4000 /* Add quiet zone indicators ("<"/">") to HRT whitespace (EAN/UPC) */ -#define EMBED_VECTOR_FONT 0x8000 /* Embed font in vector output - currently only for SVG output */ +#define BARCODE_NO_QUIET_ZONES 0x01000 /* Disable quiet zones, notably those with defaults as listed above */ +#define COMPLIANT_HEIGHT 0x02000 /* Warn if height not compliant, or use standard height (if any) as default */ +#define EANUPC_GUARD_WHITESPACE 0x04000 /* Add quiet zone indicators ("<"/">") to HRT whitespace (EAN/UPC) */ +#define EMBED_VECTOR_FONT 0x08000 /* Embed font in vector output - currently only for SVG output */ +#define BARCODE_MEMORY_FILE 0x10000 /* Write output to in-memory buffer `memfile` instead of to `outfile` */ /* Input data types (`symbol->input_mode`) */ #define DATA_MODE 0 /* Binary */ diff --git a/backend_qt/backend_qt.pro b/backend_qt/backend_qt.pro index bba1e6e7..c6578491 100644 --- a/backend_qt/backend_qt.pro +++ b/backend_qt/backend_qt.pro @@ -42,6 +42,7 @@ HEADERS += ../backend/aztec.h \ ../backend/gb18030.h \ ../backend/gb2312.h \ ../backend/gbk.h \ + ../backend/filemem.h \ ../backend/general_field.h \ ../backend/gridmtx.h \ ../backend/gs1.h \ @@ -86,6 +87,7 @@ SOURCES += ../backend/2of5.c \ ../backend/dotcode.c \ ../backend/eci.c \ ../backend/emf.c \ + ../backend/filemem.c \ ../backend/general_field.c \ ../backend/gif.c \ ../backend/gridmtx.c \ diff --git a/backend_qt/backend_vc8.pro b/backend_qt/backend_vc8.pro index 7a13213a..36180d04 100644 --- a/backend_qt/backend_vc8.pro +++ b/backend_qt/backend_vc8.pro @@ -33,6 +33,7 @@ HEADERS += ../backend/aztec.h \ ../backend/gb18030.h \ ../backend/gb2312.h \ ../backend/gbk.h \ + ../backend/filemem.h \ ../backend/general_field.h \ ../backend/gridmtx.h \ ../backend/gs1.h \ @@ -70,6 +71,7 @@ SOURCES += ../backend/2of5.c \ ../backend/eci.c \ ../backend/emf.c \ ../backend/gridmtx.c \ + ../backend/filemem.c \ ../backend/general_field.c \ ../backend/gif.c \ ../backend/gs1.c \ diff --git a/backend_tcl/configure b/backend_tcl/configure index 4d3251ea..752ed65c 100755 --- a/backend_tcl/configure +++ b/backend_tcl/configure @@ -5361,6 +5361,7 @@ printf "%s\n" "$ac_cv_c_bigendian" >&6; } ../backend/dotcode.c ../backend/eci.c ../backend/emf.c + ../backend/filemem.c ../backend/general_field.c ../backend/gif.c ../backend/gridmtx.c diff --git a/backend_tcl/configure.ac b/backend_tcl/configure.ac index e66a46d0..cb973b94 100644 --- a/backend_tcl/configure.ac +++ b/backend_tcl/configure.ac @@ -90,6 +90,7 @@ TEA_ADD_SOURCES([ ../backend/dotcode.c ../backend/eci.c ../backend/emf.c + ../backend/filemem.c ../backend/general_field.c ../backend/gif.c ../backend/gridmtx.c diff --git a/backend_tcl/zint_tcl.dsp b/backend_tcl/zint_tcl.dsp index 7addf506..89b99d93 100644 --- a/backend_tcl/zint_tcl.dsp +++ b/backend_tcl/zint_tcl.dsp @@ -161,6 +161,10 @@ SOURCE=..\backend\emf.c # End Source File # Begin Source File +SOURCE=..\backend\filemem.c +# End Source File +# Begin Source File + SOURCE=..\backend\general_field.c # End Source File # Begin Source File diff --git a/docs/manual.html b/docs/manual.html index d6aa0fa8..8f369c9b 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -464,27 +464,30 @@ Memory (raster)

  • 5.5 Buffering Symbols in Memory (vector)
  • -
  • 5.6 Setting +
  • 5.6 Buffering Symbols in +Memory (memfile)
  • +
  • 5.7 Setting Options
  • -
  • 5.7 Handling +
  • 5.8 Handling Errors
  • 5.8 Specifying a Symbology
  • +id="toc-specifying-a-symbology">5.9 Specifying a Symbology
  • 5.9 Adjusting Output Options
  • +id="toc-adjusting-output-options">5.10 Adjusting Output Options
  • 5.10 Setting the Input Mode
  • -
  • 5.11 +id="toc-setting-the-input-mode">5.11 Setting the Input Mode
  • +
  • 5.12 Multiple Segments
  • -
  • 5.12 Scaling +
  • 5.13 Scaling Helpers
  • 5.13 Verifying Symbology +id="toc-verifying-symbology-availability">5.14 Verifying Symbology Availability
  • 5.14 Checking Symbology +id="toc-checking-symbology-capabilities">5.15 Checking Symbology Capabilities
  • -
  • 5.15 Zint +
  • 5.16 Zint Version
  • 6. Types @@ -2197,7 +2200,7 @@ alt="zint -d "This Text" --fg=00FF0055" /> -

    will produce a semi-transparent green foreground with standard +

    will produce a semi-transparent green foreground with a standard (white) background. Note that transparency is treated differently by raster and vector (SVG) output formats, as for vector output the background will “shine through” a transparent foreground. For @@ -3138,7 +3141,7 @@ example:

    Note that when using the API, the input data is assumed to be 8-bit binary unless the input_mode member of the zint_symbol structure is set - see 5.10 Setting the Input Mode for +href="#setting-the-input-mode">5.11 Setting the Input Mode for details.

    5.3 Encoding and Printing Functions in Depth

    @@ -3293,14 +3296,43 @@ available:

    for (circle = my_symbol->vector->circles; circle; circle = circle->next) { draw_circle(circle->x, circle->y, circle->diameter, circle->width); } -

    5.6 Setting Options

    +

    5.6 Buffering Symbols in +Memory (memfile)

    +

    Symbols can also be stored as “in-memory” file buffers by giving the +BARCODE_MEMORY_FILE option to the +output_options member, which saves the print output to +member memfile instead of to the output file +outfile. The length of the buffer is given in +memfile_size. For instance:

    +
    #include <zint.h>
    +#include <stdio.h>
    +#include <string.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_symbol *my_symbol;
    +    my_symbol = ZBarcode_Create();
    +    my_symbol->output_options |= BARCODE_MEMORY_FILE;
    +    /* Only the extension is used, to determine output format */
    +    strcpy(my_symbol->outfile, "mem.svg");
    +    ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0);
    +    /* `my_symbol->memfile` now contains the SVG output */
    +    fwrite(my_symbol->memfile, 1, my_symbol->memfile_size, stdout);
    +    ZBarcode_Delete(my_symbol);
    +    return 0;
    +}
    +

    will print the SVG output to stdout (the file “mem.svg” +is not created). This is particularly useful for the textual formats EPS +and SVG,7 allowing the output to be +manipulated and processed by the client.

    +

    5.7 Setting Options

    So far our application is not very useful unless we plan to only make Code 128 symbols and we don’t mind that they only save to -"out.png". As with the CLI program, of course, these -options can be altered. The way this is done is by altering the contents -of the zint_symbol structure between the creation and -encoding stages. The zint_symbol structure consists of the -following members:

    +"out.png" (or to memory, as above). As with the CLI +program, of course, these options can be altered. The way this is done +is by altering the contents of the zint_symbol structure +between the creation and encoding stages. The zint_symbol +structure consists of the following members:

    +href="#specifying-a-symbology">5.9 Specifying a Symbology. +fixed width-to-height symbols.8 @@ -3366,7 +3398,7 @@ X-dimensions. +href="#adjusting-output-options">5.10 Adjusting Output Options. @@ -3407,8 +3439,8 @@ resulting barcode symbol to. Must end in .png, .gif, .bmp, .emf, .eps, .pcx, .svg, .tif or .txt followed by a terminating -NUL.8 +NUL.9 @@ -3447,7 +3479,7 @@ symbols, with a terminating NUL. +href="#setting-the-input-mode">5.11 Setting the Input Mode. @@ -3501,7 +3533,7 @@ symbols. +Zint API - see 5.8 Handling Errors. @@ -3541,7 +3573,7 @@ with a terminating NUL. +href="#handling-errors">5.8 Handling Errors. @@ -3583,31 +3615,46 @@ href="#buffering-symbols-in-memory-vector">5.5 Buffering Symbols in Memory (vector). + + + + + + + + + + + +
    Table  : API @@ -3324,15 +3356,15 @@ Structure zint_symbol
    symbology integer Symbol to use - see 5.8 Specifying a Symbology. BARCODE_CODE128
    height float Symbol height in X-dimensions, excluding -fixed width-to-height symbols.7 Symbol dependent
    output_options integer Set various output parameters - see 5.9 Adjusting Output Options. 0 (none)
    "out.png"
    input_mode integer Set encoding of input data - see 5.10 Setting the Input Mode. DATA_MODE
    warn_level integer Affects error/warning value returned by -Zint API - see 5.7 Handling Errors. WARN_DEFAULT
    character string Error message in the event that an error occurred, with a terminating NUL - see 5.7 Handling Errors. (output only)
    (output only)
    memfilepointer to unsigned character arrayPointer to in-memory file buffer if +BARCODE_MEMORY_FILE set in output_options - +see 5.6 Buffering Symbols +in Memory (memfile).(output only)
    memfile_sizeintegerLength of in-memory file buffer.(output only)

    To alter these values use the syntax shown in the example below. This code has the same result as the previous example except the output is now taller and plotted in green.

    -
    #include <zint.h>
    -#include <string.h>
    -int main(int argc, char **argv)
    -{
    -    struct zint_symbol *my_symbol;
    -    my_symbol = ZBarcode_Create();
    -    strcpy(my_symbol->fgcolour, "00ff00");
    -    my_symbol->height = 400.0f;
    -    ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0);
    -    ZBarcode_Delete(my_symbol);
    -    return 0;
    -}
    +
    #include <zint.h>
    +#include <string.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_symbol *my_symbol;
    +    my_symbol = ZBarcode_Create();
    +    strcpy(my_symbol->fgcolour, "00ff00");
    +    my_symbol->height = 400.0f;
    +    ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0);
    +    ZBarcode_Delete(my_symbol);
    +    return 0;
    +}

    Note that background removal for all outputs except BMP can be achieved by setting the background alpha to "00" where the values for R, G and B will be ignored:

    -
        strcpy(my_symbol->bgcolour, "55555500");
    +
        strcpy(my_symbol->bgcolour, "55555500");

    This is what the CLI option --nobackground does - see 4.7 Using Colour.

    -

    5.7 Handling Errors

    +

    5.8 Handling Errors

    If errors occur during encoding a non-zero integer value is passed back to the calling application. In addition the errtxt member is set to a message detailing the nature of the error. The errors @@ -3726,47 +3773,47 @@ occurs.

    To catch errors use an integer variable as shown in the code below:

    -
    #include <zint.h>
    -#include <stdio.h>
    -#include <string.h>
    -int main(int argc, char **argv)
    -{
    -    struct zint_symbol *my_symbol;
    -    int error;
    -    my_symbol = ZBarcode_Create();
    -    /* Set invalid foreground colour */
    -    strcpy(my_symbol->fgcolour, "nonsense");
    -    error = ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0);
    -    if (error != 0) {
    -        /* Some warning or error occurred */
    -        printf("%s\n", my_symbol->errtxt);
    -        if (error >= ZINT_ERROR) {
    -            /* Stop now */
    -            ZBarcode_Delete(my_symbol);
    -            return 1;
    -        }
    -    }
    -    /* Otherwise carry on with the rest of the application */
    -    ZBarcode_Delete(my_symbol);
    -    return 0;
    -}
    +
    #include <zint.h>
    +#include <stdio.h>
    +#include <string.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_symbol *my_symbol;
    +    int error;
    +    my_symbol = ZBarcode_Create();
    +    /* Set invalid foreground colour */
    +    strcpy(my_symbol->fgcolour, "nonsense");
    +    error = ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0);
    +    if (error != 0) {
    +        /* Some warning or error occurred */
    +        printf("%s\n", my_symbol->errtxt);
    +        if (error >= ZINT_ERROR) {
    +            /* Stop now */
    +            ZBarcode_Delete(my_symbol);
    +            return 1;
    +        }
    +    }
    +    /* Otherwise carry on with the rest of the application */
    +    ZBarcode_Delete(my_symbol);
    +    return 0;
    +}

    This code will exit with the appropriate message:

    Error 881: Malformed foreground RGB colour 'nonsense' (hexadecimal only)

    To treat all warnings as errors, set symbol->warn_level to WARN_FAIL_ALL.

    -

    5.8 Specifying a Symbology

    +

    5.9 Specifying a Symbology

    Symbologies can be specified by number or by name as shown in the Table : Barcode Types (Symbologies). For example

    -
    symbol->symbology = BARCODE_LOGMARS;
    +
    symbol->symbology = BARCODE_LOGMARS;

    means the same as

    -
    symbol->symbology = 50;
    -

    5.9 Adjusting Output Options

    +
    symbol->symbology = 50;
    +

    5.10 Adjusting Output Options

    The output_options member can be used to adjust various aspects of the output file. To select more than one option from the table below simply OR them together when adjusting this value:

    -
    my_symbol->output_options |= BARCODE_BIND | READER_INIT;
    +
    my_symbol->output_options |= BARCODE_BIND | READER_INIT;
    +href="#fn10" class="footnote-ref" id="fnref10" +role="doc-noteref">10 +and between rows if stacking multiple symbols.11 @@ -3847,8 +3894,8 @@ Memory (raster). +any specified whitespace).12 @@ -3870,10 +3917,16 @@ use standard height (if any) as default. + + + +
    Table  : API @@ -3789,15 +3836,15 @@ value:

    BARCODE_BIND_TOP Boundary bar above the symbol only.9
    BARCODE_BIND Boundary bars above and below the symbol -and between rows if stacking multiple symbols.10
    BARCODE_BOX
    BARCODE_QUIET_ZONES Add compliant quiet zones (additional to -any specified whitespace).11
    BARCODE_NO_QUIET_ZONES Embed font in vector output - currently available for SVG output only.
    BARCODE_MEMORY_FILEWrite output to in-memory buffer +symbol->memfile instead of to outfile +file.
    -

    5.10 Setting the Input Mode

    +

    5.11 Setting the Input Mode

    The way in which the input data is encoded can be set using the input_mode member. Valid values are shown in the table below.

    @@ -3958,11 +4011,11 @@ from the default for the CLI and GUI, which is GS1NOCHECK_MODE, HEIGHTPERROW_MODE, FAST_MODE and EXTRA_ESCAPE_MODE are optional. So, for example, you can set

    -
    my_symbol->input_mode = UNICODE_MODE | ESCAPE_MODE;
    +
    my_symbol->input_mode = UNICODE_MODE | ESCAPE_MODE;

    or

    -
    my_symbol->input_mode = GS1_MODE | GS1PARENS_MODE | GS1NOCHECK_MODE;
    +
    my_symbol->input_mode = GS1_MODE | GS1PARENS_MODE | GS1NOCHECK_MODE;

    whereas

    -
    my_symbol->input_mode = DATA_MODE | GS1_MODE;
    +
    my_symbol->input_mode = DATA_MODE | GS1_MODE;

    is not valid.

    Permissible escape sequences (ESCAPE_MODE) are listed in Table : Escape Sequences, and the @@ -3983,20 +4036,20 @@ input (it will be set to the overall height on output).

    used for Data Matrix, MicroPDF417 and PDF417. For QR Code and UPNQR, it affects Zint’s automatic mask selection - see 6.6.3 QR Code (ISO 18004) for details.

    -

    5.11 Multiple Segments

    +

    5.12 Multiple Segments

    For input data requiring multiple ECIs, the following functions may be used:

    -
    int ZBarcode_Encode_Segs(struct zint_symbol *symbol,
    -      const struct zint_seg segs[], const int seg_count);
    -
    -int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol,
    -      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    -
    -int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol,
    -      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    -
    -int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol,
    -      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    +
    int ZBarcode_Encode_Segs(struct zint_symbol *symbol,
    +      const struct zint_seg segs[], const int seg_count);
    +
    +int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol,
    +      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    +
    +int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol,
    +      const struct zint_seg segs[], const int seg_count, int rotate_angle);
    +
    +int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol,
    +      const struct zint_seg segs[], const int seg_count, int rotate_angle);

    These are direct analogues of the previously mentioned ZBarcode_Encode(), ZBarcode_Encode_and_Print(), @@ -4007,44 +4060,44 @@ consisting of "segs, seg_count" is given, with segs being an array of struct zint_seg segments and seg_count being the number of elements it contains. The zint_seg structure is of the form:

    -
    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 */
    -};
    +
    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 */
    +};

    The symbology must support ECIs (see Table : ECI-Aware Symbologies). For example:

    -
    #include <zint.h>
    -int main(int argc, char **argv)
    -{
    -    struct zint_seg segs[] = {
    -        { "Κείμενο", 0, 9 },
    -        { "Текст", 0, 7 },
    -        { "文章", 0, 20 }
    -    };
    -    struct zint_symbol *my_symbol;
    -    my_symbol = ZBarcode_Create();
    -    my_symbol->symbology = BARCODE_AZTEC;
    -    my_symbol->input_mode = UNICODE_MODE;
    -    ZBarcode_Encode_Segs(my_symbol, segs, 3);
    -    ZBarcode_Print(my_symbol, 0);
    -    ZBarcode_Delete(my_symbol);
    -    return 0;
    -}
    +
    #include <zint.h>
    +int main(int argc, char **argv)
    +{
    +    struct zint_seg segs[] = {
    +        { "Κείμενο", 0, 9 },
    +        { "Текст", 0, 7 },
    +        { "文章", 0, 20 }
    +    };
    +    struct zint_symbol *my_symbol;
    +    my_symbol = ZBarcode_Create();
    +    my_symbol->symbology = BARCODE_AZTEC;
    +    my_symbol->input_mode = UNICODE_MODE;
    +    ZBarcode_Encode_Segs(my_symbol, segs, 3);
    +    ZBarcode_Print(my_symbol, 0);
    +    ZBarcode_Delete(my_symbol);
    +    return 0;
    +}

    A maximum of 256 segments may be specified. Use of multiple segments with GS1 data is not currently supported.

    -

    5.12 Scaling Helpers

    +

    5.13 Scaling Helpers

    To help with scaling the output, the following three function are available:

    -
    float ZBarcode_Default_Xdim(int symbol_id);
    -
    -float ZBarcode_Scale_From_XdimDp(int symbol_id, float x_dim_mm, float dpmm,
    -        const char *filetype) {
    -
    -float ZBarcode_XdimDP_From_Scale(int symbol_id, float scale,
    -        float x_dim_mm_or_dpmm, const char *filetype);
    +
    float ZBarcode_Default_Xdim(int symbol_id);
    +
    +float ZBarcode_Scale_From_XdimDp(int symbol_id, float x_dim_mm, float dpmm,
    +        const char *filetype) {
    +
    +float ZBarcode_XdimDP_From_Scale(int symbol_id, float scale,
    +        float x_dim_mm_or_dpmm, const char *filetype);

    The first ZBarcode_Default_Xdim() returns the default X-dimension suggested by Zint for symbology symbol_id.

    The second ZBarcode_Scale_From_XdimDp() returns the @@ -4056,13 +4109,13 @@ however dpmm may be zero and defaults to 12 dpmm, and is assumed. For raster output (BMP/GIF/PCX/PNG/TIF) the scale is rounded to half-integer increments.

    For example:

    -
    /* Royal Mail 4-State Customer Code */
    -my_symbol->symbology = BARCODE_RM4SCC;
    -my_symbol->dpmm = 600.0f / 25.4f; /* 600 dpi */
    -my_symbol->scale = ZBarcode_Scale_From_XdimDp(
    -                        my_symbol->symbology,
    -                        ZBarcode_Default_Xdim(my_symbol->symbology),
    -                        my_symbol->dpmm, "PNG"); /* Returns 7.5 */
    +
    /* Royal Mail 4-State Customer Code */
    +my_symbol->symbology = BARCODE_RM4SCC;
    +my_symbol->dpmm = 600.0f / 25.4f; /* 600 dpi */
    +my_symbol->scale = ZBarcode_Scale_From_XdimDp(
    +                        my_symbol->symbology,
    +                        ZBarcode_Default_Xdim(my_symbol->symbology),
    +                        my_symbol->dpmm, "PNG"); /* Returns 7.5 */

    The third function ZBarcode_XdimDP_From_Scale() is the “reverse” of ZBarcode_Scale_From_XdimDp(), returning the X-dimension (in mm) or the dot density (in dpmm) given a scale @@ -4074,33 +4127,33 @@ bound to the maximum value of dpmm (1000), so must be further bound to not only due to the symbology, resolution and filetype but also due to the type of scanner used, the intended scanning distance, and what media (“substrates”) the barcode appears on.

    -

    5.13 Verifying Symbology +

    5.14 Verifying Symbology Availability

    An additional function available in the API is:

    -
    int ZBarcode_ValidID(int symbol_id);
    +
    int ZBarcode_ValidID(int symbol_id);

    which allows you to check whether a given symbology is available, returning a non-zero value if so. For example:

    -
    if (ZBarcode_ValidID(BARCODE_PDF417) != 0) {
    -    printf("PDF417 available\n");
    -} else {
    -    printf("PDF417 not available\n");
    -}
    +
    if (ZBarcode_ValidID(BARCODE_PDF417) != 0) {
    +    printf("PDF417 available\n");
    +} else {
    +    printf("PDF417 not available\n");
    +}

    Another function that may be useful is:

    -
    int ZBarcode_BarcodeName(int symbol_id, char name[32]);
    +
    int ZBarcode_BarcodeName(int symbol_id, char name[32]);

    which copies the name of a symbology into the supplied name buffer, which should be 32 characters in length. The name is NUL-terminated, and zero is returned on success. For instance:

    -
    char name[32];
    -if (ZBarcode_BarcodeName(BARCODE_PDF417, name) == 0) {
    -    printf("%s\n", name);
    -}
    +
    char name[32];
    +if (ZBarcode_BarcodeName(BARCODE_PDF417, name) == 0) {
    +    printf("%s\n", name);
    +}

    will print BARCODE_PDF417.

    -

    5.14 Checking Symbology +

    5.15 Checking Symbology Capabilities

    It can be useful for frontend programs to know the capabilities of a symbology. This can be determined using another additional function:

    -
    unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag);
    +
    unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag);

    by OR-ing the flags below in the cap_flag argument and checking the return to see which are set.

    @@ -4128,8 +4181,8 @@ Text? ZINT_CAP_EANUPC12 +href="#fn13" class="footnote-ref" id="fnref13" +role="doc-noteref">13 Is the symbology EAN/UPC? @@ -4191,25 +4244,25 @@ defined?

    For example:

    -
    unsigned int cap;
    -cap = ZBarcode_Cap(BARCODE_PDF417, ZINT_CAP_HRT | ZINT_CAP_ECI);
    -if (cap & ZINT_CAP_HRT) {
    -    printf("PDF417 supports HRT\n");
    -} else {
    -    printf("PDF417 does not support HRT\n");
    -}
    -if (cap & ZINT_CAP_ECI) {
    -    printf("PDF417 supports ECI\n");
    -} else {
    -    printf("PDF417 does not support ECI\n");
    -}
    -

    5.15 Zint Version

    +
    unsigned int cap;
    +cap = ZBarcode_Cap(BARCODE_PDF417, ZINT_CAP_HRT | ZINT_CAP_ECI);
    +if (cap & ZINT_CAP_HRT) {
    +    printf("PDF417 supports HRT\n");
    +} else {
    +    printf("PDF417 does not support HRT\n");
    +}
    +if (cap & ZINT_CAP_ECI) {
    +    printf("PDF417 supports ECI\n");
    +} else {
    +    printf("PDF417 does not support ECI\n");
    +}
    +

    5.16 Zint Version

    Whether the Zint library linked to was built with PNG support may be determined with:

    -
    int ZBarcode_NoPng();
    +
    int ZBarcode_NoPng();

    which returns 1 if no PNG support is available, else zero.

    Lastly, the version of the Zint library linked to is returned by:

    -
    int ZBarcode_Version();
    +
    int ZBarcode_Version();

    The version parts are separated by hundreds. For instance, version "2.9.1" is returned as "20901".

    6. Types of Symbology

    @@ -4357,12 +4410,12 @@ calculated by Zint. In addition EAN-2 and EAN-5 add-on symbols can be added using the + character. For example, to draw a UPC-A symbol with the data 72527270270 with an EAN-5 add-on showing the data 12345 use the command:

    -
    zint -b UPCA -d "72527270270+12345"
    +
    zint -b UPCA -d "72527270270+12345"

    or using the API encode a data string with the + character included:

    -
    my_symbol->symbology = BARCODE_UPCA;
    -error = ZBarcode_Encode_and_Print(my_symbol, "72527270270+12345", 0, 0);
    +
    my_symbol->symbology = BARCODE_UPCA;
    +error = ZBarcode_Encode_and_Print(my_symbol, "72527270270+12345", 0, 0);
    zint -b UPCA --compliantheight -d "72527270270+12345" @@ -4376,12 +4429,12 @@ input and validates the check digit before encoding.

    --guardwhitespace (API output_options |= EANUPC_GUARD_WHITESPACE). For UPC, this is only relevant when there is add-on:

    -
    zint -b UPCA -d "72527270270+12345" --guardwhitespace
    +
    zint -b UPCA -d "72527270270+12345" --guardwhitespace

    or using the API:

    -
    my_symbol->symbology = BARCODE_UPCA;
    -my_symbol->output_options |= EANUPC_GUARD_WHITESPACE;
    -error = ZBarcode_Encode_and_Print(my_symbol, "72527270270+12345", 0, 0);
    +
    my_symbol->symbology = BARCODE_UPCA;
    +my_symbol->output_options |= EANUPC_GUARD_WHITESPACE;
    +error = ZBarcode_Encode_and_Print(my_symbol, "72527270270+12345", 0, 0);
    zint -b UPCA --compliantheight -d "72527270270+12345" --guardwhitespace @@ -4407,19 +4460,19 @@ check digit is calculated by Zint. EAN-2 and EAN-5 add-on symbols can be added using the + character as with UPC-A. In addition Zint also supports Number System 1 encoding by entering a 7-digit article number starting with the digit 1. For example:

    -
    zint -b UPCE -d "1123456"
    +
    zint -b UPCE -d "1123456"

    or

    -
    my_symbol->symbology = BARCODE_UPCE;
    -error = ZBarcode_Encode_and_Print(my_symbol, "1123456", 0, 0);
    +
    my_symbol->symbology = BARCODE_UPCE;
    +error = ZBarcode_Encode_and_Print(my_symbol, "1123456", 0, 0);

    If your input data already includes the check digit symbology BARCODE_UPCE_CHK (38) can be used which takes a 7 or 8-digit input and validates the check digit before encoding.

    As with UPC-A, a quiet zone indicator can be added when there is an add-on by setting --guardwhitespace (API output_options |= EANUPC_GUARD_WHITESPACE):

    -
    zint -b UPCE -d "1123456+12" --guardwhitespace
    +
    zint -b UPCE -d "1123456+12" --guardwhitespace
    zint -b UPCE --compliantheight -d "1123456+12" --guardwhitespace @@ -4448,8 +4501,8 @@ numbers respectively. Zint will decide which symbology to use depending on the length of the input data. In addition EAN-2 and EAN-5 add-on symbols can be added to EAN-8 and EAN-13 symbols using the + character as with UPC symbols. For example:

    -
    zint -b EANX -d "54321"
    +
    zint -b EANX -d "54321"
    zint -b EANX --compliantheight -d "54321" @@ -4457,15 +4510,15 @@ alt="zint -b EANX --compliantheight -d "54321"" /> aria-hidden="true">zint -b EANX --compliantheight -d "54321"

    will encode a stand-alone EAN-5, whereas

    -
    zint -b EANX -d "7432365+54321"
    +
    zint -b EANX -d "7432365+54321"

    will encode an EAN-8 symbol with an EAN-5 add-on. As before these results can be achieved using the API:

    -
    my_symbol->symbology = BARCODE_EANX;
    -
    -error = ZBarcode_Encode_and_Print(my_symbol, "54321", 0, 0);
    -
    -error = ZBarcode_Encode_and_Print(my_symbol, "7432365+54321", 0, 0);
    +
    my_symbol->symbology = BARCODE_EANX;
    +
    +error = ZBarcode_Encode_and_Print(my_symbol, "54321", 0, 0);
    +
    +error = ZBarcode_Encode_and_Print(my_symbol, "7432365+54321", 0, 0);
    zint -b EANX --compliantheight -d "7432365+54321" @@ -4481,8 +4534,8 @@ and validates the check digit before encoding.

    Options to add quiet zone indicators and to adjust the add-on gap and the guard bar descent height are the same as for 6.1.3.2 UPC Version E. For instance:

    -
    zint -b EANX_CHK -d "74323654" --guardwhitespace
    +
    zint -b EANX_CHK -d "74323654" --guardwhitespace
    zint -b EANX_CHK --compliantheight -d "74323654" –guardwhitespace @@ -4765,15 +4818,15 @@ digit.

    escapes \^A, \^B, \^C. For instance the following will force switching to Code Set B for the data "5678" (normally Code Set C would be used throughout):

    -
    zint -b CODE128 -d "1234\^B5678" --extraesc
    +
    zint -b CODE128 -d "1234\^B5678" --extraesc

    The manually selected Code Set will apply until the next Code Set escape sequence, with the exception that data that cannot be represented in that Code Set will be switched as appropriate. If the data contains a special code sequence, it can be escaped by doubling the caret (^). For instance

    -
    zint -b CODE128 -d "\^AABC\^^BDEF" --extraesc
    +
    zint -b CODE128 -d "\^AABC\^^BDEF" --extraesc

    will encode the data "ABC\^BDEF" in Code Set A.

    Code 128 is the default barcode symbology used by Zint. In addition Zint supports the encoding of ISO/IEC 8859-1 (non-English) characters in @@ -4792,8 +4845,8 @@ aria-hidden="true">zint -b CODE128AB -d "130170X178"

    It is sometimes advantageous to stop Code 128 from using Code Set C which compresses numerical data. The BARCODE_CODE128AB13 variant (symbology 60) suppresses +href="#fn14" class="footnote-ref" id="fnref14" +role="doc-noteref">14 variant (symbology 60) suppresses Code Set C in favour of Code Sets A and B.

    Note that the special escapes to manually switch Code Sets mentioned above are not available for this variant (nor for any other).

    @@ -4819,11 +4872,11 @@ correct encoding. GS1-128 does not support extended ASCII (ISO/IEC 8859-1) characters. Check digits for GTIN data AI (01) are not generated and need to be included in the input data. The following is an example of a valid GS1-128 input:

    -
    zint -b 16 -d "[01]98898765432106[3202]012345[15]991231"
    -

    or using the --gs1parens option:

    zint -b 16 --gs1parens -d "(01)98898765432106(3202)012345(15)991231"
    +class="sourceCode bash">zint -b 16 -d "[01]98898765432106[3202]012345[15]991231" +

    or using the --gs1parens option:

    +
    zint -b 16 --gs1parens -d "(01)98898765432106(3202)012345(15)991231"

    6.1.10.4 EAN-14

    6.1.10.3 GS1-128.

    not calculated by Zint when this symbology is encoded. Fixed length data should be entered at the appropriate length for correct encoding. The following is an example of a valid GS1 DataBar Expanded input:

    -
    zint -b 31 -d "[01]98898765432106[3202]012345[15]991231"
    +
    zint -b 31 -d "[01]98898765432106[3202]012345[15]991231"

    6.1.12 Korea Post Barcode

    primarily in the vehicle industry, is to simply stack one-dimensional codes on top of each other. This can be achieved at the command prompt by giving more than one set of input data. For example

    -
    zint -d "This" -d "That"
    +
    zint -d "This" -d "That"

    will draw two Code 128 symbols, one on top of the other. The same result can be achieved using the API by executing the ZBarcode_Encode() function more than once on a symbol. For example:

    -
    my_symbol->symbology = BARCODE_CODE128;
    -
    -error = ZBarcode_Encode(my_symbol, "This", 0);
    -
    -error = ZBarcode_Encode(my_symbol, "That", 0);
    -
    -error = ZBarcode_Print(my_symbol);
    +
    my_symbol->symbology = BARCODE_CODE128;
    +
    +error = ZBarcode_Encode(my_symbol, "This", 0);
    +
    +error = ZBarcode_Encode(my_symbol, "That", 0);
    +
    +error = ZBarcode_Print(my_symbol);
    zint -d "This" -d "That" @@ -5113,8 +5166,8 @@ specifying --bind (API separator bars in integral multiples of the X-dimension (minimum and default 1, maximum 4) can be set by --separator (API option_3):

    -
    zint --bind --notext --separator=2 -d "This" -d "That"
    +
    zint --bind --notext --separator=2 -d "This" -d "That"
    zint --notext --bind --separator=2 -d "This" -d "That" @@ -5389,21 +5442,21 @@ should be entered into a primary string with the data for the 2D component being entered in the normal way. To do this at the command prompt use the --primary switch (API primary). For example:

    -
    zint -b EANX_CC --mode=1 --primary=331234567890 -d "[99]1234-abcd"
    +
    zint -b EANX_CC --mode=1 --primary=331234567890 -d "[99]1234-abcd"

    This creates an EAN-13 linear component with the data "331234567890" and a 2D CC-A (see below) component with the data "(99)1234-abcd". The same results can be achieved using the API as shown below:

    -
    my_symbol->symbology = BARCODE_EANX_CC;
    -
    -my_symbol->option_1 = 1;
    -
    -strcpy(my_symbol->primary, "331234567890");
    -
    -ZBarcode_Encode_and_Print(my_symbol, "[99]1234-abcd", 0, 0);
    +
    my_symbol->symbology = BARCODE_EANX_CC;
    +
    +my_symbol->option_1 = 1;
    +
    +strcpy(my_symbol->primary, "331234567890");
    +
    +ZBarcode_Encode_and_Print(my_symbol, "[99]1234-abcd", 0, 0);

    EAN-2 and EAN-5 add-on data can be used with EAN and UPC symbols using the + symbol as described in sections 6.1.3 UPC (Universal @@ -5763,13 +5816,13 @@ size to full height can be given in thousandths (permille) using the --vers option (API option_2). The default value is 250 (25%).

    For example the following

    -
    zint -b DAFT -d AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF --height=8.494 --vers=256
    +
    zint -b DAFT -d AAFDTTDAFADTFTTFFFDATFTADTTFFTDAFAFDTF --height=8.494 --vers=256

    produces the same barcode (see 6.5.3 Royal Mail 4-State Customer Code (RM4SCC)) as

    -
    zint -b RM4SCC --compliantheight -d "W1J0TR01"
    +
    zint -b RM4SCC --compliantheight -d "W1J0TR01"

    6.6 Matrix Symbols

    6.6.1 Data Matrix (ISO 16022)

    @@ -6409,8 +6462,8 @@ be manually specified by using the --mask switch with values 0-7, or in the API by setting option_3 = (N + 1) << 8 where N is 0-7. To use with ZINT_FULL_MULTIBYTE set

    -
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8
    +
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8

    The --fast option (API input_mode |= FAST_MODE) may be used when leaving Zint to automatically select a mask to reduce the number of masks to try to four @@ -6546,8 +6599,8 @@ be manually specified by using the --mask switch with values 0-3, or in the API by setting option_3 = (N + 1) << 8 where N is 0-3. To use with ZINT_FULL_MULTIBYTE set

    -
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8
    +
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8

    6.6.5 Rectangular Micro QR Code (rMQR) (ISO 23941)

    @@ -6814,8 +6867,8 @@ Latin-2 formatted use the --binary switch (API input_mode = DATA MODE).

    The following example creates a symbol from data saved as a Latin-2 file:

    -
    zint -o upnqr.png -b 143 --scale=3 --binary -i upn.txt
    +
    zint -o upnqr.png -b 143 --scale=3 --binary -i upn.txt

    A mask may be manually specified or the --fast option used as with QRCODE.

    6.6.7 MaxiCode (ISO 16023)

    @@ -6890,9 +6943,9 @@ your parcel courier.

    The primary message can be set at the command prompt using the --primary switch (API primary). The secondary message uses the normal data entry method. For example:

    -
    zint -o test.eps -b 57 --primary="999999999840012" \
    -    -d "Secondary Message Here"
    +
    zint -o test.eps -b 57 --primary="999999999840012" \
    +    -d "Secondary Message Here"

    When using the API the primary message must be placed in the primary string. The secondary is entered in the same way as described in 5.2 Encoding and @@ -6905,9 +6958,9 @@ to be prefixed by the ISO/IEC 15434 Format "01" vv is a 2-digit version, by using the --scmvv switch (API option_2 = vv + 1). For example to use the common version "96" (ASC MH10/SC 8):

    -
    zint -b 57 --primary="152382802840001" --scmvv=96 --esc -d \
    -  "1Z00004951\GUPSN\G06X610\G159\G1234567\G1/1\G\GY\G1 MAIN ST\GNY\GNY\R\E"
    +
    zint -b 57 --primary="152382802840001" --scmvv=96 --esc -d \
    +  "1Z00004951\GUPSN\G06X610\G159\G1234567\G1/1\G\GY\G1 MAIN ST\GNY\GNY\R\E"

    will prefix "[)>\R01\G96" to the secondary message. (\R, \G and \E are the escape sequences for Record Separator, Group Separator and End of Transmission @@ -6916,8 +6969,8 @@ Sequences.)

    Modes 4 to 6 can be accessed using the --mode switch (API option_1). Modes 4 to 6 do not have a primary message. For example:

    -
    zint -o test.eps -b 57 --mode=4 -d "A MaxiCode Message in Mode 4"
    +
    zint -o test.eps -b 57 --mode=4 -d "A MaxiCode Message in Mode 4"

    Mode 6 is reserved for the maintenance of scanner hardware and should not be used to encode user data.

    This symbology uses Latin-1 character encoding by default but also @@ -7842,8 +7895,8 @@ be manually specified by using the --mask switch with values 0-3, or in the API by setting option_3 = (N + 1) << 8 where N is 0-3. To use with ZINT_FULL_MULTIBYTE set

    -
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8
    +
    option_3 = ZINT_FULL_MULTIBYTE | (N + 1) << 8

    6.6.14 Ultracode

    Zint does not currently implement data compression by default, but this can be initiated through the API by setting

    -
    symbol->option_3 = ULTRA_COMPRESSION;
    +
    symbol->option_3 = ULTRA_COMPRESSION;

    With compression, up to 504 digits, 375 alphanumerics or 252 bytes can be encoded.

    Revision 2 of Ultracode (2023) may be specified using @@ -8553,32 +8606,32 @@ Buffering Symbols in Memory (vector)) provided by the Zint library libzint.

    The main class is Zint::QZint, which has getter/setter properties that correspond to the zint_symbol structure -(see 5.6 Setting Options), and a main +(see 5.7 Setting Options), and a main method render() which takes a Qt QPainter to paint with, and a QRectF rectangular area specifying where to paint into:

    -
    /* Encode and display barcode in `paintRect` using `painter`.
    -   Note: legacy argument `mode` is not used */
    -void render(QPainter& painter, const QRectF& paintRect,
    -            AspectRatioMode mode = IgnoreAspectRatio);
    +
    /* Encode and display barcode in `paintRect` using `painter`.
    +   Note: legacy argument `mode` is not used */
    +void render(QPainter& painter, const QRectF& paintRect,
    +            AspectRatioMode mode = IgnoreAspectRatio);

    render() will emit one of two Qt signals - encoded on successful encoding and drawing, or errored on failure. The client can connect and act appropriately, for instance:

    -
    connect(qzint, SIGNAL(encoded()), SLOT(on_encoded()));
    -connect(qzint, SIGNAL(errored()), SLOT(on_errored()));
    +
    connect(qzint, SIGNAL(encoded()), SLOT(on_encoded()));
    +connect(qzint, SIGNAL(errored()), SLOT(on_errored()));

    where qzint is an instance of Zint::QZint and on_encoded() and on_error() are Qt slot methods provided by the caller. On error, the error value and message can be retrieved by the methods getError() and lastError() respectively.

    The other main method is save_to_file():

    -
    /* Encode and print barcode to file `filename`.
    -   Only sets `getError()` on error, not on warning */
    -bool save_to_file(const QString& filename); // `ZBarcode_Print()`
    +
    /* Encode and print barcode to file `filename`.
    +   Only sets `getError()` on error, not on warning */
    +bool save_to_file(const QString& filename); // `ZBarcode_Print()`

    which takes a filename to output to. It too will emit an errored signal on failure, returning false (but nothing on success, which just returns true). Note @@ -8593,33 +8646,33 @@ symbology capabilities, and utility methods such as

    Annex C. Tcl Backend Binding

    A Tcl binding is available in the "backend_tcl” sub-directory. To make on Unix:

    -
    cd backend_tcl
    -autoconf
    -./configure
    -make
    -sudo make install
    +
    cd backend_tcl
    +autoconf
    +./configure
    +make
    +sudo make install

    For Windows, a Visual Studio 6.0 project file is available at "backend_tcl\zint_tcl.dsp". This can also be opened (and converted) by more modern Visual Studio versions, though some fixing up of the project configuration will likely be required.

    Once built and installed, invoke the Tcl/Tk CLI "wish":

    -
    wish
    +
    wish

    and ignoring the Tk window click back to the command prompt "%" and type:

    -
    require package zint
    -zint help
    +
    require package zint
    +zint help

    which will show the usage message, with options very similiar to the Zint CLI. (One notable difference is that boolean options such as -bold take a 1 or 0 as an argument.)

    A demonstration Tcl/Tk program which is also useful in itself is available at "backend_tcl/demo/demo.tcl". To run type:

    -
    wish demo/demo.tcl
    +
    wish demo/demo.tcl

    which will display the following window.

    --werror given

    EXAMPLES

    Create “out.png” (or “out.gif” if zint built without PNG support) in the current directory, as a Code 128 symbol.

    -
    zint -d 'This Text'
    -

    Create “qr.svg” in the current directory, as a QR Code symbol.

    zint -b QRCode -d 'This Text' -o 'qr.svg'
    +class="sourceCode bash">zint -d 'This Text' +

    Create “qr.svg” in the current directory, as a QR Code symbol.

    +
    zint -b QRCode -d 'This Text' -o 'qr.svg'

    Use batch mode to read from an input file “ean13nos.txt” containing 13-digit GTINs, to create a series of EAN-13 barcodes, formatting the output filenames to “ean001.gif”, “ean002.gif” etc. using the special character “~”.

    -
    zint -b EANX --batch -i 'ean13nos.txt' -o 'ean~~~.gif'
    +
    zint -b EANX --batch -i 'ean13nos.txt' -o 'ean~~~.gif'

    BUGS

    Please send bug reports to https://sourceforge.net/p/zint/tickets/.

    @@ -9395,31 +9448,35 @@ characters undefined: #, $, @, `, {, |, }, ~.↩︎

  • -
  • The height value is ignored for Aztec +

  • BARCODE_MEMORY_FILE textual formats EPS and SVG will +have Unix newlines (LF) on both Windows and Unix, i.e. not CR+LF on +Windows.↩︎

  • +
  • The height value is ignored for Aztec (including HIBC and Aztec Rune), Code One, Data Matrix (including HIBC), DotCode, Grid Matrix, Han Xin, MaxiCode, QR Code (including HIBC, Micro QR, rMQR and UPNQR), and Ultracode - all of which have a fixed width-to-height ratio (or, in the case of Code One, a fixed height).↩︎

  • -
  • For Windows, outfile is assumed to be UTF-8 -encoded.↩︎

  • +
  • For Windows, outfile is assumed to be UTF-8 +encoded.↩︎

  • -
  • The BARCODE_BIND_TOP flag is set by default -for DPD - see 6.1.10.7 DPD Code.↩︎

  • -
  • The BARCODE_BIND flag is always set for +

  • The BARCODE_BIND_TOP flag is set by +default for DPD - see 6.1.10.7 DPD Code.↩︎

  • +
  • The BARCODE_BIND flag is always set for Codablock-F, Code 16K and Code 49. Special considerations apply to -ITF-14 - see 6.1.2.6 ITF-14.6.1.2.6 ITF-14.↩︎

  • -
  • Codablock-F, Code 16K, Code 49, EAN-2 to EAN-13, ISBN, +

  • Codablock-F, Code 16K, Code 49, EAN-2 to EAN-13, ISBN, ITF-14, UPC-A and UPC-E have compliant quiet zones added by default.↩︎

  • -
  • ZINT_CAP_EANUPC was previously named -ZINT_CAP_EXTENDABLE, which is still recognised.↩︎

  • -
  • BARCODE_CODE128AB previously used the name -BARCODE_CODE128B, which is still recognised.

    ZINT_CAP_EANUPC was previously named +ZINT_CAP_EXTENDABLE, which is still recognised.↩︎

  • +
  • BARCODE_CODE128AB previously used the name +BARCODE_CODE128B, which is still recognised.↩︎

  • diff --git a/docs/manual.pmd b/docs/manual.pmd index bd46083a..f0c80e21 100644 --- a/docs/manual.pmd +++ b/docs/manual.pmd @@ -1028,7 +1028,7 @@ zint --fg=00ff0055 -d "This Text" ![`zint -d "This Text" --fg=00FF0055`](images/code128_green_alpha.svg){.lin} -will produce a semi-transparent green foreground with standard (white) +will produce a semi-transparent green foreground with a standard (white) background. Note that transparency is treated differently by raster and vector (SVG) output formats, as for vector output the background will "shine through" a transparent foreground. For instance @@ -1707,7 +1707,7 @@ int main(int argc, char **argv) ``` Note that when using the API, the input data is assumed to be 8-bit binary -unless the `input_mode` member of the `zint_symbol` structure is set - see [5.10 +unless the `input_mode` member of the `zint_symbol` structure is set - see [5.11 Setting the Input Mode] for details. ## 5.3 Encoding and Printing Functions in Depth @@ -1876,24 +1876,59 @@ for (circle = my_symbol->vector->circles; circle; circle = circle->next) { } ``` -## 5.6 Setting Options +## 5.6 Buffering Symbols in Memory (memfile) + +Symbols can also be stored as "in-memory" file buffers by giving the +`BARCODE_MEMORY_FILE` option to the `output_options` member, which saves the +print output to member `memfile` instead of to the output file `outfile`. The +length of the buffer is given in `memfile_size`. For instance: + +```c +#include +#include +#include +int main(int argc, char **argv) +{ + struct zint_symbol *my_symbol; + my_symbol = ZBarcode_Create(); + my_symbol->output_options |= BARCODE_MEMORY_FILE; + /* Only the extension is used, to determine output format */ + strcpy(my_symbol->outfile, "mem.svg"); + ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0); + /* `my_symbol->memfile` now contains the SVG output */ + fwrite(my_symbol->memfile, 1, my_symbol->memfile_size, stdout); + ZBarcode_Delete(my_symbol); + return 0; +} + +``` + +will print the SVG output to `stdout` (the file "mem.svg" is not created). This +is particularly useful for the textual formats EPS and SVG,[^7] allowing the +output to be manipulated and processed by the client. + +[^7]: BARCODE_MEMORY_FILE textual formats EPS and SVG will have Unix newlines +(LF) on both Windows and Unix, i.e. not CR+LF on Windows. + +## 5.7 Setting Options So far our application is not very useful unless we plan to only make Code 128 -symbols and we don't mind that they only save to `"out.png"`. As with the CLI -program, of course, these options can be altered. The way this is done is by -altering the contents of the `zint_symbol` structure between the creation and -encoding stages. The `zint_symbol` structure consists of the following members: +symbols and we don't mind that they only save to `"out.png"` (or to memory, as +above). As with the CLI program, of course, these options can be altered. The +way this is done is by altering the contents of the `zint_symbol` structure +between the creation and encoding stages. The `zint_symbol` structure consists +of the following members: ----------------------------------------------------------------------------- Member Name Type Meaning Default Value ------------------- ---------- ------------------------- ----------------- -`symbology` integer Symbol to use - see [5.8 `BARCODE_CODE128` +`symbology` integer Symbol to use - see [5.9 `BARCODE_CODE128` Specifying a Symbology]. `height` float Symbol height in Symbol dependent X-dimensions, excluding fixed width-to-height - symbols.[^7] + symbols.[^8] `scale` float Scale factor for 1.0 adjusting size of image @@ -1909,7 +1944,7 @@ Member Name Type Meaning Default Value X-dimensions. `output_options` integer Set various output 0 (none) - parameters - see [5.9 + parameters - see [5.10 Adjusting Output Options]. @@ -1943,7 +1978,7 @@ Member Name Type Meaning Default Value `.eps`, `.pcx`, `.svg`, `.tif` or `.txt` followed by a terminating - `NUL`.[^8] + `NUL`.[^9] `primary` character Primary message data for `""` (empty) string more complex symbols, @@ -1959,7 +1994,7 @@ Member Name Type Meaning Default Value Readable Text (HRT). `input_mode` integer Set encoding of input `DATA_MODE` - data - see [5.10 Setting + data - see [5.11 Setting the Input Mode]. `eci` integer Extended Channel 0 (none) @@ -1989,7 +2024,7 @@ Member Name Type Meaning Default Value `warn_level` integer Affects error/warning `WARN_DEFAULT` value returned by Zint - API - see [5.7 Handling + API - see [5.8 Handling Errors]. `text` unsigned Human Readable Text, `""` (empty) @@ -2017,7 +2052,7 @@ Member Name Type Meaning Default Value string event that an error occurred, with a terminating `NUL` - see - [5.7 Handling Errors]. + [5.8 Handling Errors]. `bitmap` pointer to Pointer to stored bitmap (output only) unsigned image - see [5.4 @@ -2044,17 +2079,28 @@ Member Name Type Meaning Default Value structure vector elements - see [5.5 Buffering Symbols in Memory (vector)]. + +`memfile` pointer to Pointer to in-memory (output only) + unsigned file buffer if + character `BARCODE_MEMORY_FILE` + array set in `output_options` + - see [5.6 Buffering + Symbols in Memory + (memfile)]. + +`memfile_size` integer Length of in-memory file (output only) + buffer. ----------------------------------------------------------------------------- Table: API Structure `zint_symbol` {#tbl:api_structure_zint_symbol tag="$ $"} -[^7]: The `height` value is ignored for Aztec (including HIBC and Aztec Rune), +[^8]: The `height` value is ignored for Aztec (including HIBC and Aztec Rune), Code One, Data Matrix (including HIBC), DotCode, Grid Matrix, Han Xin, MaxiCode, QR Code (including HIBC, Micro QR, rMQR and UPNQR), and Ultracode - all of which have a fixed width-to-height ratio (or, in the case of Code One, a fixed height). -[^8]: For Windows, `outfile` is assumed to be UTF-8 encoded. +[^9]: For Windows, `outfile` is assumed to be UTF-8 encoded. To alter these values use the syntax shown in the example below. This code has the same result as the previous example except the output is now taller and @@ -2085,7 +2131,7 @@ ignored: This is what the CLI option `--nobackground` does - see [4.7 Using Colour]. -## 5.7 Handling Errors +## 5.8 Handling Errors If errors occur during encoding a non-zero integer value is passed back to the calling application. In addition the `errtxt` member is set to a message @@ -2196,7 +2242,7 @@ Error 881: Malformed foreground RGB colour 'nonsense' (hexadecimal only) To treat all warnings as errors, set `symbol->warn_level` to `WARN_FAIL_ALL`. -## 5.8 Specifying a Symbology +## 5.9 Specifying a Symbology Symbologies can be specified by number or by name as shown in the Table {@tbl:barcode_types}. For example @@ -2211,7 +2257,7 @@ means the same as symbol->symbology = 50; ``` -## 5.9 Adjusting Output Options +## 5.10 Adjusting Output Options The `output_options` member can be used to adjust various aspects of the output file. To select more than one option from the table below simply `OR` them @@ -2226,10 +2272,10 @@ Value Effect ------------------------- --------------------------------------------------- 0 No options selected. -`BARCODE_BIND_TOP` Boundary bar above the symbol only.[^9] +`BARCODE_BIND_TOP` Boundary bar above the symbol only.[^10] `BARCODE_BIND` Boundary bars above and below the symbol and - between rows if stacking multiple symbols.[^10] + between rows if stacking multiple symbols.[^11] `BARCODE_BOX` Add a box surrounding the symbol and whitespace. @@ -2256,7 +2302,7 @@ Value Effect Symbols in Memory (raster)]. `BARCODE_QUIET_ZONES` Add compliant quiet zones (additional to any - specified whitespace).[^11] + specified whitespace).[^12] `BARCODE_NO_QUIET_ZONES` Disable quiet zones, notably those with defaults. @@ -2268,20 +2314,23 @@ Value Effect `EMBED_VECTOR_FONT` Embed font in vector output - currently available for SVG output only. + +`BARCODE_MEMORY_FILE` Write output to in-memory buffer `symbol->memfile` + instead of to `outfile` file. ------------------------------------------------------------------------------ Table: API `output_options` Values {#tbl:api_output_options tag="$ $"} -[^9]: The `BARCODE_BIND_TOP` flag is set by default for DPD - see [6.1.10.7 DPD +[^10]: The `BARCODE_BIND_TOP` flag is set by default for DPD - see [6.1.10.7 DPD Code]. -[^10]: The `BARCODE_BIND` flag is always set for Codablock-F, Code 16K and Code +[^11]: The `BARCODE_BIND` flag is always set for Codablock-F, Code 16K and Code 49. Special considerations apply to ITF-14 - see [6.1.2.6 ITF-14]. -[^11]: Codablock-F, Code 16K, Code 49, EAN-2 to EAN-13, ISBN, ITF-14, UPC-A and +[^12]: Codablock-F, Code 16K, Code 49, EAN-2 to EAN-13, ISBN, ITF-14, UPC-A and UPC-E have compliant quiet zones added by default. -## 5.10 Setting the Input Mode +## 5.11 Setting the Input Mode The way in which the input data is encoded can be set using the `input_mode` member. Valid values are shown in the table below. @@ -2366,7 +2415,7 @@ be set to the overall height on output). MicroPDF417 and PDF417. For QR Code and UPNQR, it affects Zint's automatic mask selection - see [6.6.3 QR Code (ISO 18004)] for details. -## 5.11 Multiple Segments +## 5.12 Multiple Segments For input data requiring multiple ECIs, the following functions may be used: @@ -2426,7 +2475,7 @@ int main(int argc, char **argv) A maximum of 256 segments may be specified. Use of multiple segments with GS1 data is not currently supported. -## 5.12 Scaling Helpers +## 5.13 Scaling Helpers To help with scaling the output, the following three function are available: @@ -2473,7 +2522,7 @@ due to the symbology, resolution and filetype but also due to the type of scanner used, the intended scanning distance, and what media ("substrates") the barcode appears on. -## 5.13 Verifying Symbology Availability +## 5.14 Verifying Symbology Availability An additional function available in the API is: @@ -2511,7 +2560,7 @@ if (ZBarcode_BarcodeName(BARCODE_PDF417, name) == 0) { will print `BARCODE_PDF417`. -## 5.14 Checking Symbology Capabilities +## 5.15 Checking Symbology Capabilities It can be useful for frontend programs to know the capabilities of a symbology. This can be determined using another additional function: @@ -2530,7 +2579,7 @@ Value Meaning `ZINT_CAP_STACKABLE` Is the symbology stackable? -`ZINT_CAP_EANUPC`[^12] Is the symbology EAN/UPC? +`ZINT_CAP_EANUPC`[^13] Is the symbology EAN/UPC? `ZINT_CAP_COMPOSITE` Does the symbology support composite data? (see [6.3 GS1 Composite Symbols (ISO 24723)] below) @@ -2561,7 +2610,7 @@ Value Meaning Table: {#tbl:api_cap tag=": API Capability Flags"} -[^12]: `ZINT_CAP_EANUPC` was previously named `ZINT_CAP_EXTENDABLE`, which is +[^13]: `ZINT_CAP_EANUPC` was previously named `ZINT_CAP_EXTENDABLE`, which is still recognised. For example: @@ -2581,7 +2630,7 @@ if (cap & ZINT_CAP_ECI) { } ``` -## 5.15 Zint Version +## 5.16 Zint Version Whether the Zint library linked to was built with PNG support may be determined with: @@ -3091,13 +3140,13 @@ all-numeric characters. ![`zint -b CODE128AB -d "130170X178"`](images/code128ab.svg){.lin} It is sometimes advantageous to stop Code 128 from using Code Set C which -compresses numerical data. The `BARCODE_CODE128AB`[^13] variant (symbology 60) +compresses numerical data. The `BARCODE_CODE128AB`[^14] variant (symbology 60) suppresses Code Set C in favour of Code Sets A and B. Note that the special escapes to manually switch Code Sets mentioned above are not available for this variant (nor for any other). -[^13]: `BARCODE_CODE128AB` previously used the name `BARCODE_CODE128B`, which is +[^14]: `BARCODE_CODE128AB` previously used the name `BARCODE_CODE128B`, which is still recognised. #### 6.1.10.3 GS1-128 @@ -4866,7 +4915,7 @@ Used internally by Zint Barcode Studio to display the preview, the Qt Backend Buffering Symbols in Memory (vector)]) provided by the Zint library `libzint`. The main class is `Zint::QZint`, which has getter/setter properties that -correspond to the `zint_symbol` structure (see [5.6 Setting Options]), and a +correspond to the `zint_symbol` structure (see [5.7 Setting Options]), and a main method `render()` which takes a Qt `QPainter` to paint with, and a `QRectF` rectangular area specifying where to paint into: diff --git a/docs/manual.txt b/docs/manual.txt index ce271b59..2b66257a 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -62,16 +62,17 @@ December 2023 - 5.3 Encoding and Printing Functions in Depth - 5.4 Buffering Symbols in Memory (raster) - 5.5 Buffering Symbols in Memory (vector) - - 5.6 Setting Options - - 5.7 Handling Errors - - 5.8 Specifying a Symbology - - 5.9 Adjusting Output Options - - 5.10 Setting the Input Mode - - 5.11 Multiple Segments - - 5.12 Scaling Helpers - - 5.13 Verifying Symbology Availability - - 5.14 Checking Symbology Capabilities - - 5.15 Zint Version + - 5.6 Buffering Symbols in Memory (memfile) + - 5.7 Setting Options + - 5.8 Handling Errors + - 5.9 Specifying a Symbology + - 5.10 Adjusting Output Options + - 5.11 Setting the Input Mode + - 5.12 Multiple Segments + - 5.13 Scaling Helpers + - 5.14 Verifying Symbology Availability + - 5.15 Checking Symbology Capabilities + - 5.16 Zint Version - 6. Types of Symbology - 6.1 One-Dimensional Symbols - 6.1.1 Code 11 @@ -1130,7 +1131,7 @@ format. For example: [zint -d "This Text" --fg=00FF0055] -will produce a semi-transparent green foreground with standard (white) +will produce a semi-transparent green foreground with a standard (white) background. Note that transparency is treated differently by raster and vector (SVG) output formats, as for vector output the background will “shine through” a transparent foreground. For instance @@ -1742,7 +1743,7 @@ function as shown in the next example: } Note that when using the API, the input data is assumed to be 8-bit binary -unless the input_mode member of the zint_symbol structure is set - see 5.10 +unless the input_mode member of the zint_symbol structure is set - see 5.11 Setting the Input Mode for details. 5.3 Encoding and Printing Functions in Depth @@ -1899,24 +1900,53 @@ draw_string(), and draw_circle() routines available: draw_circle(circle->x, circle->y, circle->diameter, circle->width); } -5.6 Setting Options +5.6 Buffering Symbols in Memory (memfile) + +Symbols can also be stored as “in-memory” file buffers by giving the +BARCODE_MEMORY_FILE option to the output_options member, which saves the print +output to member memfile instead of to the output file outfile. The length of +the buffer is given in memfile_size. For instance: + + #include + #include + #include + int main(int argc, char **argv) + { + struct zint_symbol *my_symbol; + my_symbol = ZBarcode_Create(); + my_symbol->output_options |= BARCODE_MEMORY_FILE; + /* Only the extension is used, to determine output format */ + strcpy(my_symbol->outfile, "mem.svg"); + ZBarcode_Encode_and_Print(my_symbol, argv[1], 0, 0); + /* `my_symbol->memfile` now contains the SVG output */ + fwrite(my_symbol->memfile, 1, my_symbol->memfile_size, stdout); + ZBarcode_Delete(my_symbol); + return 0; + } + +will print the SVG output to stdout (the file “mem.svg” is not created). This is +particularly useful for the textual formats EPS and SVG,[7] allowing the output +to be manipulated and processed by the client. + +5.7 Setting Options So far our application is not very useful unless we plan to only make Code 128 -symbols and we don’t mind that they only save to "out.png". As with the CLI -program, of course, these options can be altered. The way this is done is by -altering the contents of the zint_symbol structure between the creation and -encoding stages. The zint_symbol structure consists of the following members: +symbols and we don’t mind that they only save to "out.png" (or to memory, as +above). As with the CLI program, of course, these options can be altered. The +way this is done is by altering the contents of the zint_symbol structure +between the creation and encoding stages. The zint_symbol structure consists of +the following members: ------------------------------------------------------------------------------ Member Name Type Meaning Default Value -------------------- ------------ -------------------------- ----------------- - symbology integer Symbol to use - see 5.8 BARCODE_CODE128 + symbology integer Symbol to use - see 5.9 BARCODE_CODE128 Specifying a Symbology. height float Symbol height in Symbol dependent X-dimensions, excluding fixed width-to-height - symbols.[7] + symbols.[8] scale float Scale factor for adjusting 1.0 size of image (sets @@ -1932,7 +1962,7 @@ encoding stages. The zint_symbol structure consists of the following members: X-dimensions. output_options integer Set various output 0 (none) - parameters - see 5.9 + parameters - see 5.10 Adjusting Output Options. fgcolour character Foreground (ink) colour as "000000" @@ -1963,7 +1993,7 @@ encoding stages. The zint_symbol structure consists of the following members: end in .png, .gif, .bmp, .emf, .eps, .pcx, .svg, .tif or .txt followed by a - terminating NUL.[8] + terminating NUL.[9] primary character Primary message data for "" (empty) string more complex symbols, with @@ -1979,7 +2009,7 @@ encoding stages. The zint_symbol structure consists of the following members: Readable Text (HRT). input_mode integer Set encoding of input DATA_MODE - data - see 5.10 Setting + data - see 5.11 Setting the Input Mode. eci integer Extended Channel 0 (none) @@ -2009,7 +2039,7 @@ encoding stages. The zint_symbol structure consists of the following members: warn_level integer Affects error/warning WARN_DEFAULT value returned by Zint - API - see 5.7 Handling + API - see 5.8 Handling Errors. text unsigned Human Readable Text, which "" (empty) @@ -2036,7 +2066,7 @@ encoding stages. The zint_symbol structure consists of the following members: errtxt character Error message in the event (output only) string that an error occurred, with a terminating NUL - - see 5.7 Handling Errors. + see 5.8 Handling Errors. bitmap pointer to Pointer to stored bitmap (output only) unsigned image - see 5.4 Buffering @@ -2062,6 +2092,16 @@ encoding stages. The zint_symbol structure consists of the following members: structure vector elements - see 5.5 Buffering Symbols in Memory (vector). + + memfile pointer to Pointer to in-memory file (output only) + unsigned buffer if + character BARCODE_MEMORY_FILE set in + array output_options - see 5.6 + Buffering Symbols in + Memory (memfile). + + memfile_size integer Length of in-memory file (output only) + buffer. ------------------------------------------------------------------------------ : Table  : API Structure zint_symbol @@ -2091,7 +2131,7 @@ ignored: This is what the CLI option --nobackground does - see 4.7 Using Colour. -5.7 Handling Errors +5.8 Handling Errors If errors occur during encoding a non-zero integer value is passed back to the calling application. In addition the errtxt member is set to a message detailing @@ -2198,7 +2238,7 @@ This code will exit with the appropriate message: To treat all warnings as errors, set symbol->warn_level to WARN_FAIL_ALL. -5.8 Specifying a Symbology +5.9 Specifying a Symbology Symbologies can be specified by number or by name as shown in the Table : Barcode Types (Symbologies). For example @@ -2209,7 +2249,7 @@ means the same as symbol->symbology = 50; -5.9 Adjusting Output Options +5.10 Adjusting Output Options The output_options member can be used to adjust various aspects of the output file. To select more than one option from the table below simply OR them @@ -2222,10 +2262,10 @@ together when adjusting this value: -------------------------- --------------------------------------------------- 0 No options selected. - BARCODE_BIND_TOP Boundary bar above the symbol only.[9] + BARCODE_BIND_TOP Boundary bar above the symbol only.[10] BARCODE_BIND Boundary bars above and below the symbol and - between rows if stacking multiple symbols.[10] + between rows if stacking multiple symbols.[11] BARCODE_BOX Add a box surrounding the symbol and whitespace. @@ -2252,7 +2292,7 @@ together when adjusting this value: Symbols in Memory (raster). BARCODE_QUIET_ZONES Add compliant quiet zones (additional to any - specified whitespace).[11] + specified whitespace).[12] BARCODE_NO_QUIET_ZONES Disable quiet zones, notably those with defaults. @@ -2264,11 +2304,14 @@ together when adjusting this value: EMBED_VECTOR_FONT Embed font in vector output - currently available for SVG output only. + + BARCODE_MEMORY_FILE Write output to in-memory buffer symbol->memfile + instead of to outfile file. ------------------------------------------------------------------------------ : Table  : API output_options Values -5.10 Setting the Input Mode +5.11 Setting the Input Mode The way in which the input data is encoded can be set using the input_mode member. Valid values are shown in the table below. @@ -2345,7 +2388,7 @@ FAST_MODE causes a less optimal encodation scheme to be used for Data Matrix, MicroPDF417 and PDF417. For QR Code and UPNQR, it affects Zint’s automatic mask selection - see 6.6.3 QR Code (ISO 18004) for details. -5.11 Multiple Segments +5.12 Multiple Segments For input data requiring multiple ECIs, the following functions may be used: @@ -2399,7 +2442,7 @@ example: A maximum of 256 segments may be specified. Use of multiple segments with GS1 data is not currently supported. -5.12 Scaling Helpers +5.13 Scaling Helpers To help with scaling the output, the following three function are available: @@ -2442,7 +2485,7 @@ due to the symbology, resolution and filetype but also due to the type of scanner used, the intended scanning distance, and what media (“substrates”) the barcode appears on. -5.13 Verifying Symbology Availability +5.14 Verifying Symbology Availability An additional function available in the API is: @@ -2472,7 +2515,7 @@ success. For instance: will print BARCODE_PDF417. -5.14 Checking Symbology Capabilities +5.15 Checking Symbology Capabilities It can be useful for frontend programs to know the capabilities of a symbology. This can be determined using another additional function: @@ -2489,7 +2532,7 @@ see which are set. ZINT_CAP_STACKABLE Is the symbology stackable? - ZINT_CAP_EANUPC[12] Is the symbology EAN/UPC? + ZINT_CAP_EANUPC[13] Is the symbology EAN/UPC? ZINT_CAP_COMPOSITE Does the symbology support composite data? (see 6.3 GS1 Composite Symbols (ISO 24723) below) @@ -2535,7 +2578,7 @@ For example: printf("PDF417 does not support ECI\n"); } -5.15 Zint Version +5.16 Zint Version Whether the Zint library linked to was built with PNG support may be determined with: @@ -2995,7 +3038,7 @@ all-numeric characters. [zint -b CODE128AB -d "130170X178"] It is sometimes advantageous to stop Code 128 from using Code Set C which -compresses numerical data. The BARCODE_CODE128AB[13] variant (symbology 60) +compresses numerical data. The BARCODE_CODE128AB[14] variant (symbology 60) suppresses Code Set C in favour of Code Sets A and B. Note that the special escapes to manually switch Code Sets mentioned above are @@ -4689,7 +4732,7 @@ QZint renders a barcode by drawing the vector representation (see 5.5 Buffering Symbols in Memory (vector)) provided by the Zint library libzint. The main class is Zint::QZint, which has getter/setter properties that -correspond to the zint_symbol structure (see 5.6 Setting Options), and a main +correspond to the zint_symbol structure (see 5.7 Setting Options), and a main method render() which takes a Qt QPainter to paint with, and a QRectF rectangular area specifying where to paint into: @@ -5492,24 +5535,28 @@ the yen sign (¥), and tilde (~) to overline (U+203E). [6] ISO/IEC 646 Invariant is a subset of ASCII with 12 characters undefined: #, $, @, [, \, ], ^, `, {, |, }, ~. -[7] The height value is ignored for Aztec (including HIBC and Aztec Rune), Code +[7] BARCODE_MEMORY_FILE textual formats EPS and SVG will have Unix newlines (LF) +on both Windows and Unix, i.e. not CR+LF on Windows. + +[8] The height value is ignored for Aztec (including HIBC and Aztec Rune), Code One, Data Matrix (including HIBC), DotCode, Grid Matrix, Han Xin, MaxiCode, QR Code (including HIBC, Micro QR, rMQR and UPNQR), and Ultracode - all of which have a fixed width-to-height ratio (or, in the case of Code One, a fixed height). -[8] For Windows, outfile is assumed to be UTF-8 encoded. +[9] For Windows, outfile is assumed to be UTF-8 encoded. -[9] The BARCODE_BIND_TOP flag is set by default for DPD - see 6.1.10.7 DPD Code. +[10] The BARCODE_BIND_TOP flag is set by default for DPD - see 6.1.10.7 DPD +Code. -[10] The BARCODE_BIND flag is always set for Codablock-F, Code 16K and Code 49. +[11] The BARCODE_BIND flag is always set for Codablock-F, Code 16K and Code 49. Special considerations apply to ITF-14 - see 6.1.2.6 ITF-14. -[11] Codablock-F, Code 16K, Code 49, EAN-2 to EAN-13, ISBN, ITF-14, UPC-A and +[12] Codablock-F, Code 16K, Code 49, EAN-2 to EAN-13, ISBN, ITF-14, UPC-A and UPC-E have compliant quiet zones added by default. -[12] ZINT_CAP_EANUPC was previously named ZINT_CAP_EXTENDABLE, which is still +[13] ZINT_CAP_EANUPC was previously named ZINT_CAP_EXTENDABLE, which is still recognised. -[13] BARCODE_CODE128AB previously used the name BARCODE_CODE128B, which is still +[14] BARCODE_CODE128AB previously used the name BARCODE_CODE128B, which is still recognised. diff --git a/frontend/main.c b/frontend/main.c index f4eef960..92d93eaf 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -44,16 +44,20 @@ typedef char static_assert_int_at_least_32bits[sizeof(int) * CHAR_BIT < 32 ? -1 #define ARRAY_SIZE(x) ((int) (sizeof(x) / sizeof((x)[0]))) #endif -/* Determine if C89 (excluding MSVC, which doesn't define __STDC_VERSION__) */ -#if !defined(_MSC_VER) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199000L) -#define ZINT_IS_C89 +/* Determine if C89 or C99 (excluding MSVC, which doesn't define __STDC_VERSION__) */ +#ifndef _MSC_VER +# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199000L +# define ZINT_IS_C89 +# elif __STDC_VERSION__ <= 199901L /* Actually includes pseudo-standards "C94/C95" as well */ +# define ZINT_IS_C99 +# endif #endif #ifdef _MSC_VER # include # define z_alloca(nmemb) _alloca(nmemb) #else -# if defined(ZINT_IS_C89) || defined(__NuttX__) /* C89 or NuttX RTOS */ +# if defined(ZINT_IS_C89) || defined(ZINT_IS_C99) || defined(__NuttX__) /* C89 or C99 or NuttX RTOS */ # include # endif # define z_alloca(nmemb) alloca(nmemb) diff --git a/tools/update_version.php b/tools/update_version.php index e9a9e027..6236e1ff 100644 --- a/tools/update_version.php +++ b/tools/update_version.php @@ -326,11 +326,11 @@ version_replace(2, $data_dirname . 'win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp' // win32/vs2008/libzint.vcproj -version_replace(3, $data_dirname . 'win32/vs2008/libzint.vcproj', '/ZINT_VERSION="/', '/"[0-9.]+/', '"' . $v_str); +version_replace(2, $data_dirname . 'win32/vs2008/libzint.vcproj', '/ZINT_VERSION="/', '/"[0-9.]+/', '"' . $v_str); // win32/vs2008/zint.vcproj -version_replace(3, $data_dirname . 'win32/vs2008/zint.vcproj', '/ZINT_VERSION="/', '/"[0-9.]+/', '"' . $v_str); +version_replace(2, $data_dirname . 'win32/vs2008/zint.vcproj', '/ZINT_VERSION="/', '/"[0-9.]+/', '"' . $v_str); // win32/vs2015/libzint.vcxproj diff --git a/win32/libzint.vcxproj b/win32/libzint.vcxproj index 366201ec..93e4e1d0 100644 --- a/win32/libzint.vcxproj +++ b/win32/libzint.vcxproj @@ -139,6 +139,7 @@ + @@ -187,6 +188,7 @@ + diff --git a/win32/vs2008/libzint.vcproj b/win32/vs2008/libzint.vcproj index accc690e..e7e7c908 100644 --- a/win32/vs2008/libzint.vcproj +++ b/win32/vs2008/libzint.vcproj @@ -184,76 +184,6 @@ Name="VCPostBuildEventTool" /> - - - - - - - - - - - - - - - - - @@ -318,14 +248,6 @@ - - - + + @@ -533,6 +459,10 @@ RelativePath="..\..\backend\gbk.h" > + + @@ -642,14 +572,6 @@ - - - diff --git a/win32/vs2008/zint.sln b/win32/vs2008/zint.sln new file mode 100644 index 00000000..3288aa7d --- /dev/null +++ b/win32/vs2008/zint.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zint", "zint.vcproj", "{3169C7FA-E52C-4BFC-B7BB-E55EBA133770}" + ProjectSection(ProjectDependencies) = postProject + {5C08DC40-8F7D-475E-AA3C-814DED735A4B} = {5C08DC40-8F7D-475E-AA3C-814DED735A4B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzint", "libzint.vcproj", "{5C08DC40-8F7D-475E-AA3C-814DED735A4B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Debug|Win32.ActiveCfg = Debug|Win32 + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Debug|Win32.Build.0 = Debug|Win32 + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Release|Win32.ActiveCfg = Release|Win32 + {3169C7FA-E52C-4BFC-B7BB-E55EBA133770}.Release|Win32.Build.0 = Release|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Debug|Win32.ActiveCfg = Debug|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Debug|Win32.Build.0 = Debug|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Release|Win32.ActiveCfg = Release|Win32 + {5C08DC40-8F7D-475E-AA3C-814DED735A4B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/win32/vs2008/zint.vcproj b/win32/vs2008/zint.vcproj index c0b60b77..879a9717 100644 --- a/win32/vs2008/zint.vcproj +++ b/win32/vs2008/zint.vcproj @@ -41,7 +41,7 @@ - - - - - - - - - - - - - - - - - - - @@ -261,11 +188,11 @@ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > @@ -275,7 +202,7 @@ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" > diff --git a/win32/vs2015/libzint.vcxproj b/win32/vs2015/libzint.vcxproj index 4049f835..99bbb6fd 100644 --- a/win32/vs2015/libzint.vcxproj +++ b/win32/vs2015/libzint.vcxproj @@ -316,6 +316,7 @@ + @@ -364,6 +365,7 @@ + diff --git a/win32/vs2017/libzint.vcxproj b/win32/vs2017/libzint.vcxproj index 929578a9..04100810 100644 --- a/win32/vs2017/libzint.vcxproj +++ b/win32/vs2017/libzint.vcxproj @@ -139,6 +139,7 @@ + @@ -187,6 +188,7 @@ + diff --git a/win32/vs2019/libzint.vcxproj b/win32/vs2019/libzint.vcxproj index 22d840cf..84717cdb 100644 --- a/win32/vs2019/libzint.vcxproj +++ b/win32/vs2019/libzint.vcxproj @@ -139,6 +139,7 @@ + @@ -187,6 +188,7 @@ + diff --git a/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp b/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp index c6f19728..d4b13c9b 100644 --- a/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp +++ b/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp @@ -156,6 +156,10 @@ SOURCE=..\..\backend\emf.c # End Source File # Begin Source File +SOURCE=..\..\backend\filemem.c +# End Source File +# Begin Source File + SOURCE=..\..\backend\general_field.c # End Source File # Begin Source File