Compare commits
53 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c9909d3d91 | ||
|
88155343bf | ||
|
f1f283d6a1 | ||
|
705b7254f2 | ||
|
71b2dc50b7 | ||
|
7e6da28761 | ||
|
5e2044ff2e | ||
|
752c1fae5d | ||
|
c1666cf350 | ||
|
34be69d241 | ||
|
b42d5baf4c | ||
|
93c3e27fba | ||
|
10747d6385 | ||
|
7f4ccccb98 | ||
|
3c7a702169 | ||
|
9c701f1009 | ||
|
b3a8680a90 | ||
|
857021de84 | ||
|
fb3b3001aa | ||
|
7246d67175 | ||
|
d70edce067 | ||
|
d97fc7e110 | ||
|
04e8cacb81 | ||
|
83fe2f3fee | ||
|
a1aefdc50b | ||
|
eb035a6372 | ||
|
0a00d04ccc | ||
|
3960dfdbfc | ||
|
c8bb299908 | ||
|
0eaa9f3e7d | ||
|
5390c0df92 | ||
|
bdb4fcbcf8 | ||
|
55a7369cd8 | ||
|
624574a64c | ||
|
11b3c18aed | ||
|
f0d8901d9e | ||
|
f312cdf630 | ||
|
e167f5b534 | ||
|
7b41dfbee2 | ||
|
7c1bdba8ae | ||
|
57fac4048d | ||
|
1449866d18 | ||
|
bead450f38 | ||
|
cf04ac15b0 | ||
|
f3a982c1dd | ||
|
d42eb13841 | ||
|
3cb724253b | ||
|
2a55ba0cef | ||
|
f37831bfef | ||
|
3950b49050 | ||
|
98f86727cc | ||
|
070162214b | ||
|
6ff485e6fa |
3
.clang-tidy
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
Checks: 'clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-clang-analyzer-security.insecureAPI.strcpy'
|
||||
HeaderFilterRegex: '.*'
|
101
CMakeLists.txt
@ -1,5 +1,5 @@
|
||||
# Copyright (C) 2008 by BogDan Vatra < bogdan@licentia.eu >
|
||||
# Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
# Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
# vim: set ts=4 sw=4 et :
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
@ -10,13 +10,11 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(ZINT_VERSION_MAJOR 2)
|
||||
set(ZINT_VERSION_MINOR 13)
|
||||
set(ZINT_VERSION_RELEASE 0)
|
||||
set(ZINT_VERSION_BUILD 0) # Set to 0 before release, set to 9 after release
|
||||
set(ZINT_VERSION_BUILD 9) # Set to 0 before release, set to 9 after release
|
||||
set(ZINT_VERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}.${ZINT_VERSION_RELEASE}.${ZINT_VERSION_BUILD}")
|
||||
|
||||
add_definitions(-DZINT_VERSION=\"${ZINT_VERSION}\")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
|
||||
|
||||
option(ZINT_DEBUG "Set debug compile flags" OFF)
|
||||
option(ZINT_NOOPT "Set no optimize compile flags" OFF)
|
||||
option(ZINT_SANITIZE "Set sanitize compile/link flags" OFF)
|
||||
@ -34,38 +32,51 @@ if(NOT ZINT_SHARED AND NOT ZINT_STATIC)
|
||||
message(SEND_ERROR "Either ZINT_SHARED or ZINT_STATIC or both must be set")
|
||||
endif()
|
||||
|
||||
include(SetPaths.cmake)
|
||||
include(GNUInstallDirs)
|
||||
# Taken from old (2008) KDE "SetPaths.cmake"
|
||||
# Set a default build type for single-configuration CMake generators if no build type is set
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||
endif()
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckFunctionExists)
|
||||
|
||||
if(NOT MSVC) # Use default warnings if MSVC otherwise inundated
|
||||
check_cxx_compiler_flag("-Wall" CXX_COMPILER_FLAG_WALL)
|
||||
if(CXX_COMPILER_FLAG_WALL)
|
||||
check_c_compiler_flag("-Wall" C_COMPILER_FLAG_WALL)
|
||||
if(C_COMPILER_FLAG_WALL)
|
||||
add_compile_options("-Wall")
|
||||
endif()
|
||||
|
||||
check_cxx_compiler_flag("-Wextra" CXX_COMPILER_FLAG_WEXTRA)
|
||||
if(CXX_COMPILER_FLAG_WEXTRA)
|
||||
check_c_compiler_flag("-Wextra" C_COMPILER_FLAG_WEXTRA)
|
||||
if(C_COMPILER_FLAG_WEXTRA)
|
||||
add_compile_options("-Wextra")
|
||||
endif()
|
||||
|
||||
check_cxx_compiler_flag("-Wpedantic" CXX_COMPILER_FLAG_WPEDANTIC)
|
||||
if(CXX_COMPILER_FLAG_WPEDANTIC)
|
||||
add_compile_options("-Wpedantic")
|
||||
# gcc complains about "%n$" `errtxtf()` arguments if "-Wpedantic" used, so only use for clang
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
check_c_compiler_flag("-Wpedantic" C_COMPILER_FLAG_WPEDANTIC)
|
||||
if(C_COMPILER_FLAG_WPEDANTIC)
|
||||
add_compile_options("-Wpedantic")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_c_compiler_flag("-Wundef" C_COMPILER_FLAG_WUNDEF)
|
||||
if(C_COMPILER_FLAG_WUNDEF)
|
||||
add_compile_options("-Wundef")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ZINT_DEBUG)
|
||||
check_cxx_compiler_flag("-g" CXX_COMPILER_FLAG_G)
|
||||
if(CXX_COMPILER_FLAG_G)
|
||||
check_c_compiler_flag("-g" C_COMPILER_FLAG_G)
|
||||
if(C_COMPILER_FLAG_G)
|
||||
add_compile_options("-g")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ZINT_NOOPT)
|
||||
check_cxx_compiler_flag("-O0" CXX_COMPILER_FLAG_O0)
|
||||
if(CXX_COMPILER_FLAG_O0)
|
||||
check_c_compiler_flag("-O0" C_COMPILER_FLAG_O0)
|
||||
if(C_COMPILER_FLAG_O0)
|
||||
add_compile_options("-O0")
|
||||
endif()
|
||||
endif()
|
||||
@ -82,19 +93,19 @@ if(ZINT_SANITIZE)
|
||||
set(SANITIZERS address undefined)
|
||||
foreach(sanitizer IN ITEMS ${SANITIZERS})
|
||||
set(CMAKE_REQUIRED_LIBRARIES -fsanitize=${sanitizer})
|
||||
check_cxx_compiler_flag(-fsanitize=${sanitizer} CXX_COMPILER_FLAG_FSANITIZE_${sanitizer})
|
||||
if(CXX_COMPILER_FLAG_FSANITIZE_${sanitizer})
|
||||
check_c_compiler_flag(-fsanitize=${sanitizer} C_COMPILER_FLAG_FSANITIZE_${sanitizer})
|
||||
if(C_COMPILER_FLAG_FSANITIZE_${sanitizer})
|
||||
add_compile_options(-fsanitize=${sanitizer})
|
||||
link_libraries(-fsanitize=${sanitizer})
|
||||
endif()
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
endforeach()
|
||||
|
||||
if(NOT ZINT_DEBUG AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
if(NOT ZINT_DEBUG AND CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
# Gives warning on MainWindow::setupUI() and retries (& takes forever) if var-tracking-assignments enabled
|
||||
add_compile_options(-fno-var-tracking-assignments)
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# Recent clangs added deprecation warnings for `sprintf()` that are only triggered on sanitize - suppress
|
||||
add_compile_options(-Wno-deprecated-declarations)
|
||||
endif()
|
||||
@ -107,40 +118,21 @@ endif()
|
||||
|
||||
if(ZINT_COVERAGE)
|
||||
set(CMAKE_REQUIRED_LIBRARIES -fprofile-arcs)
|
||||
check_cxx_compiler_flag(--coverage CXX_COMPILER_FLAG_COVERAGE)
|
||||
check_c_compiler_flag(--coverage C_COMPILER_FLAG_COVERAGE)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
if(CXX_COMPILER_FLAG_COVERAGE)
|
||||
if(C_COMPILER_FLAG_COVERAGE)
|
||||
add_compile_options(--coverage)
|
||||
link_libraries(-fprofile-arcs)
|
||||
|
||||
check_cxx_compiler_flag(-O0 CXX_COMPILER_FLAG_O0)
|
||||
if(CXX_COMPILER_FLAG_O0)
|
||||
check_c_compiler_flag(-O0 C_COMPILER_FLAG_O0)
|
||||
if(C_COMPILER_FLAG_O0)
|
||||
add_compile_options(-O0)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(UNIVERSAL) # TODO: make universal binary
|
||||
if(NOT ZINT_HAS_BEEN_RUN_BEFORE)
|
||||
if(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk)
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;i386;ppc64;x86_64" CACHE STRING "Build architectures for OSX" FORCE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING
|
||||
"Flags used by the compiler during all build types." FORCE)
|
||||
elseif(EXISTS /Developer/SDKs/MacOSX10.4u.sdk OR EXISTS /SDKs/MacOSX10.4u.sdk)
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;i386" CACHE STRING "Build architectures for OSX" FORCE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING
|
||||
"Flags used by the compiler during all build types." FORCE)
|
||||
endif()
|
||||
message("Build architectures for OSX:${CMAKE_OSX_ARCHITECTURES}")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_OSX_SYSROOT "/")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_function_exists(getopt HAVE_GETOPT)
|
||||
if(NOT HAVE_GETOPT)
|
||||
check_function_exists(getopt_long_only HAVE_GETOPT_LONG_ONLY)
|
||||
if(NOT HAVE_GETOPT_LONG_ONLY)
|
||||
add_subdirectory(getopt)
|
||||
endif()
|
||||
|
||||
@ -198,20 +190,5 @@ if(ZINT_UNINSTALL)
|
||||
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
endif()
|
||||
|
||||
# staniek: don't install
|
||||
if(DATA_INSTALL_DIR)
|
||||
set(CMAKE_MODULES_INSTALL_PATH ${DATA_INSTALL_DIR}/cmake/modules)
|
||||
else()
|
||||
set(CMAKE_MODULES_INSTALL_PATH ${CMAKE_ROOT}/Modules)
|
||||
endif()
|
||||
|
||||
install(FILES cmake/modules/FindZint.cmake DESTINATION ${CMAKE_MODULES_INSTALL_PATH} COMPONENT Devel)
|
||||
configure_file("zint-config.cmake.in" "zint-config.cmake" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zint-config.cmake" DESTINATION "${SHARE_INSTALL_PREFIX}/zint")
|
||||
|
||||
# This needs to be run very last so other parts of the scripts can take
|
||||
# advantage of this.
|
||||
if(NOT ZINT_HAS_BEEN_RUN_BEFORE)
|
||||
set(ZINT_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL
|
||||
"Flag to track whether this is the first time running CMake or if CMake has been configured before")
|
||||
endif()
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zint-config.cmake" DESTINATION "${CMAKE_INSTALL_DATADIR}/zint")
|
||||
|
75
ChangeLog
@ -1,3 +1,75 @@
|
||||
Version 2.13.0.9 (dev) not released yet
|
||||
=======================================
|
||||
|
||||
**Incompatible changes**
|
||||
------------------------
|
||||
- New `memfile` & `memfile_size` fields in `symbol` for use with new output
|
||||
option `BARCODE_MEMORY_FILE`
|
||||
- Invalid `input_mode` now returns warning
|
||||
- Aztec Code symbols that due to input length & user-requested version have less
|
||||
than recommended 5% error correction codewords now return warning
|
||||
- New CODE128-only special extra escape `\^1` for manually inserting FNC1s
|
||||
- Add-ons for UPC-A and UPC-E now descend to be level with the main symbol guard
|
||||
bars, and the righthand outside digit is now placed 1X less from main symbol
|
||||
to avoid touching any add-on
|
||||
|
||||
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
|
||||
- CODE16K (was for CODE128): improve encodation on A/B shifting, props Daniel
|
||||
Gredler (Okapi)
|
||||
- CODE128: add new extra escape `\^1` for manual insertion of FNC1s, ticket
|
||||
#324, props Jim Shank;
|
||||
add minimal encodation algorithm (non-extended ASCII only), props Alex Geller
|
||||
(ZXing);
|
||||
reduce extended latch cut-off from 5 to 4 for better encodation in certain
|
||||
cases, props Bue Jensen (BWIPP)
|
||||
- library: return warning on invalid `input_mode` reset
|
||||
- library/CLI: expanded error messages
|
||||
- GS1: new AIs 7250-7259 (GSCN 22-246);
|
||||
iso4217: new ISO 4217 currency code 924;
|
||||
new AIs 7041 (GSCN 23-272) (packagetype) and 716 (GSCN-24-157)
|
||||
- AZTEC: workaround MSVC 2022 optimizer bug in `az_populate_map()` loops,
|
||||
ticket #317, props Andre Maute;
|
||||
return warning if ECC < 5% (due to bit-stuffing when version given)
|
||||
- MAXICODE: zero-pad US postcodes that lack "+4" (Annex B.1.4a), from
|
||||
OkapiBarcode, props Daniel Gredler;
|
||||
use code set E for padding as well, saves codeword, props Bue Jensen (BWIPP PR
|
||||
#279)
|
||||
- GUI: use X11 (xcb) as platform instead of Wayland on Linux to avoid various
|
||||
weird behaviours;
|
||||
in "grpDATF.ui" use "PlainText" rather than "RichText" for tracker ratio
|
||||
examples as height of text messing up sometimes
|
||||
- UPCA/UPCE: descend add-ons to same level as guards and adjust righthand
|
||||
outside digit to be 4X/2X instead of 5X/3X away from main symbol so as not to
|
||||
touch add-on TODO: revisit when standard clarified
|
||||
- manual: make explicit that AI "(00)" and "(01)" prefixes added by Zint are
|
||||
HRT-only; clarify Codablock-F length maximum & add examples
|
||||
|
||||
Bugs
|
||||
----
|
||||
- raster/BMP/GIF/PCX/TIF: fix dealing with very large data (use `size_t`)
|
||||
- raster: add `raster_malloc()` to fail > 1GB (avoids very large output files;
|
||||
also lessens to some degree chances of being victim of OOM killer on Linux)
|
||||
- GUI: printing scale dialog: set maxima on X-dim and resolution to keep scale
|
||||
<= 200
|
||||
- BMP/EMF/PCX/TIF: fix endianness on big-endian machines (note TIF now always
|
||||
written as little-endian - simplifies testing)
|
||||
- ITF14/DPLEIT/DPIDENT: ignore `option_2` (check digit options)
|
||||
- GUI: scalewindow: fix cropping of initial resolution and bound X-dim <= 10
|
||||
- GUI: factory reset: reset preview background colour also
|
||||
- GUI: cliwindow: `#if _WIN32` -> `#ifdef _WIN32`
|
||||
- QZint: fix legacy width and security level getters/setters, MR #158, props
|
||||
Philip Ye
|
||||
- CODE128: fix extended char latching when exactly 3 extended chars at end
|
||||
- library: need to check for valid UTF-8 after de-escaping
|
||||
- MAXICODE: maintain current set between segments
|
||||
|
||||
|
||||
Version 2.13.0 (2023-12-18)
|
||||
===========================
|
||||
|
||||
@ -134,6 +206,9 @@ Bugs
|
||||
- QRCODE: fix out-of-bounds crash due to incorrect mode costings for GS1
|
||||
percents in `qr_in_alpha()`; fix incorrect numeric costings (out-by-1) in
|
||||
`qr_in_numeric()`; ticket #300 (#14, #15; #16), props Andre Maute
|
||||
- GS1: fix square brackets treated as FNC1 in GS1PARENS_MODE by changing
|
||||
internal FNC1 marker '[' -> '\x1D' (GS), ticket #319, props Moli Sojet;
|
||||
also fix non-AI square brackets -> round brackets in GS1_128 HRT
|
||||
|
||||
|
||||
Version 2.12.0 (2022-12-12)
|
||||
|
19
README.bsd
@ -1,4 +1,5 @@
|
||||
% Tested on FreeBSD 13.2-RELEASE (with X11 + GNOME installed) and OpenBSD 7.3 (with X11)
|
||||
% README.bsd 2024-01-17
|
||||
% Tested on FreeBSD 14.0-RELEASE (with X11 + GNOME installed), OpenBSD 7.4 (with X11) and NetBSD 9.3 (with X11)
|
||||
|
||||
1. Prerequisites for building zint
|
||||
==================================
|
||||
@ -15,6 +16,12 @@ or OpenBSD (make and clang should already be installed):
|
||||
pkg_add git cmake png
|
||||
exit
|
||||
|
||||
or NetBSD (make and gcc should already be installed):
|
||||
|
||||
su
|
||||
pkgin install git cmake png
|
||||
exit
|
||||
|
||||
Then clone the latest source
|
||||
|
||||
git clone https://git.code.sf.net/p/zint/code zint
|
||||
@ -36,6 +43,12 @@ On OpenBSD:
|
||||
pkg_add qtbase qttools qtsvg
|
||||
exit
|
||||
|
||||
On NetBSD:
|
||||
|
||||
su
|
||||
pkgin install qt5-qtbase qt5-qttools qt5-qtsvg
|
||||
exit
|
||||
|
||||
|
||||
3. Build
|
||||
========
|
||||
@ -54,6 +67,10 @@ except that on OpenBSD you need to use
|
||||
|
||||
cmake -DCMAKE_PREFIX_PATH=/usr/local/lib/qt5/cmake ..
|
||||
|
||||
and on NetBSD
|
||||
|
||||
cmake -DCMAKE_PREFIX_PATH=/usr/pkg/qt5 ..
|
||||
|
||||
instead.
|
||||
|
||||
|
||||
|
22
README.clang-tidy
Normal file
@ -0,0 +1,22 @@
|
||||
% README.clang-tidy 2024-09-03
|
||||
% Current as of latest clang-tidy-20 from Ubuntu 22.04 apt package
|
||||
|
||||
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-20 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-20 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-20 backend/tests/*.c frontend/tests/*.c backend_qt/tests/*.cpp \
|
||||
-checks='-clang-analyzer-optin.performance.Padding' -p build/compile_commands.json
|
15
README.linux
@ -1,4 +1,6 @@
|
||||
% Tested on Ubuntu 20.04.4 LTS, Ubuntu 22.04 LTS and Fedora Linux 38 (Workstation Edition)
|
||||
% README.linux 2024-10-04
|
||||
% Tested on Ubuntu 20.04.4 LTS, Ubuntu 22.04 LTS, Ubuntu 24.04 LTS and
|
||||
% Fedora Linux 40 (Workstation Edition)
|
||||
|
||||
1. Prerequisites for building zint
|
||||
==================================
|
||||
@ -44,6 +46,9 @@ or Fedora
|
||||
|
||||
sudo dnf install mesa-libGL mesa-libGL-devel
|
||||
|
||||
zint-qt has issues running on Wayland so sets X11 as the Qt platform (via the environment variable
|
||||
"QT_QPA_PLATFORM=xcb") on startup unless already set.
|
||||
|
||||
2.1. Using Qt packages
|
||||
----------------------
|
||||
|
||||
@ -52,7 +57,7 @@ what their ever-changing names and contents are isn't. A complication is that zi
|
||||
components beyond the basic setup: Qt UI Tools (for dynamically loading the symbology-specific
|
||||
tabs), and Qt SVG (for rendering icons).
|
||||
|
||||
E.g. on Ubuntu 22.04
|
||||
E.g. on Ubuntu 22.04 or 24.04
|
||||
|
||||
sudo apt install qtbase5-dev qttools5-dev qttools5-dev-tools libqt5svg5-dev
|
||||
|
||||
@ -60,7 +65,7 @@ or Ubuntu 20.04
|
||||
|
||||
sudo apt install qt5-default qt5-uitools
|
||||
|
||||
or Fedora 38 (not recommended)
|
||||
or Fedora (not recommended)
|
||||
|
||||
sudo dnf install qt5-qtbase-devel qt5-qttools-devel qt5-qttools-static qt5-qtsvg-devel
|
||||
|
||||
@ -83,7 +88,7 @@ On Ubuntu/Debian you may need to install xinerama to run the tool:
|
||||
sudo apt install libxcb-xinerama0
|
||||
|
||||
Launch the tool and install the "Desktop gcc 64-bit" component for either Qt 5.15.2 (preferred)
|
||||
or Qt 6 (>= 6.1, 6.2.4 preferably, and not >= 6.3 which are incompatible).
|
||||
or Qt 6 (>= 6.1).
|
||||
|
||||
Once Qt is installed you may need to tell CMake where it is:
|
||||
|
||||
@ -112,11 +117,13 @@ A number of options are available:
|
||||
|
||||
ZINT_COVERAGE:BOOL=OFF # Set code coverage flags
|
||||
ZINT_DEBUG:BOOL=OFF # Set debug compile flags
|
||||
ZINT_FRONTEND:BOOL=ON # Build frontend
|
||||
ZINT_NOOPT:BOOL=OFF # Set no optimize compile flags
|
||||
ZINT_SANITIZE:BOOL=OFF # Set sanitize compile/link flags
|
||||
ZINT_SHARED:BOOL=ON # Build shared library
|
||||
ZINT_STATIC:BOOL=OFF # Build static library
|
||||
ZINT_TEST:BOOL=OFF # Set test compile flag
|
||||
ZINT_UNINSTALL:BOOL=ON # Add uninstall target
|
||||
ZINT_USE_PNG:BOOL=ON # Build with PNG support
|
||||
ZINT_USE_QT:BOOL=ON # Build with Qt support
|
||||
ZINT_QT6:BOOL=OFF # If ZINT_USE_QT, use Qt6
|
||||
|
@ -1,4 +1,5 @@
|
||||
% Tested on macOS 12.4 Monterey VirtualBox (thanks to https://github.com/myspaghetti/macos-virtualbox)
|
||||
% README.macos 2024-01-18
|
||||
% Tested on macOS 12.7.2 Monterey VirtualBox (thanks to https://github.com/myspaghetti/macos-virtualbox)
|
||||
|
||||
1. Prerequisites for building zint and zint-qt
|
||||
==============================================
|
||||
|
@ -1 +1,2 @@
|
||||
% README.windows 2024-01-17
|
||||
See "README" in the "win32" sub-directory.
|
||||
|
273
SetPaths.cmake
@ -1,273 +0,0 @@
|
||||
# - Find include and library dirs, and define a some macros
|
||||
#
|
||||
# This module defines a bunch of variables used as locations for install directories.
|
||||
# They can be relative (to CMAKE_INSTALL_PREFIX) or absolute.
|
||||
# Under Windows they are always relative.
|
||||
#
|
||||
# BIN_INSTALL_DIR - the directory where executables will be installed (default is prefix/bin)
|
||||
# BUNDLE_INSTALL_DIR - Mac only: the directory where application bundles will be installed (default is /Applications/KDE4 )
|
||||
# SBIN_INSTALL_DIR - the directory where system executables will be installed (default is prefix/sbin)
|
||||
# LIB_INSTALL_DIR - the directory where libraries will be installed (default is prefix/lib)
|
||||
# CONFIG_INSTALL_DIR - the config file install dir
|
||||
# DATA_INSTALL_DIR - the parent directory where applications can install their data
|
||||
# HTML_INSTALL_DIR - the HTML install dir for documentation
|
||||
# ICON_INSTALL_DIR - the icon install dir (default prefix/share/icons/)
|
||||
# INFO_INSTALL_DIR - the kde info install dir (default prefix/info)
|
||||
# KCFG_INSTALL_DIR - the install dir for kconfig files
|
||||
# LOCALE_INSTALL_DIR - the install dir for translations
|
||||
# MAN_INSTALL_DIR - the kde man page install dir (default prefix/man/)
|
||||
# MIME_INSTALL_DIR - the install dir for the mimetype desktop files
|
||||
# PLUGIN_INSTALL_DIR - the subdirectory relative to the install prefix where plugins will be installed (default is ${KDE4_LIB_INSTALL_DIR}/kde4)
|
||||
# SERVICES_INSTALL_DIR - the install dir for service (desktop, protocol, ...) files
|
||||
# SERVICETYPES_INSTALL_DIR - the install dir for servicestypes desktop files
|
||||
# SOUND_INSTALL_DIR - the install dir for sound files
|
||||
# TEMPLATES_INSTALL_DIR - the install dir for templates (Create new file...)
|
||||
# WALLPAPER_INSTALL_DIR - the install dir for wallpapers
|
||||
# DEMO_INSTALL_DIR - the install dir for demos
|
||||
# KCONF_UPDATE_INSTALL_DIR - the kconf_update install dir
|
||||
# XDG_APPS_INSTALL_DIR - the XDG apps dir
|
||||
# XDG_DIRECTORY_INSTALL_DIR- the XDG directory
|
||||
# XDG_MIME_INSTALL_DIR - the XDG mimetypes install dir
|
||||
# DBUS_INTERFACES_INSTALL_DIR - the directory where dbus interfaces be installed (default is prefix/share/dbus-1/interfaces)
|
||||
# DBUS_SERVICES_INSTALL_DIR - the directory where dbus services be installed (default is prefix/share/dbus-1/services )
|
||||
#
|
||||
# A note on the possible values for CMAKE_BUILD_TYPE and how KDE handles
|
||||
# the flags for those buildtypes. FindKDE4Internal supports the values
|
||||
# Debug, Release, Relwithdebinfo, Profile and Debugfull
|
||||
#
|
||||
# Release
|
||||
# optimised for speed, qDebug/kDebug turned off, no debug symbols
|
||||
# Release with debug info
|
||||
# optimised for speed, debugging symbols on (-g)
|
||||
# Debug
|
||||
# optimised but debuggable, debugging on (-g)
|
||||
# (-fno-reorder-blocks -fno-schedule-insns -fno-inline)
|
||||
# DebugFull
|
||||
# no optimisation, full debugging on (-g3)
|
||||
# Profile
|
||||
# DebugFull + -ftest-coverage -fprofile-arcs
|
||||
#
|
||||
# It is expected that the "Debug" build type be still debuggable with gdb
|
||||
# without going all over the place, but still produce better performance.
|
||||
# It's also important to note that gcc cannot detect all warning conditions
|
||||
# unless the optimiser is active.
|
||||
#
|
||||
|
||||
# Copyright (c) 2006-2008, Alexander Neundorf <neundorf@kde.org>
|
||||
# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
|
||||
# Copyright (c) 2008, BogDan Vatra, <bogdan@licentia.eu>
|
||||
#
|
||||
# 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 copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
|
||||
########## the following are directories where stuff will be installed to ###########
|
||||
#
|
||||
# this has to be after find_xxx() block above
|
||||
|
||||
if (WIN32)
|
||||
# use relative install prefix to avoid hardcoded install paths in cmake_install.cmake files
|
||||
|
||||
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" ) # The subdirectory relative to the install prefix where libraries will be installed (default is ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX})
|
||||
|
||||
set(EXEC_INSTALL_PREFIX "" ) # Base directory for executables and libraries
|
||||
set(SHARE_INSTALL_PREFIX "share" ) # Base directory for files which go to share/
|
||||
set(BIN_INSTALL_DIR "bin" ) # The install dir for executables (default ${EXEC_INSTALL_PREFIX}/bin)
|
||||
set(SBIN_INSTALL_DIR "sbin" ) # The install dir for system executables (default ${EXEC_INSTALL_PREFIX}/sbin)
|
||||
|
||||
set(LIBEXEC_INSTALL_DIR "${BIN_INSTALL_DIR}" ) # The subdirectory relative to the install prefix where libraries will be installed (default is ${BIN_INSTALL_DIR})
|
||||
set(INCLUDE_INSTALL_DIR "include" ) # The subdirectory to the header prefix
|
||||
|
||||
set(PLUGIN_INSTALL_DIR "lib${LIB_SUFFIX}/kde4" ) # "The subdirectory relative to the install prefix where plugins will be installed (default is ${LIB_INSTALL_DIR}/kde4)
|
||||
set(CONFIG_INSTALL_DIR "share/config" ) # The config file install dir
|
||||
set(DATA_INSTALL_DIR "share/apps" ) # The parent directory where applications can install their data
|
||||
set(HTML_INSTALL_DIR "share/doc/HTML" ) # The HTML install dir for documentation
|
||||
set(ICON_INSTALL_DIR "share/icons" ) # The icon install dir (default ${SHARE_INSTALL_PREFIX}/share/icons/)
|
||||
set(KCFG_INSTALL_DIR "share/config.kcfg" ) # The install dir for kconfig files
|
||||
set(LOCALE_INSTALL_DIR "share/locale" ) # The install dir for translations
|
||||
set(MIME_INSTALL_DIR "share/mimelnk" ) # The install dir for the mimetype desktop files
|
||||
set(SERVICES_INSTALL_DIR "share/kde4/services" ) # The install dir for service (desktop, protocol, ...) files
|
||||
set(SERVICETYPES_INSTALL_DIR "share/kde4/servicetypes" ) # The install dir for servicestypes desktop files
|
||||
set(SOUND_INSTALL_DIR "share/sounds" ) # The install dir for sound files
|
||||
set(TEMPLATES_INSTALL_DIR "share/templates" ) # The install dir for templates (Create new file...)
|
||||
set(WALLPAPER_INSTALL_DIR "share/wallpapers" ) # The install dir for wallpapers
|
||||
set(DEMO_INSTALL_DIR "share/demos" ) # The install dir for demos
|
||||
set(KCONF_UPDATE_INSTALL_DIR "share/apps/kconf_update" ) # The kconf_update install dir
|
||||
set(AUTOSTART_INSTALL_DIR "share/autostart" ) # The install dir for autostart files
|
||||
|
||||
set(XDG_APPS_INSTALL_DIR "share/applications/kde4" ) # The XDG apps dir
|
||||
set(XDG_DIRECTORY_INSTALL_DIR "share/desktop-directories" ) # The XDG directory
|
||||
set(XDG_MIME_INSTALL_DIR "share/mime/packages" ) # The install dir for the xdg mimetypes
|
||||
|
||||
set(SYSCONF_INSTALL_DIR "etc" ) # The kde sysconfig install dir (default /etc)
|
||||
set(MAN_INSTALL_DIR "share/man" ) # The kde man install dir (default ${SHARE_INSTALL_PREFIX}/man/)
|
||||
set(INFO_INSTALL_DIR "share/info" ) # The kde info install dir (default ${SHARE_INSTALL_PREFIX}/info)")
|
||||
set(DBUS_INTERFACES_INSTALL_DIR "share/dbus-1/interfaces" ) # The kde dbus interfaces install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/interfaces)")
|
||||
set(DBUS_SERVICES_INSTALL_DIR "share/dbus-1/services" ) # The kde dbus services install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/services)")
|
||||
|
||||
else (WIN32)
|
||||
|
||||
# This macro implements some very special logic how to deal with the cache.
|
||||
# By default the various install locations inherit their value from their "parent" variable
|
||||
# so if you set CMAKE_INSTALL_PREFIX, then EXEC_INSTALL_PREFIX, PLUGIN_INSTALL_DIR will
|
||||
# calculate their value by appending subdirs to CMAKE_INSTALL_PREFIX .
|
||||
# This would work completely without using the cache.
|
||||
# But if somebody wants e.g. a different EXEC_INSTALL_PREFIX this value has to go into
|
||||
# the cache, otherwise it will be forgotten on the next cmake run.
|
||||
# Once a variable is in the cache, it doesn't depend on its "parent" variables
|
||||
# anymore and you can only change it by editing it directly.
|
||||
# this macro helps in this regard, because as long as you don't set one of the
|
||||
# variables explicitely to some location, it will always calculate its value from its
|
||||
# parents. So modifying CMAKE_INSTALL_PREFIX later on will have the desired effect.
|
||||
# But once you decide to set e.g. EXEC_INSTALL_PREFIX to some special location
|
||||
# this will go into the cache and it will no longer depend on CMAKE_INSTALL_PREFIX.
|
||||
#
|
||||
# additionally if installing to the same location as kdelibs, the other install
|
||||
# directories are reused from the installed kdelibs
|
||||
macro(_SET_FANCY _var _value _comment)
|
||||
set(predefinedvalue "${_value}")
|
||||
|
||||
if (NOT DEFINED ${_var})
|
||||
set(${_var} ${predefinedvalue})
|
||||
else (NOT DEFINED ${_var})
|
||||
set(${_var} "${${_var}}" CACHE PATH "${_comment}")
|
||||
endif (NOT DEFINED ${_var})
|
||||
endmacro(_SET_FANCY)
|
||||
|
||||
if(APPLE)
|
||||
set(BUNDLE_INSTALL_DIR "/Applications/KDE4" CACHE PATH "Directory where application bundles will be installed to on OSX" )
|
||||
endif(APPLE)
|
||||
|
||||
_set_fancy(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" "Base directory for executables and libraries")
|
||||
_set_fancy(SHARE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share" "Base directory for files which go to share/")
|
||||
_set_fancy(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" "The install dir for executables (default ${EXEC_INSTALL_PREFIX}/bin)")
|
||||
_set_fancy(SBIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/sbin" "The install dir for system executables (default ${EXEC_INSTALL_PREFIX}/sbin)")
|
||||
_set_fancy(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}" "The subdirectory relative to the install prefix where libraries will be installed (default is ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX})")
|
||||
_set_fancy(LIBEXEC_INSTALL_DIR "${LIB_INSTALL_DIR}/kde4/libexec" "The subdirectory relative to the install prefix where libraries will be installed (default is ${LIB_INSTALL_DIR}/kde4/libexec)")
|
||||
_set_fancy(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" "The subdirectory to the header prefix")
|
||||
|
||||
_set_fancy(PLUGIN_INSTALL_DIR "${LIB_INSTALL_DIR}/kde4" "The subdirectory relative to the install prefix where plugins will be installed (default is ${LIB_INSTALL_DIR}/kde4)")
|
||||
_set_fancy(CONFIG_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/config" "The config file install dir")
|
||||
_set_fancy(DATA_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/apps" "The parent directory where applications can install their data")
|
||||
_set_fancy(HTML_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/doc/HTML" "The HTML install dir for documentation")
|
||||
_set_fancy(ICON_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/icons" "The icon install dir (default ${SHARE_INSTALL_PREFIX}/share/icons/)")
|
||||
_set_fancy(KCFG_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/config.kcfg" "The install dir for kconfig files")
|
||||
_set_fancy(LOCALE_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/locale" "The install dir for translations")
|
||||
_set_fancy(MIME_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/mimelnk" "The install dir for the mimetype desktop files")
|
||||
_set_fancy(SERVICES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/kde4/services" "The install dir for service (desktop, protocol, ...) files")
|
||||
_set_fancy(SERVICETYPES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/kde4/servicetypes" "The install dir for servicestypes desktop files")
|
||||
_set_fancy(SOUND_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/sounds" "The install dir for sound files")
|
||||
_set_fancy(TEMPLATES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/templates" "The install dir for templates (Create new file...)")
|
||||
_set_fancy(WALLPAPER_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/wallpapers" "The install dir for wallpapers")
|
||||
_set_fancy(DEMO_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/demos" "The install dir for demos")
|
||||
_set_fancy(KCONF_UPDATE_INSTALL_DIR "${DATA_INSTALL_DIR}/kconf_update" "The kconf_update install dir")
|
||||
_set_fancy(AUTOSTART_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/autostart" "The install dir for autostart files")
|
||||
|
||||
_set_fancy(XDG_APPS_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/applications/kde4" "The XDG apps dir")
|
||||
_set_fancy(XDG_DIRECTORY_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/desktop-directories" "The XDG directory")
|
||||
_set_fancy(XDG_MIME_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/mime/packages" "The install dir for the xdg mimetypes")
|
||||
|
||||
_set_fancy(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc" "The kde sysconfig install dir (default ${CMAKE_INSTALL_PREFIX}/etc)")
|
||||
_set_fancy(MAN_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/man" "The kde man install dir (default ${SHARE_INSTALL_PREFIX}/man/)")
|
||||
_set_fancy(INFO_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/info" "The kde info install dir (default ${SHARE_INSTALL_PREFIX}/info)")
|
||||
_set_fancy(DBUS_INTERFACES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/dbus-1/interfaces" "The kde dbus interfaces install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/interfaces)")
|
||||
_set_fancy(DBUS_SERVICES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/dbus-1/services" "The kde dbus services install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/services)")
|
||||
|
||||
endif (WIN32)
|
||||
|
||||
|
||||
# The INSTALL_TARGETS_DEFAULT_ARGS variable should be used when libraries are installed.
|
||||
# The arguments are also ok for regular executables, i.e. executables which don't go
|
||||
# into sbin/ or libexec/, but for installing executables the basic syntax
|
||||
# INSTALL(TARGETS kate DESTINATION "${BIN_INSTALL_DIR}")
|
||||
# is enough, so using this variable there doesn't help a lot.
|
||||
# The variable must not be used for installing plugins.
|
||||
# Usage is like this:
|
||||
# install(TARGETS kdecore kdeui ${INSTALL_TARGETS_DEFAULT_ARGS} )
|
||||
#
|
||||
# This will install libraries correctly under UNIX, OSX and Windows (i.e. dll's go
|
||||
# into bin/.
|
||||
# Later on it will be possible to extend this for installing OSX frameworks
|
||||
# The COMPONENT Devel argument has the effect that static libraries belong to the
|
||||
# "Devel" install component. If we use this also for all install() commands
|
||||
# for header files, it will be possible to install
|
||||
# -everything: make install OR cmake -P cmake_install.cmake
|
||||
# -only the development files: cmake -DCOMPONENT=Devel -P cmake_install.cmake
|
||||
# -everything except the development files: cmake -DCOMPONENT=Unspecified -P cmake_install.cmake
|
||||
# This can then also be used for packaging with cpack.
|
||||
|
||||
set(INSTALL_TARGETS_DEFAULT_ARGS RUNTIME DESTINATION "${BIN_INSTALL_DIR}"
|
||||
LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
|
||||
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}" COMPONENT Devel )
|
||||
|
||||
|
||||
|
||||
# on the Mac support an extra install directory for application bundles starting with cmake 2.6
|
||||
if(APPLE)
|
||||
set(INSTALL_TARGETS_DEFAULT_ARGS ${INSTALL_TARGETS_DEFAULT_ARGS}
|
||||
BUNDLE DESTINATION "${BUNDLE_INSTALL_DIR}" )
|
||||
endif(APPLE)
|
||||
|
||||
|
||||
set(CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH}
|
||||
"${INCLUDE_INSTALL_DIR}")
|
||||
|
||||
set(CMAKE_SYSTEM_PROGRAM_PATH ${CMAKE_SYSTEM_PROGRAM_PATH}
|
||||
"${BIN_INSTALL_DIR}" )
|
||||
|
||||
set(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH}
|
||||
"${LIB_INSTALL_DIR}" )
|
||||
|
||||
# under Windows dlls may be also installed in bin/
|
||||
if(WIN32)
|
||||
set(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH}
|
||||
"${_CMAKE_INSTALL_DIR}/bin"
|
||||
"${CMAKE_INSTALL_PREFIX}/bin" )
|
||||
endif(WIN32)
|
||||
|
||||
|
||||
######################################################
|
||||
# and now the platform specific stuff
|
||||
######################################################
|
||||
|
||||
# Set a default build type for single-configuration
|
||||
# CMake generators if no build type is set.
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||
endif (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
|
||||
|
||||
# setup default RPATH/install_name handling, may be overridden by KDE4_HANDLE_RPATH_FOR_[LIBRARY|EXECUTABLE]
|
||||
# default is to build with RPATH for the install dir, so it doesn't need to relink
|
||||
if (UNIX)
|
||||
if (APPLE)
|
||||
set(CMAKE_INSTALL_NAME_DIR ${LIB_INSTALL_DIR})
|
||||
else (APPLE)
|
||||
# add our LIB_INSTALL_DIR to the RPATH and use the RPATH figured out by cmake when compiling
|
||||
set(CMAKE_INSTALL_RPATH ${LIB_INSTALL_DIR} )
|
||||
set(CMAKE_SKIP_BUILD_RPATH TRUE)
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
endif (APPLE)
|
||||
endif (UNIX)
|
||||
|
119
backend/2of5.c
@ -1,7 +1,7 @@
|
||||
/* 2of5.c - Handles Code 2 of 5 barcodes */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -34,6 +34,7 @@
|
||||
#include "common.h"
|
||||
#include "gs1.h"
|
||||
|
||||
/* First 5 of each entry Interleaved also */
|
||||
static const char C25MatrixTable[10][6] = {
|
||||
{'1','1','3','3','1','1'}, {'3','1','1','1','3','1'}, {'1','3','1','1','3','1'}, {'3','3','1','1','1','1'},
|
||||
{'1','1','3','1','3','1'}, {'3','1','3','1','1','1'}, {'1','3','3','1','1','1'}, {'1','1','1','3','3','1'},
|
||||
@ -49,38 +50,30 @@ static const char C25IndustTable[10][10] = {
|
||||
};
|
||||
|
||||
/* Note `c25_common()` assumes Stop string length one less than Start */
|
||||
static const char *C25MatrixStartStop[2] = { "411111", "41111" };
|
||||
static const char *C25IndustStartStop[2] = { "313111", "31113" };
|
||||
static const char *C25IataLogicStartStop[2] = { "1111", "311" };
|
||||
|
||||
static const char C25InterTable[10][5] = {
|
||||
{'1','1','3','3','1'}, {'3','1','1','1','3'}, {'1','3','1','1','3'}, {'3','3','1','1','1'}, {'1','1','3','1','3'},
|
||||
{'3','1','3','1','1'}, {'1','3','3','1','1'}, {'1','1','1','3','3'}, {'3','1','1','3','1'}, {'1','3','1','3','1'}
|
||||
};
|
||||
|
||||
static char c25_check_digit(const unsigned int count) {
|
||||
return itoc((10 - (count % 10)) % 10);
|
||||
}
|
||||
static const char C25MatrixStartStop[2][6] = { {'4', '1', '1', '1', '1', '1'}, {'4', '1', '1', '1', '1'} };
|
||||
static const char C25IndustStartStop[2][6] = { {'3', '1', '3', '1', '1', '1'}, {'3', '1', '1', '1', '3'} };
|
||||
static const char C25IataLogicStartStop[2][6] = { {'1', '1', '1', '1'}, {'3', '1', '1'} };
|
||||
|
||||
/* Common to Standard (Matrix), Industrial, IATA, and Data Logic */
|
||||
static int c25_common(struct zint_symbol *symbol, const unsigned char source[], int length, const int max,
|
||||
const int is_matrix, const char *start_stop[2], const int start_length, const int error_base) {
|
||||
const int is_matrix, const char start_stop[2][6], const int start_length, const int error_base) {
|
||||
|
||||
int i;
|
||||
char dest[818]; /* Largest destination 4 + (80 + 1) * 10 + 3 + 1 = 818 */
|
||||
char *d = dest;
|
||||
unsigned char temp[113 + 1 + 1]; /* Largest maximum 113 + optional check digit */
|
||||
int have_checkdigit = symbol->option_2 == 1 || symbol->option_2 == 2;
|
||||
const int have_checkdigit = symbol->option_2 == 1 || symbol->option_2 == 2;
|
||||
|
||||
if (length > max) {
|
||||
/* errtxt 301: 303: 305: 307: */
|
||||
sprintf(symbol->errtxt, "%d: Input too long (%d character maximum)", error_base, max);
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, error_base, "Input length %1$d too long (maximum %2$d)", length,
|
||||
max);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
/* Note: for all "at position" error messages, escape sequences not accounted for */
|
||||
/* errtxt 302: 304: 306: 308: */
|
||||
sprintf(symbol->errtxt, "%d: Invalid character in data (digits only)", error_base + 1);
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, error_base + 1,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
ustrcpy(temp, source);
|
||||
@ -147,31 +140,31 @@ INTERNAL int c25logic(struct zint_symbol *symbol, unsigned char source[], int le
|
||||
|
||||
/* Common to Interleaved, ITF-14, DP Leitcode, DP Identcode */
|
||||
static int c25_inter_common(struct zint_symbol *symbol, unsigned char source[], int length,
|
||||
const int dont_set_height) {
|
||||
const int checkdigit_option, const int dont_set_height) {
|
||||
int i, j, error_number = 0;
|
||||
char dest[638]; /* 4 + (125 + 1) * 5 + 3 + 1 = 638 */
|
||||
char *d = dest;
|
||||
unsigned char temp[125 + 1 + 1];
|
||||
int have_checkdigit = symbol->option_2 == 1 || symbol->option_2 == 2;
|
||||
const int have_checkdigit = checkdigit_option == 1 || checkdigit_option == 2;
|
||||
|
||||
if (length > 125) { /* 4 + (125 + 1) * 9 + 5 = 1143 */
|
||||
strcpy(symbol->errtxt, "309: Input too long (125 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 309, "Input length %d too long (maximum 125)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "310: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 310,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
temp[0] = '\0';
|
||||
/* Input must be an even number of characters for Interlaced 2 of 5 to work:
|
||||
if an odd number of characters has been entered and no check digit or an even number and have check digit
|
||||
then add a leading zero */
|
||||
if (((length & 1) && !have_checkdigit) || (!(length & 1) && have_checkdigit)) {
|
||||
ustrcpy(temp, "0");
|
||||
length++;
|
||||
if (have_checkdigit == !(length & 1)) {
|
||||
temp[0] = '0';
|
||||
memcpy(temp + 1, source, length++);
|
||||
} else {
|
||||
memcpy(temp, source, length);
|
||||
}
|
||||
ustrncat(temp, source, length);
|
||||
temp[length] = '\0';
|
||||
|
||||
if (have_checkdigit) {
|
||||
/* Add standard GS1 check digit */
|
||||
@ -179,16 +172,16 @@ static int c25_inter_common(struct zint_symbol *symbol, unsigned char source[],
|
||||
temp[++length] = '\0';
|
||||
}
|
||||
|
||||
/* start character */
|
||||
/* Start character */
|
||||
memcpy(d, "1111", 4);
|
||||
d += 4;
|
||||
|
||||
for (i = 0; i < length; i += 2) {
|
||||
/* look up the bars and the spaces */
|
||||
const char *const bars = C25InterTable[temp[i] - '0'];
|
||||
const char *const spaces = C25InterTable[temp[i + 1] - '0'];
|
||||
/* Look up the bars and the spaces */
|
||||
const char *const bars = C25MatrixTable[temp[i] - '0'];
|
||||
const char *const spaces = C25MatrixTable[temp[i + 1] - '0'];
|
||||
|
||||
/* then merge (interlace) the strings together */
|
||||
/* Then merge (interlace) the strings together */
|
||||
for (j = 0; j < 5; j++) {
|
||||
*d++ = bars[j];
|
||||
*d++ = spaces[j];
|
||||
@ -202,7 +195,7 @@ static int c25_inter_common(struct zint_symbol *symbol, unsigned char source[],
|
||||
expand(symbol, dest, d - dest);
|
||||
|
||||
ustrcpy(symbol->text, temp);
|
||||
if (symbol->option_2 == 2) {
|
||||
if (checkdigit_option == 2) {
|
||||
/* Remove check digit from HRT */
|
||||
symbol->text[length - 1] = '\0';
|
||||
}
|
||||
@ -213,7 +206,7 @@ static int c25_inter_common(struct zint_symbol *symbol, unsigned char source[],
|
||||
(P = character pairs, N = wide/narrow ratio = 3)
|
||||
width = (P(4N + 6) + N + 6)X = (length / 2) * 18 + 9 */
|
||||
/* Taking min X = 0.330mm from Annex D.3.1 (application specification) */
|
||||
const float min_height_min = stripf(5.0f / 0.33f);
|
||||
const float min_height_min = 15.151515f; /* 5.0 / 0.33 */
|
||||
float min_height = stripf((18.0f * (length / 2) + 9.0f) * 0.15f);
|
||||
if (min_height < min_height_min) {
|
||||
min_height = min_height_min;
|
||||
@ -231,7 +224,7 @@ static int c25_inter_common(struct zint_symbol *symbol, unsigned char source[],
|
||||
|
||||
/* Code 2 of 5 Interleaved ISO/IEC 16390:2007 */
|
||||
INTERNAL int c25inter(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
return c25_inter_common(symbol, source, length, 0 /*dont_set_height*/);
|
||||
return c25_inter_common(symbol, source, length, symbol->option_2 /*checkdigit_option*/, 0 /*dont_set_height*/);
|
||||
}
|
||||
|
||||
/* Interleaved 2-of-5 (ITF-14) */
|
||||
@ -240,13 +233,12 @@ INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int lengt
|
||||
unsigned char localstr[16] = {0};
|
||||
|
||||
if (length > 13) {
|
||||
strcpy(symbol->errtxt, "311: Input too long (13 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 311, "Input length %d too long (maximum 13)", length);
|
||||
}
|
||||
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "312: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 312,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
/* Add leading zeros as required */
|
||||
@ -259,7 +251,7 @@ INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int lengt
|
||||
/* Calculate the check digit - the same method used for EAN-13 */
|
||||
localstr[13] = gs1_check_digit(localstr, 13);
|
||||
localstr[14] = '\0';
|
||||
error_number = c25_inter_common(symbol, localstr, 14, 1 /*dont_set_height*/);
|
||||
error_number = c25_inter_common(symbol, localstr, 14, 0 /*checkdigit_option*/, 1 /*dont_set_height*/);
|
||||
ustrcpy(symbol->text, localstr);
|
||||
|
||||
if (error_number < ZINT_ERROR) {
|
||||
@ -276,7 +268,9 @@ INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int lengt
|
||||
/* GS1 General Specifications 21.0.1 5.12.3.2 table 2, including footnote (**): (note bind/box additional
|
||||
to symbol->height), same as GS1-128: "in case of further space constraints"
|
||||
height 5.8mm / 1.016mm (X max) ~ 5.7; default 31.75mm / 0.495mm ~ 64.14 */
|
||||
error_number = set_height(symbol, stripf(5.8f / 1.016f), stripf(31.75f / 0.495f), 0.0f, 0 /*no_errtxt*/);
|
||||
const float min_height = 5.70866156f; /* 5.8 / 1.016 */
|
||||
const float default_height = 64.1414108f; /* 31.75 / 0.495 */
|
||||
error_number = set_height(symbol, min_height, default_height, 0.0f, 0 /*no_errtxt*/);
|
||||
} else {
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
@ -285,6 +279,11 @@ INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int lengt
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Deutsche Post check digit */
|
||||
static char c25_dp_check_digit(const unsigned int count) {
|
||||
return itoc((10 - (count % 10)) % 10);
|
||||
}
|
||||
|
||||
/* Deutsche Post Leitcode */
|
||||
/* Documentation (of a very incomplete and non-technical type):
|
||||
https://www.deutschepost.de/content/dam/dpag/images/D_d/dialogpost-schwer/dp-dialogpost-schwer-broschuere-072021.pdf
|
||||
@ -298,12 +297,11 @@ INTERNAL int dpleit(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
|
||||
count = 0;
|
||||
if (length > 13) {
|
||||
strcpy(symbol->errtxt, "313: Input wrong length (13 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 313, "Input length %d too long (maximum 13)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "314: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 314,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
zeroes = 13 - length;
|
||||
@ -316,9 +314,9 @@ INTERNAL int dpleit(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
count += factor * ctoi(localstr[i]);
|
||||
factor ^= 0x0D; /* Toggles 4 and 9 */
|
||||
}
|
||||
localstr[13] = c25_check_digit(count);
|
||||
localstr[13] = c25_dp_check_digit(count);
|
||||
localstr[14] = '\0';
|
||||
error_number = c25_inter_common(symbol, localstr, 14, 1 /*dont_set_height*/);
|
||||
error_number = c25_inter_common(symbol, localstr, 14, 0 /*checkdigit_option*/, 1 /*dont_set_height*/);
|
||||
|
||||
/* HRT formatting as per DIALOGPOST SCHWER brochure but TEC-IT differs as do examples at
|
||||
https://www.philaseiten.de/cgi-bin/index.pl?ST=8615&CP=0&F=1#M147 */
|
||||
@ -346,12 +344,11 @@ INTERNAL int dpident(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
|
||||
count = 0;
|
||||
if (length > 11) {
|
||||
strcpy(symbol->errtxt, "315: Input wrong length (11 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 315, "Input length %d too long (maximum 11)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "316: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 316,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
zeroes = 11 - length;
|
||||
@ -364,9 +361,9 @@ INTERNAL int dpident(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
count += factor * ctoi(localstr[i]);
|
||||
factor ^= 0x0D; /* Toggles 4 and 9 */
|
||||
}
|
||||
localstr[11] = c25_check_digit(count);
|
||||
localstr[11] = c25_dp_check_digit(count);
|
||||
localstr[12] = '\0';
|
||||
error_number = c25_inter_common(symbol, localstr, 12, 1 /*dont_set_height*/);
|
||||
error_number = c25_inter_common(symbol, localstr, 12, 0 /*checkdigit_option*/, 1 /*dont_set_height*/);
|
||||
|
||||
/* HRT formatting as per DIALOGPOST SCHWER brochure but TEC-IT differs as do other examples (see above) */
|
||||
for (i = 0, j = 0; i <= 12; i++) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Copyright (C) 2008 by BogDan Vatra < bogdan@licentia.eu >
|
||||
# Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
# Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
# vim: set ts=4 sw=4 et :
|
||||
|
||||
project(zint)
|
||||
@ -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)
|
||||
@ -54,6 +54,15 @@ function(zint_target_compile_definitions scope definition)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(zint_target_compile_options scope option)
|
||||
if(ZINT_SHARED)
|
||||
target_compile_options(zint ${scope} ${option})
|
||||
endif()
|
||||
if(ZINT_STATIC)
|
||||
target_compile_options(zint-static ${scope} ${option})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(zint_target_include_directories)
|
||||
if(ZINT_SHARED)
|
||||
target_include_directories(zint ${ARGN})
|
||||
@ -80,6 +89,11 @@ if(ZINT_TEST)
|
||||
zint_target_compile_definitions(PUBLIC ZINT_TEST)
|
||||
endif()
|
||||
|
||||
check_c_compiler_flag("-Wc90-c99-compat" C_COMPILER_FLAG_WC90_C99_COMPAT)
|
||||
if(C_COMPILER_FLAG_WC90_C99_COMPAT)
|
||||
zint_target_compile_options(PRIVATE "-Wc90-c99-compat")
|
||||
endif()
|
||||
|
||||
if(NOT MSVC)
|
||||
# Link with standard C math library.
|
||||
zint_target_link_libraries(m)
|
||||
@ -93,17 +107,22 @@ endif()
|
||||
|
||||
zint_target_include_directories(PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${INCLUDE_INSTALL_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
# Adapted from old (2008) KDE "SetPaths.cmake" to use GNUInstallDirs
|
||||
set(INSTALL_TARGETS_DEFAULT_ARGS RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Devel)
|
||||
|
||||
if(ZINT_SHARED)
|
||||
install(TARGETS zint EXPORT zint-targets ${INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
endif()
|
||||
if(ZINT_STATIC)
|
||||
install(TARGETS zint-static EXPORT zint-targets ${INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
endif()
|
||||
install(EXPORT zint-targets NAMESPACE zint:: DESTINATION "${SHARE_INSTALL_PREFIX}/zint")
|
||||
install(FILES zint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel)
|
||||
install(EXPORT zint-targets NAMESPACE zint:: DESTINATION "${CMAKE_INSTALL_DATADIR}/zint")
|
||||
install(FILES zint.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT Devel)
|
||||
|
||||
if(ZINT_TEST)
|
||||
add_subdirectory(tests)
|
||||
|
@ -6,7 +6,7 @@
|
||||
# make clean cleans up a previous compilation and any object or editor files
|
||||
#
|
||||
|
||||
ZINT_VERSION:=-DZINT_VERSION=\"2.13.0\"
|
||||
ZINT_VERSION:=-DZINT_VERSION=\"2.13.0.9\"
|
||||
|
||||
|
||||
CC:= gcc
|
||||
@ -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
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* auspost.c - Handles Australia Post 4-State Barcode */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -91,7 +91,7 @@ static char *aus_rs_error(char data_pattern[], char *d) {
|
||||
rs_encode(&rs, triple_writer, triple, result);
|
||||
|
||||
for (reader = 4; reader > 0; reader--, d += 3) {
|
||||
memcpy(d, AusBarTable[(int) result[reader - 1]], 3);
|
||||
memcpy(d, AusBarTable[result[reader - 1]], 3);
|
||||
}
|
||||
|
||||
return d;
|
||||
@ -110,6 +110,7 @@ INTERNAL int auspost(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
1 = Tracker and Ascender
|
||||
2 = Tracker and Descender
|
||||
3 = Tracker only */
|
||||
int i;
|
||||
int error_number;
|
||||
int writer;
|
||||
int loopey, reader;
|
||||
@ -123,18 +124,17 @@ INTERNAL int auspost(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
/* Do all of the length checking first to avoid stack smashing */
|
||||
if (symbol->symbology == BARCODE_AUSPOST) {
|
||||
if (length != 8 && length != 13 && length != 16 && length != 18 && length != 23) {
|
||||
strcpy(symbol->errtxt, "401: Input wrong length (8, 13, 16, 18 or 23 characters only)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 401, "Input length %d wrong (8, 13, 16, 18 or 23 only)",
|
||||
length);
|
||||
}
|
||||
} else if (length > 8) {
|
||||
strcpy(symbol->errtxt, "403: Input too long (8 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 403, "Input length %d too long (maximum 8)", length);
|
||||
}
|
||||
|
||||
/* Check input immediately to catch nuls */
|
||||
if (!is_sane(GDSET_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "404: Invalid character in data (alphanumerics, space and \"#\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(GDSET_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 404,
|
||||
"Invalid character at position %d in input (alphanumerics, space and \"#\" only)", i);
|
||||
}
|
||||
|
||||
localstr[0] = '\0';
|
||||
@ -150,9 +150,10 @@ INTERNAL int auspost(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
break;
|
||||
case 16:
|
||||
strcpy(fcc, "59");
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "402: Invalid character in data (digits only for length 16)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 402,
|
||||
"Invalid character at position %d in input (digits only for FCC 59 length 16)",
|
||||
i);
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
@ -160,9 +161,10 @@ INTERNAL int auspost(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
break;
|
||||
case 23:
|
||||
strcpy(fcc, "62");
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "406: Invalid character in data (digits only for length 23)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 406,
|
||||
"Invalid character at position %d in input (digits only for FCC 62 length 23)",
|
||||
i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -192,9 +194,9 @@ INTERNAL int auspost(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
/* Verify that the first 8 characters are numbers */
|
||||
memcpy(dpid, localstr, 8);
|
||||
dpid[8] = '\0';
|
||||
if (!is_sane(NEON_F, (unsigned char *) dpid, 8)) {
|
||||
strcpy(symbol->errtxt, "405: Invalid character in DPID (first 8 characters) (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, (unsigned char *) dpid, 8))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 405,
|
||||
"Invalid character at position %d in DPID (first 8 characters) (digits only)", i);
|
||||
}
|
||||
|
||||
/* Start character */
|
||||
|
283
backend/aztec.c
@ -1,7 +1,7 @@
|
||||
/* aztec.c - Handles Aztec 2D Symbols */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -37,10 +37,15 @@
|
||||
#include "reedsol.h"
|
||||
|
||||
#define AZTEC_MAX_CAPACITY 19968 /* ISO/IEC 24778:2008 5.3 Table 1 Maximum Symbol Bit Capacity */
|
||||
#define AZTEC_BIN_CAPACITY 17940 /* Above less 169 * 12 = 2028 bits (169 = 10% of 1664 + 3) */
|
||||
/* Allow up to absolute minimum 3 ECC codewords, but now warn if results in less than the 5% minimum (ISO/IEC
|
||||
24778:2008 4.1.e) - previously could go down to 3 ECC codewords anyway if version given, due to bit-stuffing */
|
||||
#define AZTEC_BIN_CAPACITY 19932 /* AZTEC_MAX_CAPACITY less 3 * 12 = 36 */
|
||||
#define AZTEC_MAP_SIZE 22801 /* AztecMap Version 32 151 x 151 */
|
||||
#define AZTEC_MAP_POSN_MAX 20039 /* Maximum position index in AztecMap */
|
||||
|
||||
#define AZ_BIN_CAP_CWDS_S "1661" /* String version of (AZTEC_BIN_CAPACITY / 12) */
|
||||
|
||||
/* Count number of consecutive (. SP) or (, SP) Punct mode doubles for comparison against Digit mode encoding */
|
||||
static int az_count_doubles(const unsigned char source[], int i, const int length) {
|
||||
int c = 0;
|
||||
|
||||
@ -52,6 +57,7 @@ static int az_count_doubles(const unsigned char source[], int i, const int lengt
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Count number of consecutive full stops or commas (can be encoded in Punct or Digit mode) */
|
||||
static int az_count_dotcomma(const unsigned char source[], int i, const int length) {
|
||||
int c = 0;
|
||||
|
||||
@ -63,6 +69,7 @@ static int az_count_dotcomma(const unsigned char source[], int i, const int leng
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Count number of consecutive `chr`s */
|
||||
static int az_count_chr(const unsigned char source[], int i, const int length, const unsigned char chr) {
|
||||
int c = 0;
|
||||
|
||||
@ -74,6 +81,7 @@ static int az_count_chr(const unsigned char source[], int i, const int length, c
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Return mode following current, or 'E' if none */
|
||||
static char az_get_next_mode(const char encode_mode[], const int src_len, int i) {
|
||||
int current_mode = encode_mode[i];
|
||||
|
||||
@ -87,6 +95,7 @@ static char az_get_next_mode(const char encode_mode[], const int src_len, int i)
|
||||
}
|
||||
}
|
||||
|
||||
/* Same as `bin_append_posn()`, except check for buffer overflow first */
|
||||
static int az_bin_append_posn(const int arg, const int length, char *binary, const int bin_posn) {
|
||||
|
||||
if (bin_posn + length > AZTEC_BIN_CAPACITY) {
|
||||
@ -95,6 +104,7 @@ static int az_bin_append_posn(const int arg, const int length, char *binary, con
|
||||
return bin_append_posn(arg, length, binary, bin_posn);
|
||||
}
|
||||
|
||||
/* Determine encoding modes and encode */
|
||||
static int aztec_text_process(const unsigned char source[], int src_len, int bp, char binary_string[], const int gs1,
|
||||
const int eci, char *p_current_mode, int *data_length, const int debug_print) {
|
||||
|
||||
@ -111,8 +121,10 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
|
||||
for (i = 0; i < src_len; i++) {
|
||||
if (source[i] >= 128) {
|
||||
encode_mode[i] = 'B';
|
||||
} else if (gs1 && source[i] == '\x1D') {
|
||||
encode_mode[i] = 'P'; /* For FLG(n) & FLG(0) = FNC1 */
|
||||
} else {
|
||||
encode_mode[i] = AztecModes[(int) source[i]];
|
||||
encode_mode[i] = AztecModes[source[i]];
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,32 +191,25 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
|
||||
i = 0;
|
||||
j = 0;
|
||||
while (i < src_len) {
|
||||
reduced_encode_mode[j] = encode_mode[i];
|
||||
if (i + 1 < src_len) {
|
||||
if ((source[i] == 13) && (source[i + 1] == 10)) { /* CR LF */
|
||||
reduced_source[j] = 'a';
|
||||
reduced_encode_mode[j] = encode_mode[i];
|
||||
i += 2;
|
||||
} else if ((source[i] == '.') && (source[i + 1] == ' ') && (encode_mode[i] == 'P')) {
|
||||
reduced_source[j] = 'b';
|
||||
reduced_encode_mode[j] = encode_mode[i];
|
||||
i += 2;
|
||||
} else if ((source[i] == ',') && (source[i + 1] == ' ') && (encode_mode[i] == 'P')) {
|
||||
reduced_source[j] = 'c';
|
||||
reduced_encode_mode[j] = encode_mode[i];
|
||||
i += 2;
|
||||
} else if ((source[i] == ':') && (source[i + 1] == ' ')) {
|
||||
reduced_source[j] = 'd';
|
||||
reduced_encode_mode[j] = encode_mode[i];
|
||||
i += 2;
|
||||
} else {
|
||||
reduced_source[j] = source[i];
|
||||
reduced_encode_mode[j] = encode_mode[i];
|
||||
i++;
|
||||
reduced_source[j] = source[i++];
|
||||
}
|
||||
} else {
|
||||
reduced_source[j] = source[i];
|
||||
reduced_encode_mode[j] = encode_mode[i];
|
||||
i++;
|
||||
reduced_source[j] = source[i++];
|
||||
}
|
||||
j++;
|
||||
}
|
||||
@ -576,7 +581,9 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
|
||||
int big_batch = 0;
|
||||
for (count = 0; ((i + count) < reduced_length) && (reduced_encode_mode[i + count] == 'B'); count++);
|
||||
|
||||
assert(count <= 2047 + 2078); /* Can't be more than 19968 / 8 = 2496 */
|
||||
if (count > 2047 + 2078) { /* Can't be more than 19968 / 8 = 2496 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (count > 2047) { /* Max 11-bit number */
|
||||
big_batch = count > 2078 ? 2078 : count;
|
||||
@ -616,15 +623,13 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
|
||||
if (reduced_source[i] == ' ') {
|
||||
if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return 0; /* SP */
|
||||
} else {
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp)))
|
||||
return 0;
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[reduced_source[i]], 5, binary_string, bp))) return 0;
|
||||
}
|
||||
} else if (reduced_encode_mode[i] == 'L') {
|
||||
if (reduced_source[i] == ' ') {
|
||||
if (!(bp = az_bin_append_posn(1, 5, binary_string, bp))) return 0; /* SP */
|
||||
} else {
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp)))
|
||||
return 0;
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[reduced_source[i]], 5, binary_string, bp))) return 0;
|
||||
}
|
||||
} else if (reduced_encode_mode[i] == 'M') {
|
||||
if (reduced_source[i] == ' ') {
|
||||
@ -632,11 +637,10 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
|
||||
} else if (reduced_source[i] == 13) {
|
||||
if (!(bp = az_bin_append_posn(14, 5, binary_string, bp))) return 0; /* CR */
|
||||
} else {
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp)))
|
||||
return 0;
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[reduced_source[i]], 5, binary_string, bp))) return 0;
|
||||
}
|
||||
} else if ((reduced_encode_mode[i] == 'P') || (reduced_encode_mode[i] == 'p')) {
|
||||
if (gs1 && (reduced_source[i] == '[')) {
|
||||
if (gs1 && reduced_source[i] == '\x1D') {
|
||||
if (!(bp = az_bin_append_posn(0, 5, binary_string, bp))) return 0; /* FLG(n) */
|
||||
if (!(bp = az_bin_append_posn(0, 3, binary_string, bp))) return 0; /* FLG(0) = FNC1 */
|
||||
} else if (reduced_source[i] == 13) {
|
||||
@ -654,8 +658,7 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
|
||||
} else if (reduced_source[i] == '.') {
|
||||
if (!(bp = az_bin_append_posn(19, 5, binary_string, bp))) return 0; /* Full stop */
|
||||
} else {
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string, bp)))
|
||||
return 0;
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[reduced_source[i]], 5, binary_string, bp))) return 0;
|
||||
}
|
||||
} else if (reduced_encode_mode[i] == 'D') {
|
||||
if (reduced_source[i] == ' ') {
|
||||
@ -665,8 +668,7 @@ static int aztec_text_process(const unsigned char source[], int src_len, int bp,
|
||||
} else if (reduced_source[i] == '.') {
|
||||
if (!(bp = az_bin_append_posn(13, 4, binary_string, bp))) return 0; /* Full stop */
|
||||
} else {
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[(int) reduced_source[i]], 4, binary_string, bp)))
|
||||
return 0;
|
||||
if (!(bp = az_bin_append_posn(AztecSymbolChar[reduced_source[i]], 4, binary_string, bp))) return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -714,7 +716,7 @@ static int az_avoidReferenceGrid(int output) {
|
||||
|
||||
/* Calculate the position of the bits in the grid (non-compact) */
|
||||
static void az_populate_map(short AztecMap[], const int layers) {
|
||||
int layer, n, i;
|
||||
int layer;
|
||||
int x, y;
|
||||
const int offset = AztecOffset[layers - 1];
|
||||
const int endoffset = 151 - offset;
|
||||
@ -723,53 +725,50 @@ static void az_populate_map(short AztecMap[], const int layers) {
|
||||
const int start = (112 * layer) + (16 * layer * layer) + 2;
|
||||
const int length = 28 + (layer * 4) + (layer + 1) * 4;
|
||||
int av0, av1;
|
||||
int n = start, end;
|
||||
/* Top */
|
||||
i = 0;
|
||||
x = 64 - (layer * 2);
|
||||
y = 63 - (layer * 2);
|
||||
av0 = az_avoidReferenceGrid(y) * 151;
|
||||
av1 = az_avoidReferenceGrid(y - 1) * 151;
|
||||
for (n = start; n < (start + length); n += 2) {
|
||||
int avxi = az_avoidReferenceGrid(x + i);
|
||||
AztecMap[av0 + avxi] = n;
|
||||
AztecMap[av1 + avxi] = n + 1;
|
||||
i++;
|
||||
end = start + length;
|
||||
while (n < end) {
|
||||
const int avxi = az_avoidReferenceGrid(x++);
|
||||
AztecMap[av0 + avxi] = n++;
|
||||
AztecMap[av1 + avxi] = n++;
|
||||
}
|
||||
/* Right */
|
||||
i = 0;
|
||||
x = 78 + (layer * 2);
|
||||
y = 64 - (layer * 2);
|
||||
av0 = az_avoidReferenceGrid(x);
|
||||
av1 = az_avoidReferenceGrid(x + 1);
|
||||
for (n = start + length; n < (start + (length * 2)); n += 2) {
|
||||
int avyi = az_avoidReferenceGrid(y + i) * 151;
|
||||
AztecMap[avyi + av0] = n;
|
||||
AztecMap[avyi + av1] = n + 1;
|
||||
i++;
|
||||
end += length;
|
||||
while (n < end) {
|
||||
const int avyi = az_avoidReferenceGrid(y++) * 151;
|
||||
AztecMap[avyi + av0] = n++;
|
||||
AztecMap[avyi + av1] = n++;
|
||||
}
|
||||
/* Bottom */
|
||||
i = 0;
|
||||
x = 77 + (layer * 2);
|
||||
y = 78 + (layer * 2);
|
||||
av0 = az_avoidReferenceGrid(y) * 151;
|
||||
av1 = az_avoidReferenceGrid(y + 1) * 151;
|
||||
for (n = start + (length * 2); n < (start + (length * 3)); n += 2) {
|
||||
int avxi = az_avoidReferenceGrid(x - i);
|
||||
AztecMap[av0 + avxi] = n;
|
||||
AztecMap[av1 + avxi] = n + 1;
|
||||
i++;
|
||||
end += length;
|
||||
while (n < end) {
|
||||
const int avxi = az_avoidReferenceGrid(x--);
|
||||
AztecMap[av0 + avxi] = n++;
|
||||
AztecMap[av1 + avxi] = n++;
|
||||
}
|
||||
/* Left */
|
||||
i = 0;
|
||||
x = 63 - (layer * 2);
|
||||
y = 77 + (layer * 2);
|
||||
av0 = az_avoidReferenceGrid(x);
|
||||
av1 = az_avoidReferenceGrid(x - 1);
|
||||
for (n = start + (length * 3); n < (start + (length * 4)); n += 2) {
|
||||
int avyi = az_avoidReferenceGrid(y - i) * 151;
|
||||
AztecMap[avyi + av0] = n;
|
||||
AztecMap[avyi + av1] = n + 1;
|
||||
i++;
|
||||
end += length;
|
||||
while (n < end) {
|
||||
const int avyi = az_avoidReferenceGrid(y--) * 151;
|
||||
AztecMap[avyi + av0] = n++;
|
||||
AztecMap[avyi + av1] = n++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -789,7 +788,7 @@ static void az_populate_map(short AztecMap[], const int layers) {
|
||||
|
||||
/* Helper to insert dummy '0' or '1's into runs of same bits. See ISO/IEC 24778:2008 7.3.1.2 */
|
||||
static int az_bitrun_stuff(const char *binary_string, const int data_length, const int codeword_size,
|
||||
char adjusted_string[AZTEC_MAX_CAPACITY]) {
|
||||
const int data_maxsize, char adjusted_string[AZTEC_MAX_CAPACITY]) {
|
||||
int i, j = 0, count = 0;
|
||||
|
||||
for (i = 0; i < data_length; i++) {
|
||||
@ -801,7 +800,7 @@ static int az_bitrun_stuff(const char *binary_string, const int data_length, con
|
||||
|
||||
if (count == 0 || count == (codeword_size - 1)) {
|
||||
/* Codeword of B-1 '0's or B-1 '1's */
|
||||
if (j >= AZTEC_MAX_CAPACITY) {
|
||||
if (j > data_maxsize) {
|
||||
return 0; /* Fail */
|
||||
}
|
||||
adjusted_string[j++] = count == 0 ? '1' : '0';
|
||||
@ -813,7 +812,7 @@ static int az_bitrun_stuff(const char *binary_string, const int data_length, con
|
||||
} else if (binary_string[i] == '1') { /* Skip B so only counting B-1 */
|
||||
count++;
|
||||
}
|
||||
if (j >= AZTEC_MAX_CAPACITY) {
|
||||
if (j > data_maxsize) {
|
||||
return 0; /* Fail */
|
||||
}
|
||||
adjusted_string[j++] = binary_string[i];
|
||||
@ -869,23 +868,18 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
int error_number = 0;
|
||||
int compact, data_length, data_maxsize, codeword_size, adjusted_length;
|
||||
int remainder, padbits, adjustment_size;
|
||||
int reader = 0;
|
||||
int comp_loop = 4;
|
||||
int bp = 0;
|
||||
const int gs1 = (symbol->input_mode & 0x07) == GS1_MODE;
|
||||
const int debug_print = (symbol->debug & ZINT_DEBUG_PRINT);
|
||||
const int reader_init = symbol->output_options & READER_INIT;
|
||||
const int compact_loop_start = reader_init ? 1 : 4; /* Compact 2-4 excluded from Reader Initialisation */
|
||||
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
|
||||
rs_t rs;
|
||||
rs_uint_t rs_uint;
|
||||
unsigned int *data_part;
|
||||
unsigned int *ecc_part;
|
||||
|
||||
if (symbol->output_options & READER_INIT) {
|
||||
reader = 1;
|
||||
comp_loop = 1;
|
||||
}
|
||||
if (gs1 && reader) {
|
||||
strcpy(symbol->errtxt, "501: Cannot encode in GS1 and Reader Initialisation mode at the same time");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
if (gs1 && reader_init) {
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 501, "Cannot use Reader Initialisation in GS1 mode");
|
||||
}
|
||||
|
||||
if (symbol->structapp.count) {
|
||||
@ -895,19 +889,20 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
int id_len;
|
||||
|
||||
if (symbol->structapp.count < 2 || symbol->structapp.count > 26) {
|
||||
strcpy(symbol->errtxt, "701: Structured Append count out of range (2-26)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 701,
|
||||
"Structured Append count '%d' out of range (2 to 26)", symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
|
||||
sprintf(symbol->errtxt, "702: Structured Append index out of range (1-%d)", symbol->structapp.count);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 702,
|
||||
"Structured Append index '%1$d' out of range (1 to count %2$d)",
|
||||
symbol->structapp.index, symbol->structapp.count);
|
||||
}
|
||||
|
||||
for (id_len = 0; id_len < 32 && symbol->structapp.id[id_len]; id_len++);
|
||||
|
||||
if (id_len && chr_cnt((const unsigned char *) symbol->structapp.id, id_len, ' ')) {
|
||||
strcpy(symbol->errtxt, "703: Structured Append ID cannot contain spaces");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
/* Note ID can contain any old chars apart from space so don't print in error message */
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 703, "Structured Append ID cannot contain spaces");
|
||||
}
|
||||
|
||||
bp = bin_append_posn(29, 5, binary_string, bp); /* M/L */
|
||||
@ -924,7 +919,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
sa_src[sa_len++] = 'A' + symbol->structapp.count - 1;
|
||||
if (debug_print) {
|
||||
printf("Structured Append Count: %d, Index: %d, ID: %.32s, String: %s\n",
|
||||
symbol->structapp.count, symbol->structapp.count, symbol->structapp.id, sa_src);
|
||||
symbol->structapp.count, symbol->structapp.index, symbol->structapp.id, sa_src);
|
||||
}
|
||||
|
||||
(void) aztec_text_process(sa_src, sa_len, bp, binary_string, 0 /*gs1*/, 0 /*eci*/, NULL /*p_current_mode*/,
|
||||
@ -933,32 +928,26 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
}
|
||||
|
||||
if (!aztec_text_process_segs(segs, seg_count, bp, binary_string, gs1, &data_length, debug_print)) {
|
||||
strcpy(symbol->errtxt, "502: Input too long or too many extended ASCII characters");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 502,
|
||||
"Input too long, requires too many codewords (maximum " AZ_BIN_CAP_CWDS_S ")");
|
||||
}
|
||||
assert(data_length > 0); /* Suppress clang-tidy warning: clang-analyzer-core.UndefinedBinaryOperatorResult */
|
||||
|
||||
if (!((symbol->option_1 >= -1) && (symbol->option_1 <= 4))) {
|
||||
strcpy(symbol->errtxt, "503: Invalid error correction level - using default instead");
|
||||
if (symbol->option_1 < -1 || symbol->option_1 > 4) {
|
||||
errtxtf(0, symbol, 503, "Error correction level '%d' out of range (1 to 4)", symbol->option_1);
|
||||
if (symbol->warn_level == WARN_FAIL_ALL) {
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
}
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
error_number = errtxt_adj(ZINT_WARN_INVALID_OPTION, symbol, "%1$s%2$s", ", ignoring");
|
||||
symbol->option_1 = -1;
|
||||
}
|
||||
|
||||
data_maxsize = 0; /* Keep compiler happy! */
|
||||
adjustment_size = 0;
|
||||
if (symbol->option_2 == 0) { /* The size of the symbol can be determined by Zint */
|
||||
static const short *full_sizes[5] = {
|
||||
NULL, Aztec10DataSizes, Aztec23DataSizes, Aztec36DataSizes, Aztec50DataSizes
|
||||
};
|
||||
static const short *comp_sizes[5] = {
|
||||
NULL, AztecCompact10DataSizes, AztecCompact23DataSizes, AztecCompact36DataSizes, AztecCompact50DataSizes
|
||||
};
|
||||
int ecc_level = symbol->option_1;
|
||||
|
||||
if ((ecc_level == -1) || (ecc_level == 0)) {
|
||||
if (ecc_level <= 0) {
|
||||
ecc_level = 2;
|
||||
}
|
||||
|
||||
@ -968,34 +957,43 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
layers = 0;
|
||||
|
||||
/* For each level of error correction work out the smallest symbol which the data will fit in */
|
||||
for (i = comp_loop; i > 0; i--) {
|
||||
if ((data_length + adjustment_size) < comp_sizes[ecc_level][i - 1]) {
|
||||
for (i = compact_loop_start; i > 0; i--) {
|
||||
if ((data_length + adjustment_size) <= AztecCompactDataSizes[ecc_level - 1][i - 1]) {
|
||||
layers = i;
|
||||
compact = 1;
|
||||
data_maxsize = comp_sizes[ecc_level][i - 1];
|
||||
data_maxsize = AztecCompactDataSizes[ecc_level - 1][i - 1];
|
||||
}
|
||||
}
|
||||
if (!compact) {
|
||||
for (i = 32; i > 0; i--) {
|
||||
if ((data_length + adjustment_size) < full_sizes[ecc_level][i - 1]) {
|
||||
if ((data_length + adjustment_size) <= AztecDataSizes[ecc_level - 1][i - 1]) {
|
||||
layers = i;
|
||||
compact = 0;
|
||||
data_maxsize = full_sizes[ecc_level][i - 1];
|
||||
data_maxsize = AztecDataSizes[ecc_level - 1][i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (layers == 0) { /* Couldn't find a symbol which fits the data */
|
||||
strcpy(symbol->errtxt, "504: Input too long (too many bits for selected ECC)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
if (adjustment_size == 0) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 707,
|
||||
"Input too long for ECC level %1$d, requires too many codewords (maximum %2$d)",
|
||||
ecc_level, AztecDataSizes[ecc_level - 1][31] / 12);
|
||||
}
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 504,
|
||||
"Input too long for ECC level %1$d, requires %2$d codewords (maximum %3$d)",
|
||||
ecc_level, (data_length + adjustment_size + 11) / 12,
|
||||
AztecDataSizes[ecc_level - 1][31] / 12);
|
||||
}
|
||||
|
||||
codeword_size = az_codeword_size(layers);
|
||||
|
||||
adjusted_length = az_bitrun_stuff(binary_string, data_length, codeword_size, adjusted_string);
|
||||
adjusted_length = az_bitrun_stuff(binary_string, data_length, codeword_size,
|
||||
adjustment_size ? data_maxsize : AZTEC_BIN_CAPACITY, adjusted_string);
|
||||
if (adjusted_length == 0) {
|
||||
strcpy(symbol->errtxt, "705: Data too long for specified Aztec Code symbol size");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 705,
|
||||
"Input too long for ECC level %1$d, requires too many codewords (maximum %2$d)",
|
||||
ecc_level, (adjustment_size ? data_maxsize : AZTEC_BIN_CAPACITY) / codeword_size);
|
||||
}
|
||||
adjustment_size = adjusted_length - data_length;
|
||||
|
||||
@ -1008,10 +1006,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
}
|
||||
if (debug_print) printf("Remainder: %d Pad bits: %d\n", remainder, padbits);
|
||||
|
||||
if (adjusted_length + padbits >= AZTEC_MAX_CAPACITY) { /* Probably can't happen */
|
||||
strcpy(symbol->errtxt, "706: Data too long for specified Aztec Code symbol size");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
assert(adjusted_length <= AZTEC_BIN_CAPACITY);
|
||||
|
||||
adjusted_length = az_add_padding(padbits, codeword_size, adjusted_string, adjusted_length);
|
||||
|
||||
@ -1024,11 +1019,19 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
|
||||
} else { /* The size of the symbol has been specified by the user */
|
||||
if ((symbol->option_2 < 0) || (symbol->option_2 > 36)) {
|
||||
strcpy(symbol->errtxt, "510: Invalid Aztec Code size");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 510, "Version '%d' out of range (1 to 36)",
|
||||
symbol->option_2);
|
||||
}
|
||||
if ((reader == 1) && ((symbol->option_2 >= 2) && (symbol->option_2 <= 4))) {
|
||||
symbol->option_2 = 5;
|
||||
if (reader_init) {
|
||||
/* For back-compatibility, silently ignore compact 2-4 requests but error on layers > 22 */
|
||||
if (symbol->option_2 >= 2 && symbol->option_2 <= 4) {
|
||||
symbol->option_2 = 5;
|
||||
} else if (symbol->option_2 > 26) {
|
||||
/* Caught below anyway but catch here also for better feedback */
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 709,
|
||||
"Version '%d' out of range for Reader Initialisation symbols (maximum 26)",
|
||||
symbol->option_2);
|
||||
}
|
||||
}
|
||||
if (symbol->option_2 <= 4) {
|
||||
compact = 1;
|
||||
@ -1039,11 +1042,17 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
}
|
||||
|
||||
codeword_size = az_codeword_size(layers);
|
||||
if (compact) {
|
||||
data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3);
|
||||
} else {
|
||||
data_maxsize = codeword_size * (AztecSizes[layers - 1] - 3);
|
||||
}
|
||||
|
||||
adjusted_length = az_bitrun_stuff(binary_string, data_length, codeword_size, adjusted_string);
|
||||
adjusted_length = az_bitrun_stuff(binary_string, data_length, codeword_size, data_maxsize, adjusted_string);
|
||||
if (adjusted_length == 0) {
|
||||
strcpy(symbol->errtxt, "704: Data too long for specified Aztec Code symbol size");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 704,
|
||||
"Input too long for Version %1$d, requires too many codewords (maximum %2$d)",
|
||||
symbol->option_2, data_maxsize / codeword_size);
|
||||
}
|
||||
|
||||
/* Add padding */
|
||||
@ -1056,15 +1065,12 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
if (debug_print) printf("Remainder: %d Pad bits: %d\n", remainder, padbits);
|
||||
|
||||
/* Check if the data actually fits into the selected symbol size */
|
||||
if (compact) {
|
||||
data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3);
|
||||
} else {
|
||||
data_maxsize = codeword_size * (AztecSizes[layers - 1] - 3);
|
||||
}
|
||||
|
||||
if (adjusted_length + padbits > data_maxsize) {
|
||||
strcpy(symbol->errtxt, "505: Data too long for specified Aztec Code symbol size");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 505,
|
||||
"Input too long for Version %1$d, requires %2$d codewords (maximum %3$d)",
|
||||
symbol->option_2, (adjusted_length + padbits) / codeword_size,
|
||||
data_maxsize / codeword_size);
|
||||
}
|
||||
|
||||
adjusted_length = az_add_padding(padbits, codeword_size, adjusted_string, adjusted_length);
|
||||
@ -1080,9 +1086,9 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
if (reader && (layers > 22)) {
|
||||
strcpy(symbol->errtxt, "506: Data too long for reader initialisation symbol");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
if (reader_init && (layers > 22)) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 506,
|
||||
"Input too long for Reader Initialisation, requires %d layers (maximum 22)", layers);
|
||||
}
|
||||
|
||||
data_blocks = adjusted_length / codeword_size;
|
||||
@ -1095,6 +1101,11 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
} else {
|
||||
ecc_blocks = AztecSizes[layers - 1] - data_blocks;
|
||||
}
|
||||
if (ecc_blocks < data_blocks / 20) {
|
||||
error_number = errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 708,
|
||||
"Number of ECC codewords %1$d less than %2$d (5%% of data codewords %3$d)",
|
||||
ecc_blocks, data_blocks / 20, data_blocks);
|
||||
}
|
||||
|
||||
if (debug_print) {
|
||||
printf("Generating a %s symbol with %d layers\n", compact ? "compact" : "full-size", layers);
|
||||
@ -1131,8 +1142,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
break;
|
||||
case 10:
|
||||
if (!rs_uint_init_gf(&rs_uint, 0x409, 1023)) { /* Can fail on malloc() */
|
||||
strcpy(symbol->errtxt, "500: Insufficient memory for Reed-Solomon log tables");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 500, "Insufficient memory for Reed-Solomon log tables");
|
||||
}
|
||||
rs_uint_init_code(&rs_uint, ecc_blocks, 1);
|
||||
rs_uint_encode(&rs_uint, data_blocks, data_part, ecc_part);
|
||||
@ -1141,8 +1151,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
case 12:
|
||||
if (!rs_uint_init_gf(&rs_uint, 0x1069, 4095)) { /* Can fail on malloc() */
|
||||
/* Note using AUSPOST error nos range as out of 50x ones & 51x taken by CODEONE */
|
||||
strcpy(symbol->errtxt, "700: Insufficient memory for Reed-Solomon log tables");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 700, "Insufficient memory for Reed-Solomon log tables");
|
||||
}
|
||||
rs_uint_init_code(&rs_uint, ecc_blocks, 1);
|
||||
rs_uint_encode(&rs_uint, data_blocks, data_part, ecc_part);
|
||||
@ -1173,7 +1182,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
descriptor[1] = ((layers - 1) & 0x01) ? '1' : '0';
|
||||
|
||||
/* The next 6 bits represent the number of data blocks minus 1 */
|
||||
descriptor[2] = reader || ((data_blocks - 1) & 0x20) ? '1' : '0';
|
||||
descriptor[2] = reader_init || ((data_blocks - 1) & 0x20) ? '1' : '0';
|
||||
for (i = 3; i < 8; i++) {
|
||||
descriptor[i] = ((data_blocks - 1) & (0x10 >> (i - 3))) ? '1' : '0';
|
||||
}
|
||||
@ -1185,7 +1194,7 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
}
|
||||
|
||||
/* The next 11 bits represent the number of data blocks minus 1 */
|
||||
descriptor[5] = reader || ((data_blocks - 1) & 0x400) ? '1' : '0';
|
||||
descriptor[5] = reader_init || ((data_blocks - 1) & 0x400) ? '1' : '0';
|
||||
for (i = 6; i < 16; i++) {
|
||||
descriptor[i] = ((data_blocks - 1) & (0x200 >> (i - 6))) ? '1' : '0';
|
||||
}
|
||||
@ -1230,15 +1239,13 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
|
||||
/* Plot all of the data into the symbol in pre-defined spiral pattern */
|
||||
if (compact) {
|
||||
int offset = AztecCompactOffset[layers - 1];
|
||||
int end_offset = 27 - offset;
|
||||
const int offset = AztecCompactOffset[layers - 1];
|
||||
const int end_offset = 27 - offset;
|
||||
for (y = offset; y < end_offset; y++) {
|
||||
int y_map = y * 27;
|
||||
const int y_map = y * 27;
|
||||
for (x = offset; x < end_offset; x++) {
|
||||
int map = AztecCompactMap[y_map + x];
|
||||
if (map == 1) {
|
||||
set_module(symbol, y - offset, x - offset);
|
||||
} else if (map >= 2 && bit_pattern[map - 2] == '1') {
|
||||
const int map = AztecCompactMap[y_map + x];
|
||||
if (map == 1 || (map >= 2 && bit_pattern[map - 2] == '1')) {
|
||||
set_module(symbol, y - offset, x - offset);
|
||||
}
|
||||
}
|
||||
@ -1248,16 +1255,14 @@ INTERNAL int aztec(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
symbol->rows = 27 - (2 * offset);
|
||||
symbol->width = 27 - (2 * offset);
|
||||
} else {
|
||||
int offset = AztecOffset[layers - 1];
|
||||
int end_offset = 151 - offset;
|
||||
const int offset = AztecOffset[layers - 1];
|
||||
const int end_offset = 151 - offset;
|
||||
az_populate_map(AztecMap, layers);
|
||||
for (y = offset; y < end_offset; y++) {
|
||||
int y_map = y * 151;
|
||||
const int y_map = y * 151;
|
||||
for (x = offset; x < end_offset; x++) {
|
||||
int map = AztecMap[y_map + x];
|
||||
if (map == 1) {
|
||||
set_module(symbol, y - offset, x - offset);
|
||||
} else if (map >= 2 && bit_pattern[map - 2] == '1') {
|
||||
const int map = AztecMap[y_map + x];
|
||||
if (map == 1 || (map >= 2 && bit_pattern[map - 2] == '1')) {
|
||||
set_module(symbol, y - offset, x - offset);
|
||||
}
|
||||
}
|
||||
@ -1283,12 +1288,11 @@ INTERNAL int azrune(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
|
||||
input_value = 0;
|
||||
if (length > 3) {
|
||||
strcpy(symbol->errtxt, "507: Input too large (3 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 507, "Input length %d too long (maximum 3)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "508: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 508,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
switch (length) {
|
||||
case 3:
|
||||
@ -1303,8 +1307,7 @@ INTERNAL int azrune(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
}
|
||||
|
||||
if (input_value > 255) {
|
||||
strcpy(symbol->errtxt, "509: Input out of range (0 to 255)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 509, "Input value out of range (0 to 255)");
|
||||
}
|
||||
|
||||
bp = bin_append_posn(input_value, 8, binary_string, bp);
|
||||
|
117
backend/aztec.h
@ -1,7 +1,7 @@
|
||||
/* aztec.h - Handles Aztec 2D Symbols */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -33,8 +33,8 @@
|
||||
#ifndef Z_AZTEC_H
|
||||
#define Z_AZTEC_H
|
||||
|
||||
static const short AztecCompactMap[] = {
|
||||
/* 27 x 27 data grid */
|
||||
/* 27 x 27 data grid */
|
||||
static const short AztecCompactMap[729] = {
|
||||
609, 608, 411, 413, 415, 417, 419, 421, 423, 425, 427, 429, 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, 457, 459, /* 0 */
|
||||
607, 606, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454, 456, 458, /* 1 */
|
||||
605, 604, 409, 408, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 460, 461, /* 2 */
|
||||
@ -84,83 +84,84 @@ static const short AztecMapCore[15][15] = {
|
||||
{ 0, 0, 20029, 20028, 20027, 20026, 20025, 0, 20024, 20023, 20022, 20021, 20020, 0, 0, },
|
||||
};
|
||||
|
||||
/* From Table 2 */
|
||||
static const char AztecSymbolChar[128] = {
|
||||
/* From Table 2 */
|
||||
0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 1, 6, 7, 8, 9, 10, 11, 12,
|
||||
13, 14, 15, 16, 0, 18, 0, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 21, 22,
|
||||
23, 24, 25, 26, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 27, 21, 28, 22, 23, 24, 2, 3, 4,
|
||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 26, 27, 29, 25, 30, 26, 27
|
||||
0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19,
|
||||
1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 18, 0, 20,
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 21, 22, 23, 24, 25, 26,
|
||||
20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 27, 21, 28, 22, 23,
|
||||
24, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 25, 30, 26, 27
|
||||
};
|
||||
|
||||
static const char AztecModes[129] = "BMMMMMMMMMMMMXBBBBBBBBBBBBBMMMMMXPPPPPPPPPPPXPXPDDDDDDDDDDPPPPPPMUUUUUUUUUUUUUUUUUUUUUUUUUUPMPMMMLLLLLLLLLLLLLLLLLLLLLLLLLLPMPMM";
|
||||
static const char AztecModes[128] = {
|
||||
'B', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'X', 'B', 'B',
|
||||
'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'M', 'M', 'M', 'M', 'M',
|
||||
'X', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'X', 'P', 'X', 'P',
|
||||
'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'P', 'P', 'P', 'P', 'P', 'P',
|
||||
'M', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U',
|
||||
'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'P', 'M', 'P', 'M', 'M',
|
||||
'M', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'P', 'M', 'P', 'M', 'M'
|
||||
};
|
||||
|
||||
/* Codewords per symbol */
|
||||
static const short AztecSizes[32] = {
|
||||
/* Codewords per symbol */
|
||||
21, 48, 60, 88, 120, 156, 196, 240, 230, 272, 316, 364, 416, 470, 528, 588, 652, 720, 790,
|
||||
864, 940, 1020, 920, 992, 1066, 1144, 1224, 1306, 1392, 1480, 1570, 1664
|
||||
21, 48, 60, 88, 120, 156, 196, 240, 230, 272, 316, 364, 416, 470, 528, 588,
|
||||
652, 720, 790, 864, 940, 1020, 920, 992, 1066, 1144, 1224, 1306, 1392, 1480, 1570, 1664
|
||||
};
|
||||
|
||||
static const short AztecCompactSizes[4] = {
|
||||
17, 40, 51, 64 /* 64 data blocks (Mode Message max) but 76 altogether */
|
||||
};
|
||||
|
||||
static const short Aztec10DataSizes[32] = {
|
||||
/* Data bits per symbol maximum with 10% error correction */
|
||||
96, 246, 408, 616, 840, 1104, 1392, 1704, 2040, 2420, 2820, 3250, 3720, 4200, 4730,
|
||||
5270, 5840, 6450, 7080, 7750, 8430, 9150, 9900, 10680, 11484, 12324, 13188, 14076,
|
||||
15000, 15948, 16920, 17940
|
||||
static const short AztecDataSizes[4][32] = { {
|
||||
/* Data bits per symbol maximum with 10% error correction */
|
||||
96, 246, 408, 616, 840, 1104, 1392, 1704, 2040, 2420, 2820, 3250, 3720, 4200, 4730, 5270,
|
||||
5840, 6450, 7080, 7750, 8430, 9150, 9900, 10680, 11484, 12324, 13188, 14076, 15000, 15948, 16920, 17940
|
||||
}, {
|
||||
/* Data bits per symbol maximum with 23% error correction */
|
||||
84, 204, 352, 520, 720, 944, 1184, 1456, 1750, 2070, 2410, 2780, 3180, 3590, 4040, 4500,
|
||||
5000, 5520, 6060, 6630, 7210, 7830, 8472, 9132, 9816, 10536, 11280, 12036, 12828, 13644, 14472, 15348
|
||||
}, {
|
||||
/* Data bits per symbol maximum with 36% error correction */
|
||||
66, 168, 288, 432, 592, 776, 984, 1208, 1450, 1720, 2000, 2300, 2640, 2980, 3350, 3740,
|
||||
4150, 4580, 5030, 5500, 5990, 6500, 7032, 7584, 8160, 8760, 9372, 9996, 10656, 11340, 12024, 12744
|
||||
}, {
|
||||
/* Data bits per symbol maximum with 50% error correction */
|
||||
48, 126, 216, 328, 456, 600, 760, 936, 1120, 1330, 1550, 1790, 2050, 2320, 2610, 2910,
|
||||
3230, 3570, 3920, 4290, 4670, 5070, 5484, 5916, 6360, 6828, 7308, 7800, 8316, 8844, 9384, 9948
|
||||
}
|
||||
};
|
||||
|
||||
static const short Aztec23DataSizes[32] = {
|
||||
/* Data bits per symbol maximum with 23% error correction */
|
||||
84, 204, 352, 520, 720, 944, 1184, 1456, 1750, 2070, 2410, 2780, 3180, 3590, 4040,
|
||||
4500, 5000, 5520, 6060, 6630, 7210, 7830, 8472, 9132, 9816, 10536, 11280, 12036,
|
||||
12828, 13644, 14472, 15348
|
||||
};
|
||||
|
||||
static const short Aztec36DataSizes[32] = {
|
||||
/* Data bits per symbol maximum with 36% error correction */
|
||||
66, 168, 288, 432, 592, 776, 984, 1208, 1450, 1720, 2000, 2300, 2640, 2980, 3350,
|
||||
3740, 4150, 4580, 5030, 5500, 5990, 6500, 7032, 7584, 8160, 8760, 9372, 9996, 10656,
|
||||
11340, 12024, 12744
|
||||
};
|
||||
|
||||
static const short Aztec50DataSizes[32] = {
|
||||
/* Data bits per symbol maximum with 50% error correction */
|
||||
48, 126, 216, 328, 456, 600, 760, 936, 1120, 1330, 1550, 1790, 2050, 2320, 2610,
|
||||
2910, 3230, 3570, 3920, 4290, 4670, 5070, 5484, 5916, 6360, 6828, 7308, 7800, 8316,
|
||||
8844, 9384, 9948
|
||||
};
|
||||
|
||||
static const short AztecCompact10DataSizes[4] = {
|
||||
78, 198, 336, 512 /* Max 64 * 8 */
|
||||
};
|
||||
|
||||
static const short AztecCompact23DataSizes[4] = {
|
||||
66, 168, 288, 440
|
||||
};
|
||||
|
||||
static const short AztecCompact36DataSizes[4] = {
|
||||
48, 138, 232, 360
|
||||
};
|
||||
|
||||
static const short AztecCompact50DataSizes[4] = {
|
||||
36, 102, 176, 280
|
||||
static const short AztecCompactDataSizes[4][4] = { {
|
||||
/* Data bits per symbol maximum with 10% error correction */
|
||||
78, 198, 336, 512 /* Max 64 * 8 */
|
||||
}, {
|
||||
/* Data bits per symbol maximum with 23% error correction */
|
||||
66, 168, 288, 440
|
||||
}, {
|
||||
/* Data bits per symbol maximum with 36% error correction */
|
||||
48, 138, 232, 360
|
||||
}, {
|
||||
/* Data bits per symbol maximum with 50% error correction */
|
||||
36, 102, 176, 280
|
||||
}
|
||||
};
|
||||
|
||||
/* Reference grid offsets */
|
||||
static const char AztecOffset[32] = {
|
||||
66, 64, 62, 60, 57, 55, 53, 51, 49, 47, 45, 42, 40, 38, 36, 34, 32, 30, 28, 25, 23, 21,
|
||||
19, 17, 15, 13, 10, 8, 6, 4, 2, 0
|
||||
66, 64, 62, 60, 57, 55, 53, 51, 49, 47, 45, 42, 40, 38, 36, 34,
|
||||
32, 30, 28, 25, 23, 21, 19, 17, 15, 13, 10, 8, 6, 4, 2, 0
|
||||
};
|
||||
|
||||
static const char AztecCompactOffset[4] = {
|
||||
6, 4, 2, 0
|
||||
};
|
||||
|
||||
static const short AztecMapGridYOffsets[] = {
|
||||
static const unsigned char AztecMapGridYOffsets[8] = {
|
||||
27, 43, 59, 75, 91, 107, 123, 139
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* bc412.c - Handles IBM BC412 (SEMI T1-95) symbology */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2022-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -73,9 +73,11 @@ INTERNAL int bc412(struct zint_symbol *symbol, unsigned char source[], int lengt
|
||||
char *d = dest;
|
||||
int error_number = 0;
|
||||
|
||||
if ((length < 7) || (length > 18)) {
|
||||
strcpy(symbol->errtxt, "790: Input wrong length (should be between 7 and 18 characters)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
if (length > 18) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 790, "Input length %d too long (maximum 18)", length);
|
||||
}
|
||||
if (length < 7) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 792, "Input length %d too short (minimum 7)", length);
|
||||
}
|
||||
to_upper(source, length);
|
||||
|
||||
@ -87,9 +89,9 @@ INTERNAL int bc412(struct zint_symbol *symbol, unsigned char source[], int lengt
|
||||
}
|
||||
padded_source[length + 1] = 0;
|
||||
|
||||
if (!is_sane_lookup(BROMINE, 35, padded_source, length + 1, posns)) {
|
||||
strcpy(symbol->errtxt, "791: Invalid character in data (alphanumerics only, excluding the letter \"O\")");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane_lookup(BROMINE, 35, padded_source, length + 1, posns))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 791,
|
||||
"Invalid character at position %d in input (alphanumerics only, excluding \"O\")", i - 1);
|
||||
}
|
||||
|
||||
for (i = 0; i <= length; i++) {
|
||||
@ -134,11 +136,14 @@ INTERNAL int bc412(struct zint_symbol *symbol, unsigned char source[], int lengt
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* SEMI T1-95 Table 1 "Module" (Character) Height 2mm ± 0.025mm, using Module Spacing 0.12mm ± 0.025mm as
|
||||
X-dimension */
|
||||
error_number = set_height(symbol, stripf(1.975f / 0.145f), stripf(2.0f / 0.12f), stripf(2.025f / 0.095f),
|
||||
0 /*no_errtxt*/);
|
||||
const float min_height = 13.6206894f; /* 1.975 / 0.145 */
|
||||
const float default_height = 16.666666f; /* 2.0 / 0.12 */
|
||||
const float max_height = 21.3157902f; /* 2.025 / 0.095 */
|
||||
error_number = set_height(symbol, min_height, default_height, max_height, 0 /*no_errtxt*/);
|
||||
} else {
|
||||
/* Using compliant height as default as no backwards compatibility to consider */
|
||||
(void) set_height(symbol, 0.0f, stripf(2.0f / 0.12f), 0.0f, 1 /*no_errtxt*/);
|
||||
const float default_height = 16.666666f; /* 2.0 / 0.12 */
|
||||
(void) set_height(symbol, 0.0f, default_height, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
|
||||
return error_number;
|
||||
|
174
backend/bmp.c
@ -1,7 +1,7 @@
|
||||
/* bmp.c - Handles output to Windows Bitmap file */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -33,24 +33,19 @@
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "filemem.h"
|
||||
#include "output.h"
|
||||
#include "bmp.h" /* Bitmap header structure */
|
||||
|
||||
INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf) {
|
||||
int i, row, column;
|
||||
int row_size;
|
||||
int bits_per_pixel;
|
||||
int colour_count;
|
||||
int resolution;
|
||||
unsigned int data_offset, data_size, file_size;
|
||||
unsigned char *bitmap_file_start, *bmp_posn;
|
||||
unsigned char *bitmap;
|
||||
FILE *bmp_file;
|
||||
size_t row_size, data_offset, file_size;
|
||||
struct filemem fm;
|
||||
struct filemem *const fmp = &fm;
|
||||
bitmap_file_header_t file_header;
|
||||
bitmap_info_header_t info_header;
|
||||
color_ref_t bg;
|
||||
@ -58,7 +53,7 @@ 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*/);
|
||||
fg.reserved = 0x00;
|
||||
@ -86,122 +81,93 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
|
||||
map['0'] = 0;
|
||||
map['1'] = 0x80;
|
||||
}
|
||||
row_size = 4 * ((bits_per_pixel * symbol->bitmap_width + 31) / 32);
|
||||
data_size = symbol->bitmap_height * row_size;
|
||||
row_size = 4 * (((size_t) symbol->bitmap_width * bits_per_pixel + 31) / 32);
|
||||
data_offset = sizeof(bitmap_file_header_t) + sizeof(bitmap_info_header_t);
|
||||
data_offset += colour_count * sizeof(color_ref_t);
|
||||
file_size = data_offset + data_size;
|
||||
data_offset += sizeof(color_ref_t) * colour_count;
|
||||
file_size = data_offset + row_size * symbol->bitmap_height;
|
||||
|
||||
bitmap_file_start = (unsigned char *) malloc(file_size);
|
||||
if (bitmap_file_start == NULL) {
|
||||
strcpy(symbol->errtxt, "602: Insufficient memory for BMP file buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
/* Must fit in `uint32_t` field in header */
|
||||
if (file_size != (uint32_t) file_size) {
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 606, "Output size too large for file size field of BMP header");
|
||||
}
|
||||
memset(bitmap_file_start, 0, file_size); /* Not required but keeps padding bytes consistent */
|
||||
|
||||
bitmap = bitmap_file_start + data_offset;
|
||||
if (!(rowbuf = (unsigned char *) malloc(row_size))) {
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 602, "Insufficient memory for BMP row buffer");
|
||||
}
|
||||
|
||||
out_le_u16(file_header.header_field, 0x4d42); /* "BM" */
|
||||
out_le_u32(file_header.file_size, file_size);
|
||||
out_le_u32(file_header.reserved, 0);
|
||||
out_le_u32(file_header.data_offset, data_offset);
|
||||
|
||||
out_le_u32(info_header.header_size, sizeof(bitmap_info_header_t));
|
||||
out_le_i32(info_header.width, symbol->bitmap_width);
|
||||
out_le_i32(info_header.height, symbol->bitmap_height);
|
||||
out_le_u16(info_header.colour_planes, 1);
|
||||
out_le_u16(info_header.bits_per_pixel, bits_per_pixel);
|
||||
out_le_u32(info_header.compression_method, 0); /* BI_RGB */
|
||||
out_le_u32(info_header.image_size, 0);
|
||||
resolution = symbol->dpmm ? (int) roundf(stripf(symbol->dpmm * 1000.0f)) : 0; /* pixels per metre */
|
||||
out_le_i32(info_header.horiz_res, resolution);
|
||||
out_le_i32(info_header.vert_res, resolution);
|
||||
out_le_u32(info_header.colours, colour_count);
|
||||
out_le_u32(info_header.important_colours, colour_count);
|
||||
|
||||
/* Open output file in binary mode */
|
||||
if (!fm_open(fmp, symbol, "wb")) {
|
||||
errtxtf(0, symbol, 601, "Could not open BMP output file (%1$d: %2$s)", fmp->err, strerror(fmp->err));
|
||||
free(rowbuf);
|
||||
return ZINT_ERROR_FILE_ACCESS;
|
||||
}
|
||||
|
||||
fm_write(&file_header, sizeof(bitmap_file_header_t), 1, fmp);
|
||||
fm_write(&info_header, sizeof(bitmap_info_header_t), 1, fmp);
|
||||
|
||||
fm_write(&bg, sizeof(color_ref_t), 1, fmp);
|
||||
if (bits_per_pixel == 4) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
fm_write(&palette[i], sizeof(color_ref_t), 1, fmp);
|
||||
}
|
||||
if (ultra_fg_index == 9) {
|
||||
fm_write(&fg, sizeof(color_ref_t), 1, fmp);
|
||||
}
|
||||
} else {
|
||||
fm_write(&fg, sizeof(color_ref_t), 1, fmp);
|
||||
}
|
||||
|
||||
/* Pixel Plotting */
|
||||
if (bits_per_pixel == 4) {
|
||||
for (row = 0; row < symbol->bitmap_height; row++) {
|
||||
const unsigned char *pb = pixelbuf + (symbol->bitmap_width * (symbol->bitmap_height - row - 1));
|
||||
const unsigned char *pb = pixelbuf + ((size_t) symbol->bitmap_width * (symbol->bitmap_height - row - 1));
|
||||
memset(rowbuf, 0, row_size);
|
||||
for (column = 0; column < symbol->bitmap_width; column++) {
|
||||
bitmap[(column >> 1) + (row * row_size)] |= map[pb[column]] << (!(column & 1) << 2);
|
||||
rowbuf[column >> 1] |= map[pb[column]] << (!(column & 1) << 2);
|
||||
}
|
||||
fm_write(rowbuf, 1, row_size, fmp);
|
||||
}
|
||||
} else { /* bits_per_pixel == 1 */
|
||||
for (row = 0; row < symbol->bitmap_height; row++) {
|
||||
const unsigned char *pb = pixelbuf + (symbol->bitmap_width * (symbol->bitmap_height - row - 1));
|
||||
const unsigned char *pb = pixelbuf + ((size_t) symbol->bitmap_width * (symbol->bitmap_height - row - 1));
|
||||
memset(rowbuf, 0, row_size);
|
||||
for (column = 0; column < symbol->bitmap_width; column++) {
|
||||
bitmap[(column >> 3) + (row * row_size)] |= map[pb[column]] >> (column & 7);
|
||||
rowbuf[column >> 3] |= map[pb[column]] >> (column & 7);
|
||||
}
|
||||
fm_write(rowbuf, 1, row_size, fmp);
|
||||
}
|
||||
}
|
||||
free(rowbuf);
|
||||
|
||||
file_header.header_field = 0x4d42; /* "BM" */
|
||||
file_header.file_size = file_size;
|
||||
file_header.reserved = 0;
|
||||
file_header.data_offset = data_offset;
|
||||
|
||||
info_header.header_size = sizeof(bitmap_info_header_t);
|
||||
info_header.width = symbol->bitmap_width;
|
||||
info_header.height = symbol->bitmap_height;
|
||||
info_header.colour_planes = 1;
|
||||
info_header.bits_per_pixel = bits_per_pixel;
|
||||
info_header.compression_method = 0; /* BI_RGB */
|
||||
info_header.image_size = 0;
|
||||
resolution = symbol->dpmm ? (int) roundf(stripf(symbol->dpmm * 1000.0f)) : 0; /* pixels per metre */
|
||||
info_header.horiz_res = resolution;
|
||||
info_header.vert_res = resolution;
|
||||
info_header.colours = colour_count;
|
||||
info_header.important_colours = colour_count;
|
||||
|
||||
bmp_posn = bitmap_file_start;
|
||||
memcpy(bitmap_file_start, &file_header, sizeof(bitmap_file_header_t));
|
||||
bmp_posn += sizeof(bitmap_file_header_t);
|
||||
memcpy(bmp_posn, &info_header, sizeof(bitmap_info_header_t));
|
||||
bmp_posn += sizeof(bitmap_info_header_t);
|
||||
|
||||
memcpy(bmp_posn, &bg, sizeof(color_ref_t));
|
||||
bmp_posn += sizeof(color_ref_t);
|
||||
if (bits_per_pixel == 4) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
memcpy(bmp_posn, &palette[i], sizeof(color_ref_t));
|
||||
bmp_posn += sizeof(color_ref_t);
|
||||
}
|
||||
if (ultra_fg_index == 9) {
|
||||
memcpy(bmp_posn, &fg, sizeof(color_ref_t));
|
||||
/* bmp_posn += sizeof(color_ref_t); */ /* Not needed as long as last */
|
||||
}
|
||||
} else {
|
||||
memcpy(bmp_posn, &fg, sizeof(color_ref_t));
|
||||
/* bmp_posn += sizeof(color_ref_t); */ /* Not needed as long as last */
|
||||
}
|
||||
|
||||
/* 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(bitmap_file_start);
|
||||
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(bitmap_file_start);
|
||||
return ZINT_ERROR_FILE_ACCESS;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(bitmap_file_start, file_header.file_size, 1, bmp_file);
|
||||
|
||||
if (ferror(bmp_file)) {
|
||||
sprintf(symbol->errtxt, "603: Incomplete write to output (%d: %.30s)", errno, strerror(errno));
|
||||
free(bitmap_file_start);
|
||||
if (!output_to_stdout) {
|
||||
(void) fclose(bmp_file);
|
||||
}
|
||||
if (fm_error(fmp)) {
|
||||
errtxtf(0, symbol, 603, "Incomplete write of BMP output (%1$d: %2$s)", 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));
|
||||
free(bitmap_file_start);
|
||||
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));
|
||||
free(bitmap_file_start);
|
||||
return ZINT_ERROR_FILE_WRITE;
|
||||
}
|
||||
if (!fm_close(fmp, symbol)) {
|
||||
return errtxtf(ZINT_ERROR_FILE_WRITE, symbol, 605, "Failure on closing BMP output file (%1$d: %2$s)",
|
||||
fmp->err, strerror(fmp->err));
|
||||
}
|
||||
|
||||
free(bitmap_file_start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* bmp.h - header structure for Windows bitmap files */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -35,16 +35,18 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#pragma pack (1)
|
||||
#ifdef OUT_USE_PRAGMA_PACK
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
typedef struct bitmap_file_header {
|
||||
uint16_t header_field;
|
||||
uint32_t file_size;
|
||||
uint32_t reserved;
|
||||
uint32_t data_offset;
|
||||
} bitmap_file_header_t;
|
||||
} OUT_PACK bitmap_file_header_t;
|
||||
|
||||
typedef struct bitmap_info_header {
|
||||
uint32_t header_size;
|
||||
@ -58,20 +60,22 @@ extern "C" {
|
||||
int32_t vert_res;
|
||||
uint32_t colours;
|
||||
uint32_t important_colours;
|
||||
} bitmap_info_header_t;
|
||||
} OUT_PACK bitmap_info_header_t;
|
||||
|
||||
typedef struct color_ref {
|
||||
uint8_t blue;
|
||||
uint8_t green;
|
||||
uint8_t red;
|
||||
uint8_t reserved;
|
||||
} color_ref_t;
|
||||
} OUT_PACK color_ref_t;
|
||||
|
||||
#pragma pack ()
|
||||
#ifdef OUT_USE_PRAGMA_PACK
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
#endif /* Z_BMP_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* codablock.c - Handles Codablock-F */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2016-2023 Harald Oehlmann
|
||||
Copyright (C) 2016-2024 Harald Oehlmann
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -577,14 +577,13 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int
|
||||
return error_number;
|
||||
}
|
||||
if (rows > 44) {
|
||||
strcpy(symbol->errtxt, "410: Rows parameter not in 0..44");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 410, "Number of rows '%d' out of range (0 to 44)", rows);
|
||||
}
|
||||
/* option_2: (usable data) columns: <= 0: automatic, 9..67 (min 9 == 4 data, max 67 == 62 data) */
|
||||
columns = symbol->option_2;
|
||||
if (!(columns <= 0 || (columns >= 9 && columns <= 67))) {
|
||||
strcpy(symbol->errtxt, "411: Columns parameter not in 0, 9..67");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 411, "Number of columns '%d' out of range (9 to 67)",
|
||||
columns);
|
||||
}
|
||||
if (columns < 0) { /* Protect against negative overflow (ticket #300 (#9) Andre Maute) */
|
||||
columns = 0;
|
||||
@ -637,8 +636,8 @@ INTERNAL int codablockf(struct zint_symbol *symbol, unsigned char source[], int
|
||||
error_number = Columns2Rows(symbol, T, dataLength, &rows, &useColumns, pSet, &fillings);
|
||||
}
|
||||
if (error_number != 0) {
|
||||
strcpy(symbol->errtxt, "413: Data string too long");
|
||||
return error_number;
|
||||
return errtxt(error_number, symbol, 413,
|
||||
"Input too long, requires too many symbol characters (maximum 2726)");
|
||||
}
|
||||
/* Suppresses clang-analyzer-core.VLASize warning */
|
||||
assert(rows >= 2 && useColumns >= 4);
|
||||
|
195
backend/code.c
@ -1,7 +1,7 @@
|
||||
/* code.c - Handles Code 11, 39, 39+, 93, PZN, Channel and VIN */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,18 +43,15 @@ static const char SILVER[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd";
|
||||
|
||||
#define ARSENIC_F (IS_NUM_F | IS_ARS_F) /* ARSENIC "0123456789ABCDEFGHJKLMNPRSTUVWXYZ" */
|
||||
|
||||
static const char C11Table[11][6] = {
|
||||
static const char C11Table[11 + 1][6] = {
|
||||
{'1','1','1','1','2','1'}, {'2','1','1','1','2','1'}, {'1','2','1','1','2','1'}, {'2','2','1','1','1','1'},
|
||||
{'1','1','2','1','2','1'}, {'2','1','2','1','1','1'}, {'1','2','2','1','1','1'}, {'1','1','1','2','2','1'},
|
||||
{'2','1','1','2','1','1'}, {'2','1','1','1','1','1'}, {'1','1','2','1','1','1'}
|
||||
{'2','1','1','2','1','1'}, {'2','1','1','1','1','1'}, {'1','1','2','1','1','1'},
|
||||
{'1','1','2','2','1','1'} /* Start character (full 6), Stop character (first 5) */
|
||||
};
|
||||
|
||||
/* Code 39 tables checked against ISO/IEC 16388:2007 */
|
||||
|
||||
/* Incorporates Table A1 */
|
||||
|
||||
static const char C39Table[43][10] = {
|
||||
/* Code 39 character assignments (Table 1) */
|
||||
/* Code 39 character assignments (ISO/IEC 16388:2007 Table 1 and Table A.1) */
|
||||
static const char C39Table[43 + 1][10] = {
|
||||
{'1','1','1','2','2','1','2','1','1','1'}, {'2','1','1','2','1','1','1','1','2','1'},
|
||||
{'1','1','2','2','1','1','1','1','2','1'}, {'2','1','2','2','1','1','1','1','1','1'},
|
||||
{'1','1','1','2','2','1','1','1','2','1'}, {'2','1','1','2','2','1','1','1','1','1'},
|
||||
@ -76,11 +73,12 @@ static const char C39Table[43][10] = {
|
||||
{'1','2','1','1','1','1','2','1','2','1'}, {'2','2','1','1','1','1','2','1','1','1'},
|
||||
{'1','2','2','1','1','1','2','1','1','1'}, {'1','2','1','2','1','2','1','1','1','1'},
|
||||
{'1','2','1','2','1','1','1','2','1','1'}, {'1','2','1','1','1','2','1','2','1','1'},
|
||||
{'1','1','1','2','1','2','1','2','1','1'}
|
||||
{'1','1','1','2','1','2','1','2','1','1'},
|
||||
{'1','2','1','1','2','1','2','1','1','1'} /* Start character (full 10), Stop character (first 9) */
|
||||
};
|
||||
|
||||
/* Encoding the full ASCII character set in Code 39 (ISO/IEC 16388:2007 Table A.2) */
|
||||
static const char EC39Ctrl[128][2] = {
|
||||
/* Encoding the full ASCII character set in Code 39 (Table A2) */
|
||||
{'%','U'}, {'$','A'}, {'$','B'}, {'$','C'}, {'$','D'}, {'$','E'}, {'$','F'}, {'$','G'}, {'$','H'}, {'$','I'},
|
||||
{'$','J'}, {'$','K'}, {'$','L'}, {'$','M'}, {'$','N'}, {'$','O'}, {'$','P'}, {'$','Q'}, {'$','R'}, {'$','S'},
|
||||
{'$','T'}, {'$','U'}, {'$','V'}, {'$','W'}, {'$','X'}, {'$','Y'}, {'$','Z'}, {'%','A'}, {'%','B'}, {'%','C'},
|
||||
@ -96,6 +94,7 @@ static const char EC39Ctrl[128][2] = {
|
||||
{'+','X'}, {'+','Y'}, {'+','Z'}, {'%','P'}, {'%','Q'}, {'%','R'}, {'%','S'}, {'%','T'}
|
||||
};
|
||||
|
||||
/* Code 93 ANSI/AIM BC5-1995 Table 3 */
|
||||
static const char C93Ctrl[128][2] = {
|
||||
{'b','U'}, {'a','A'}, {'a','B'}, {'a','C'}, {'a','D'}, {'a','E'}, {'a','F'}, {'a','G'}, {'a','H'}, {'a','I'},
|
||||
{'a','J'}, {'a','K'}, {'a','L'}, {'a','M'}, {'a','N'}, {'a','O'}, {'a','P'}, {'a','Q'}, {'a','R'}, {'a','S'},
|
||||
@ -112,6 +111,7 @@ static const char C93Ctrl[128][2] = {
|
||||
{'d','X'}, {'d','Y'}, {'d','Z'}, {'b','P'}, {'b','Q'}, {'b','R'}, {'b','S'}, {'b','T'}
|
||||
};
|
||||
|
||||
/* Code 93 ANSI/AIM BC5-1995 Table 2 */
|
||||
static const char C93Table[47][6] = {
|
||||
{'1','3','1','1','1','2'}, {'1','1','1','2','1','3'}, {'1','1','1','3','1','2'}, {'1','1','1','4','1','1'},
|
||||
{'1','2','1','1','1','3'}, {'1','2','1','2','1','2'}, {'1','2','1','3','1','1'}, {'1','1','1','1','1','4'},
|
||||
@ -127,8 +127,8 @@ static const char C93Table[47][6] = {
|
||||
{'3','1','2','1','1','1'}, {'3','1','1','1','2','1'}, {'1','2','2','2','1','1'}
|
||||
};
|
||||
|
||||
/* *********************** CODE 11 ******************** */
|
||||
INTERNAL int code11(struct zint_symbol *symbol, unsigned char source[], int length) { /* Code 11 */
|
||||
/* Code 11 */
|
||||
INTERNAL int code11(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
|
||||
int i;
|
||||
int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count;
|
||||
@ -144,17 +144,16 @@ INTERNAL int code11(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
assert(length > 0);
|
||||
|
||||
if (length > 140) { /* 8 (Start) + 140 * 8 + 2 * 8 (Check) + 7 (Stop) = 1151 */
|
||||
strcpy(symbol->errtxt, "320: Input too long (140 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 320, "Input length %d too long (maximum 140)", length);
|
||||
}
|
||||
if (!is_sane(SODIUM_MNS_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "321: Invalid character in data (digits and \"-\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(SODIUM_MNS_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 321,
|
||||
"Invalid character at position %d in input (digits and \"-\" only)", i);
|
||||
}
|
||||
|
||||
if (symbol->option_2 < 0 || symbol->option_2 > 2) {
|
||||
strcpy(symbol->errtxt, "339: Invalid check digit version (1, 2 only)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 339, "Invalid check digit version '%d' (1 or 2 only)",
|
||||
symbol->option_2);
|
||||
}
|
||||
if (symbol->option_2 == 2) {
|
||||
num_check_digits = 0;
|
||||
@ -170,7 +169,7 @@ INTERNAL int code11(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
k_count = 0;
|
||||
|
||||
/* start character */
|
||||
memcpy(d, "112211", 6);
|
||||
memcpy(d, C11Table[11], 6);
|
||||
d += 6;
|
||||
|
||||
/* Draw main body of barcode */
|
||||
@ -223,7 +222,7 @@ INTERNAL int code11(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
}
|
||||
|
||||
/* Stop character */
|
||||
memcpy(d, "11221", 5);
|
||||
memcpy(d, C11Table[11], 5);
|
||||
d += 5;
|
||||
|
||||
expand(symbol, dest, d - dest);
|
||||
@ -255,26 +254,23 @@ INTERNAL int code39(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
|
||||
/* LOGMARS MIL-STD-1189 Rev. B https://apps.dtic.mil/dtic/tr/fulltext/u2/a473534.pdf */
|
||||
if ((symbol->symbology == BARCODE_LOGMARS) && (length > 30)) { /* MIL-STD-1189 Rev. B Section 5.2.6.2 */
|
||||
strcpy(symbol->errtxt, "322: Input too long (30 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 322, "Input length %d too long (maximum 30)", length);
|
||||
/* Prevent encoded_data out-of-bounds >= 143 for BARCODE_HIBC_39 due to wider 'wide' bars */
|
||||
} else if ((symbol->symbology == BARCODE_HIBC_39) && (length > 70)) { /* 16 (Start) + 70*16 + 15 (Stop) = 1151 */
|
||||
/* Note use 319 (2of5 range) as 340 taken by CODE128 */
|
||||
strcpy(symbol->errtxt, "319: Input too long (68 character maximum)"); /* 70 less '+' and check */
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
/* 70 less '+' and check */
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 319, "Input length %d too long (maximum 68)", length - 2);
|
||||
} else if (length > 86) { /* 13 (Start) + 86*13 + 12 (Stop) = 1143 */
|
||||
strcpy(symbol->errtxt, "323: Input too long (86 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 323, "Input length %d too long (maximum 86)", length);
|
||||
}
|
||||
|
||||
to_upper(source, length);
|
||||
if (!is_sane_lookup(SILVER, 43 /* Up to "%" */, source, length, posns)) {
|
||||
strcpy(symbol->errtxt, "324: Invalid character in data (alphanumerics, space and \"-.$/+%\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane_lookup(SILVER, 43 /* Up to "%" */, source, length, posns))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 324,
|
||||
"Invalid character at position %d in input (alphanumerics, space and \"-.$/+%%\" only)", i);
|
||||
}
|
||||
|
||||
/* Start character */
|
||||
memcpy(d, "1211212111", 10);
|
||||
memcpy(d, C39Table[43], 10);
|
||||
d += 10;
|
||||
|
||||
for (i = 0; i < length; i++, d += 10) {
|
||||
@ -303,7 +299,7 @@ INTERNAL int code39(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
}
|
||||
|
||||
/* Stop character */
|
||||
memcpy(d, "121121211", 9);
|
||||
memcpy(d, C39Table[43], 9);
|
||||
d += 9;
|
||||
|
||||
if ((symbol->symbology == BARCODE_LOGMARS) || (symbol->symbology == BARCODE_HIBC_39)) {
|
||||
@ -327,8 +323,9 @@ INTERNAL int code39(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
/* MIL-STD-1189 Rev. B Section 5.2
|
||||
Min height 0.25" / 0.04" (X max) = 6.25
|
||||
Default height 0.625" (average of 0.375" - 0.875") / 0.01375" (average of 0.0075" - 0.02") ~ 45.45 */
|
||||
error_number = set_height(symbol, 6.25f, stripf(0.625f / 0.01375f), stripf(0.875f / 0.0075f),
|
||||
0 /*no_errtxt*/);
|
||||
const float default_height = 45.4545441f; /* 0.625 / 0.01375 */
|
||||
const float max_height = 116.666664f; /* 0.875 / 0.0075 */
|
||||
error_number = set_height(symbol, 6.25f, default_height, max_height, 0 /*no_errtxt*/);
|
||||
} else if (symbol->symbology == BARCODE_CODE39 || symbol->symbology == BARCODE_EXCODE39
|
||||
|| symbol->symbology == BARCODE_HIBC_39) {
|
||||
/* ISO/IEC 16388:2007 4.4 (e) recommended min height 5.0mm or 15% of width excluding quiet zones;
|
||||
@ -369,16 +366,16 @@ INTERNAL int pzn(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
const int pzn7 = symbol->option_2 == 1;
|
||||
|
||||
if (length > 8 - pzn7) {
|
||||
sprintf(symbol->errtxt, "325: Input wrong length (%d character maximum)", 8 - pzn7);
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 325, "Input length %1$d too long (maximum %2$d)", length,
|
||||
8 - pzn7);
|
||||
}
|
||||
if (length == 8 - pzn7) {
|
||||
have_check_digit = source[7 - pzn7];
|
||||
length--;
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "326: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 326,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
localstr[0] = '-';
|
||||
@ -399,12 +396,11 @@ INTERNAL int pzn(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
}
|
||||
|
||||
if (check_digit == 10) {
|
||||
strcpy(symbol->errtxt, "327: Invalid PZN, check digit is '10'");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 327, "Invalid PZN, check digit is '10'");
|
||||
}
|
||||
if (have_check_digit && ctoi(have_check_digit) != check_digit) {
|
||||
sprintf(symbol->errtxt, "890: Invalid check digit '%c', expecting '%c'", have_check_digit, itoc(check_digit));
|
||||
return ZINT_ERROR_INVALID_CHECK;
|
||||
return errtxtf(ZINT_ERROR_INVALID_CHECK, symbol, 890, "Invalid check digit '%1$c', expecting '%2$c'",
|
||||
have_check_digit, itoc(check_digit));
|
||||
}
|
||||
|
||||
localstr[8 - pzn7] = itoc(check_digit);
|
||||
@ -429,7 +425,9 @@ INTERNAL int pzn(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
"normal" X 0.25mm (0.187mm - 0.45mm), height 8mm - 20mm for 0.25mm X, 10mm mentioned so use that
|
||||
as default, 10mm / 0.25mm = 40 */
|
||||
if (error_number < ZINT_ERROR) {
|
||||
error_number = set_height(symbol, stripf(8.0f / 0.45f), 40.0f, stripf(20.0f / 0.187f), 0 /*no_errtxt*/);
|
||||
const float min_height = 17.7777786f; /* 8.0 / 0.45 */
|
||||
const float max_height = 106.951874f; /* 20.0 / 0.187 */
|
||||
error_number = set_height(symbol, min_height, 40.0f, max_height, 0 /*no_errtxt*/);
|
||||
}
|
||||
} else {
|
||||
if (error_number < ZINT_ERROR) {
|
||||
@ -450,23 +448,22 @@ INTERNAL int excode39(struct zint_symbol *symbol, unsigned char source[], int le
|
||||
int error_number;
|
||||
|
||||
if (length > 86) {
|
||||
strcpy(symbol->errtxt, "328: Input too long (86 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 328, "Input length %d too long (maximum 86)", length);
|
||||
}
|
||||
|
||||
/* Creates a buffer string and places control characters into it */
|
||||
for (i = 0; i < length; i++) {
|
||||
if (source[i] > 127) {
|
||||
/* Cannot encode extended ASCII */
|
||||
strcpy(symbol->errtxt, "329: Invalid character in data, extended ASCII not allowed");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 329,
|
||||
"Invalid character at position %d in input, extended ASCII not allowed", i + 1);
|
||||
}
|
||||
memcpy(b, EC39Ctrl[source[i]], 2);
|
||||
b += EC39Ctrl[source[i]][1] ? 2 : 1;
|
||||
}
|
||||
if (b - buffer > 86) {
|
||||
strcpy(symbol->errtxt, "317: Expanded input too long (86 symbol character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 317, "Input too long, requires %d symbol characters (maximum 86)",
|
||||
(int) (b - buffer));
|
||||
}
|
||||
*b = '\0';
|
||||
|
||||
@ -512,16 +509,15 @@ INTERNAL int code93(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
assert(length > 0);
|
||||
|
||||
if (length > 123) { /* 9 (Start) + 123*9 + 2*9 (Checks) + 10 (Stop) = 1144 */
|
||||
strcpy(symbol->errtxt, "330: Input too long (123 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 330, "Input length %d too long (maximum 123)", length);
|
||||
}
|
||||
|
||||
/* Message Content */
|
||||
for (i = 0; i < length; i++) {
|
||||
if (source[i] > 127) {
|
||||
/* Cannot encode extended ASCII */
|
||||
strcpy(symbol->errtxt, "331: Invalid character in data, extended ASCII not allowed");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 331,
|
||||
"Invalid character at position %d in input, extended ASCII not allowed", i + 1);
|
||||
}
|
||||
memcpy(b, C93Ctrl[source[i]], 2);
|
||||
b += C93Ctrl[source[i]][1] ? 2 : 1;
|
||||
@ -531,8 +527,8 @@ INTERNAL int code93(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
/* Now we can check the true length of the barcode */
|
||||
h = b - buffer;
|
||||
if (h > 123) {
|
||||
strcpy(symbol->errtxt, "332: Expanded input too long (123 symbol character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 332,
|
||||
"Input too long, requires %d symbol characters (maximum 123)", h);
|
||||
}
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
@ -588,7 +584,7 @@ INTERNAL int code93(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
/* ANSI/AIM BC5-1995 Section 2.6 minimum height 0.2" or 15% of symbol length, whichever is greater
|
||||
no max X given so for min height use symbol length = (9 * (C + 4) + 1) * X + 2 * Q = symbol->width + 20;
|
||||
use 40 as default height based on figures in spec */
|
||||
float min_height = stripf((symbol->width + 20) * 0.15f);
|
||||
const float min_height = stripf((symbol->width + 20) * 0.15f);
|
||||
error_number = set_height(symbol, min_height, min_height > 40.0f ? min_height : 40.0f, 0.0f, 0 /*no_errtxt*/);
|
||||
} else {
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
|
||||
@ -604,7 +600,7 @@ INTERNAL int code93(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
}
|
||||
|
||||
typedef const struct s_channel_precalc {
|
||||
long value; unsigned char B[8]; unsigned char S[8]; unsigned char bmax[7]; unsigned char smax[7];
|
||||
int value; unsigned char B[8]; unsigned char S[8]; unsigned char bmax[7]; unsigned char smax[7];
|
||||
} channel_precalc;
|
||||
|
||||
#if 0
|
||||
@ -614,7 +610,7 @@ typedef const struct s_channel_precalc {
|
||||
#ifdef CHANNEL_GENERATE_PRECALCS
|
||||
/* To generate precalc tables uncomment CHANNEL_GENERATE_PRECALCS define and run
|
||||
"backend/tests/test_channel -f generate -g" and place result in "channel_precalcs.h" */
|
||||
static void channel_generate_precalc(int channels, long value, int mod, int last, int B[8], int S[8], int bmax[7],
|
||||
static void channel_generate_precalc(int channels, int value, int mod, int last, int B[8], int S[8], int bmax[7],
|
||||
int smax[7]) {
|
||||
int i;
|
||||
if (value == mod) printf("static channel_precalc channel_precalcs%d[] = {\n", channels);
|
||||
@ -628,19 +624,19 @@ static void channel_generate_precalc(int channels, long value, int mod, int last
|
||||
#include "channel_precalcs.h"
|
||||
#endif
|
||||
|
||||
static long channel_copy_precalc(channel_precalc precalc, int B[8], int S[8], int bmax[7], int smax[7]) {
|
||||
static int channel_copy_precalc(channel_precalc *const precalc, int B[8], int S[8], int bmax[7], int smax[7]) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
B[i] = precalc.B[i];
|
||||
S[i] = precalc.S[i];
|
||||
bmax[i] = precalc.bmax[i];
|
||||
smax[i] = precalc.smax[i];
|
||||
B[i] = precalc->B[i];
|
||||
S[i] = precalc->S[i];
|
||||
bmax[i] = precalc->bmax[i];
|
||||
smax[i] = precalc->smax[i];
|
||||
}
|
||||
B[7] = precalc.B[7];
|
||||
S[7] = precalc.S[7];
|
||||
B[7] = precalc->B[7];
|
||||
S[7] = precalc->S[7];
|
||||
|
||||
return precalc.value;
|
||||
return precalc->value;
|
||||
}
|
||||
|
||||
/* CHNCHR is adapted from ANSI/AIM BC12-1998 Annex D Figure D5 and is Copyright (c) AIM 1997 */
|
||||
@ -653,7 +649,7 @@ static long channel_copy_precalc(channel_precalc precalc, int B[8], int S[8], in
|
||||
specification is entirely in the public domain and free of all use restrictions,
|
||||
licenses and fees. AIM USA, its member companies, or individual officers
|
||||
assume no liability for the use of this document." */
|
||||
static void CHNCHR(int channels, long target_value, int B[8], int S[8]) {
|
||||
static void CHNCHR(int channels, int target_value, int B[8], int S[8]) {
|
||||
/* Use of initial pre-calculations taken from Barcode Writer in Pure PostScript (BWIPP)
|
||||
* Copyright (c) 2004-2020 Terry Burton (MIT/X-Consortium license) */
|
||||
static channel_precalc initial_precalcs[6] = {
|
||||
@ -671,16 +667,16 @@ static void CHNCHR(int channels, long target_value, int B[8], int S[8]) {
|
||||
{ 8, 8, 8, 8, 8, 8, 8, }, },
|
||||
};
|
||||
int bmax[7], smax[7];
|
||||
long value = 0;
|
||||
int value = 0;
|
||||
|
||||
channel_copy_precalc(initial_precalcs[channels - 3], B, S, bmax, smax);
|
||||
channel_copy_precalc(&initial_precalcs[channels - 3], B, S, bmax, smax);
|
||||
|
||||
#ifndef CHANNEL_GENERATE_PRECALCS
|
||||
if (channels == 7 && target_value >= channel_precalcs7[0].value) {
|
||||
value = channel_copy_precalc(channel_precalcs7[(target_value / channel_precalcs7[0].value) - 1], B, S, bmax,
|
||||
value = channel_copy_precalc(&channel_precalcs7[(target_value / channel_precalcs7[0].value) - 1], B, S, bmax,
|
||||
smax);
|
||||
} else if (channels == 8 && target_value >= channel_precalcs8[0].value) {
|
||||
value = channel_copy_precalc(channel_precalcs8[(target_value / channel_precalcs8[0].value) - 1], B, S, bmax,
|
||||
value = channel_copy_precalc(&channel_precalcs8[(target_value / channel_precalcs8[0].value) - 1], B, S, bmax,
|
||||
smax);
|
||||
}
|
||||
#endif
|
||||
@ -743,20 +739,20 @@ nb0: if (++B[0] <= bmax[0]) goto lb0;
|
||||
INTERNAL int channel(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
static const int max_ranges[] = { -1, -1, -1, 26, 292, 3493, 44072, 576688, 7742862 };
|
||||
int S[8] = {0}, B[8] = {0};
|
||||
long target_value = 0;
|
||||
int target_value;
|
||||
char dest[30];
|
||||
char *d = dest;
|
||||
int channels, i;
|
||||
int error_number = 0, zeroes;
|
||||
|
||||
if (length > 7) {
|
||||
strcpy(symbol->errtxt, "333: Input too long (7 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 333, "Input length %d too long (maximum 7)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "334: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 334,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
target_value = to_int(source, length);
|
||||
|
||||
if ((symbol->option_2 < 3) || (symbol->option_2 > 8)) {
|
||||
channels = 0;
|
||||
@ -764,11 +760,6 @@ INTERNAL int channel(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
channels = symbol->option_2;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
target_value *= 10;
|
||||
target_value += ctoi((char) source[i]);
|
||||
}
|
||||
|
||||
if (channels == 0) {
|
||||
channels = length + 1;
|
||||
if (target_value > 576688 && channels < 8) {
|
||||
@ -789,12 +780,12 @@ INTERNAL int channel(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
|
||||
if (target_value > max_ranges[channels]) {
|
||||
if (channels == 8) {
|
||||
sprintf(symbol->errtxt, "318: Value out of range (0 to %d)", max_ranges[channels]);
|
||||
} else {
|
||||
sprintf(symbol->errtxt, "335: Value out of range (0 to %d) for %d channels",
|
||||
max_ranges[channels], channels);
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 318, "Input value \"%1$d\" out of range (0 to %2$d)",
|
||||
target_value, max_ranges[channels]);
|
||||
}
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 335,
|
||||
"Input value \"%1$d\" out of range (0 to %2$d for %3$d channels)",
|
||||
target_value, max_ranges[channels], channels);
|
||||
}
|
||||
|
||||
CHNCHR(channels, target_value, B, S);
|
||||
@ -809,8 +800,7 @@ INTERNAL int channel(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
zeroes = channels - 1 - length;
|
||||
if (zeroes < 0) {
|
||||
zeroes = 0;
|
||||
}
|
||||
if (zeroes) {
|
||||
} else if (zeroes) {
|
||||
memset(symbol->text, '0', zeroes);
|
||||
}
|
||||
ustrcpy(symbol->text + zeroes, source);
|
||||
@ -841,19 +831,17 @@ INTERNAL int vin(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
char output_check;
|
||||
int sum;
|
||||
int i;
|
||||
static const int weight[17] = {8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2};
|
||||
static const char weight[17] = { 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 };
|
||||
|
||||
/* Check length */
|
||||
if (length != 17) {
|
||||
strcpy(symbol->errtxt, "336: Input wrong length (17 characters required)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 336, "Input length %d wrong (17 only)", length);
|
||||
}
|
||||
|
||||
/* Check input characters, I, O and Q are not allowed */
|
||||
if (!is_sane(ARSENIC_F, source, length)) {
|
||||
strcpy(symbol->errtxt,
|
||||
"337: Invalid character in data (alphanumerics only, excluding \"I\", \"O\" and \"Q\")");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(ARSENIC_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 337,
|
||||
"Invalid character at position %d in input (alphanumerics only, excluding \"IOQ\")", i);
|
||||
}
|
||||
|
||||
to_upper(source, length);
|
||||
@ -890,14 +878,13 @@ INTERNAL int vin(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
}
|
||||
|
||||
if (input_check != output_check) {
|
||||
sprintf(symbol->errtxt, "338: Invalid check digit '%c' (position 9), expecting '%c'",
|
||||
input_check, output_check);
|
||||
return ZINT_ERROR_INVALID_CHECK;
|
||||
return errtxtf(ZINT_ERROR_INVALID_CHECK, symbol, 338,
|
||||
"Invalid check digit '%1$c' (position 9), expecting '%2$c'", input_check, output_check);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start character */
|
||||
memcpy(d, "1211212111", 10);
|
||||
memcpy(d, C39Table[43], 10);
|
||||
d += 10;
|
||||
|
||||
/* Import character 'I' prefix? */
|
||||
@ -912,7 +899,7 @@ INTERNAL int vin(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
}
|
||||
|
||||
/* Stop character */
|
||||
memcpy(d, "121121211", 9);
|
||||
memcpy(d, C39Table[43], 9);
|
||||
d += 9;
|
||||
|
||||
expand(symbol, dest, d - dest);
|
||||
|
103
backend/code1.c
@ -1,7 +1,7 @@
|
||||
/* code1.c - USS Code One */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -30,6 +30,7 @@
|
||||
*/
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "common.h"
|
||||
@ -37,8 +38,9 @@
|
||||
#include "reedsol.h"
|
||||
#include "large.h"
|
||||
|
||||
#define C1_MAX_CWS 1480 /* Max data codewords for Version H */
|
||||
#define C1_MAX_ECCS 560 /* Max ECC codewords for Version H */
|
||||
#define C1_MAX_CWS 1480 /* Max data codewords for Version H */
|
||||
#define C1_MAX_CWS_S "1480" /* String version of above */
|
||||
#define C1_MAX_ECCS 560 /* Max ECC codewords for Version H */
|
||||
|
||||
#define C1_ASCII 1
|
||||
#define C1_C40 2
|
||||
@ -246,7 +248,7 @@ static int c1_look_ahead_test(const unsigned char source[], const int length, co
|
||||
}
|
||||
|
||||
/* Step P */
|
||||
if (gs1 && (c == '[')) {
|
||||
if (gs1 && c == '\x1D') {
|
||||
byte_count += C1_MULT_3; /* Step P1 */
|
||||
} else {
|
||||
byte_count += C1_MULT_1; /* Step P2 */
|
||||
@ -453,7 +455,7 @@ static int c1_codewords_remaining(struct zint_symbol *symbol, const int tp) {
|
||||
static int c1_c40text_cnt(const int current_mode, const int gs1, unsigned char input) {
|
||||
int cnt;
|
||||
|
||||
if (gs1 && input == '[') {
|
||||
if (gs1 && input == '\x1D') {
|
||||
return 2;
|
||||
}
|
||||
cnt = 1;
|
||||
@ -461,7 +463,7 @@ static int c1_c40text_cnt(const int current_mode, const int gs1, unsigned char i
|
||||
cnt += 2;
|
||||
input -= 128;
|
||||
}
|
||||
if ((current_mode == C1_C40 && c40_shift[input]) || (current_mode == C1_TEXT && text_shift[input])) {
|
||||
if ((current_mode == C1_C40 && c1_c40_shift[input]) || (current_mode == C1_TEXT && c1_text_shift[input])) {
|
||||
cnt += 1;
|
||||
}
|
||||
|
||||
@ -616,7 +618,7 @@ static int c1_encode(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
if (debug_print) printf("ASCDD(%.2s) ", source + sp);
|
||||
sp += 2;
|
||||
} else {
|
||||
if ((gs1) && (source[sp] == '[')) {
|
||||
if (gs1 && source[sp] == '\x1D') {
|
||||
if (length - (sp + 1) >= 15 && num_digits[sp + 1] >= 15) {
|
||||
/* Step B4 */
|
||||
target[tp++] = 236; /* FNC1 and change to Decimal */
|
||||
@ -648,7 +650,7 @@ static int c1_encode(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
target[tp++] = 235; /* FNC4 (Upper Shift) */
|
||||
target[tp++] = (source[sp] - 128) + 1;
|
||||
if (debug_print) printf("UpSh(%d) ", source[sp]);
|
||||
} else if ((gs1) && (source[sp] == '[')) {
|
||||
} else if (gs1 && source[sp] == '\x1D') {
|
||||
/* Step B8 */
|
||||
target[tp++] = 232; /* FNC1 */
|
||||
if (debug_print) fputs("FNC1 ", stdout);
|
||||
@ -689,11 +691,11 @@ static int c1_encode(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
const char *ct_shift, *ct_value;
|
||||
|
||||
if (current_mode == C1_C40) {
|
||||
ct_shift = c40_shift;
|
||||
ct_value = c40_value;
|
||||
ct_shift = c1_c40_shift;
|
||||
ct_value = c1_c40_value;
|
||||
} else {
|
||||
ct_shift = text_shift;
|
||||
ct_value = text_value;
|
||||
ct_shift = c1_text_shift;
|
||||
ct_value = c1_text_value;
|
||||
}
|
||||
if (debug_print) fputs(current_mode == C1_C40 ? "C40 " : "TEXT ", stdout);
|
||||
|
||||
@ -704,7 +706,7 @@ static int c1_encode(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
cte_buffer[cte_p++] = ct_shift[source[sp] - 128] - 1;
|
||||
}
|
||||
cte_buffer[cte_p++] = ct_value[source[sp] - 128];
|
||||
} else if (gs1 && (source[sp] == '[')) {
|
||||
} else if (gs1 && source[sp] == '\x1D') {
|
||||
cte_buffer[cte_p++] = 1; /* Shift 2 */
|
||||
cte_buffer[cte_p++] = 27; /* FNC1 */
|
||||
} else {
|
||||
@ -826,7 +828,7 @@ static int c1_encode(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
} else if (current_mode == C1_BYTE) {
|
||||
next_mode = C1_BYTE;
|
||||
|
||||
if (gs1 && (source[sp] == '[')) {
|
||||
if (gs1 && source[sp] == '\x1D') {
|
||||
next_mode = C1_ASCII;
|
||||
} else {
|
||||
if (source[sp] <= 127) {
|
||||
@ -901,7 +903,7 @@ static int c1_encode(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
} else if (source[sp] & 0x80) {
|
||||
target[tp++] = 235; /* FNC4 (Upper Shift) */
|
||||
target[tp++] = (source[sp] - 128) + 1;
|
||||
} else if ((gs1) && (source[sp] == '[')) {
|
||||
} else if (gs1 && source[sp] == '\x1D') {
|
||||
target[tp++] = 232; /* FNC1 */
|
||||
} else {
|
||||
target[tp++] = source[sp] + 1;
|
||||
@ -1023,35 +1025,33 @@ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
int row, col;
|
||||
int sub_version = 0;
|
||||
rs_t rs;
|
||||
int error_number = 0;
|
||||
const int gs1 = (symbol->input_mode & 0x07) == GS1_MODE;
|
||||
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
|
||||
|
||||
if ((symbol->option_2 < 0) || (symbol->option_2 > 10)) {
|
||||
strcpy(symbol->errtxt, "513: Invalid symbol size");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 513, "Version '%d' out of range (1 to 10)",
|
||||
symbol->option_2);
|
||||
}
|
||||
|
||||
if (symbol->structapp.count) {
|
||||
if (symbol->option_2 == 9) { /* Version S */
|
||||
strcpy(symbol->errtxt, "714: Structured Append not available for Version S");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 714, "Structured Append not available for Version S");
|
||||
}
|
||||
if (gs1) {
|
||||
strcpy(symbol->errtxt, "710: Cannot have Structured Append and GS1 mode at the same time");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 710,
|
||||
"Cannot have Structured Append and GS1 mode at the same time");
|
||||
}
|
||||
if (symbol->structapp.count < 2 || symbol->structapp.count > 128) {
|
||||
strcpy(symbol->errtxt, "711: Structured Append count out of range (2-128)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 711,
|
||||
"Structured Append count '%d' out of range (2 to 128)", symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
|
||||
sprintf(symbol->errtxt, "712: Structured Append index out of range (1-%d)", symbol->structapp.count);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 712,
|
||||
"Structured Append index '%1$d' out of range (1 to count %2$d)",
|
||||
symbol->structapp.index, symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.id[0]) {
|
||||
strcpy(symbol->errtxt, "713: Structured Append ID not available for Code One");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 713, "Structured Append ID not available for Code One");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1063,16 +1063,15 @@ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
int block_width;
|
||||
|
||||
if (seg_count > 1) {
|
||||
strcpy(symbol->errtxt, "715: Multiple segments not supported for Version S");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 715, "Multiple segments not supported for Version S");
|
||||
}
|
||||
if (segs[0].length > 18) {
|
||||
strcpy(symbol->errtxt, "514: Input data too long for Version S");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 514, "Input length %d too long for Version S (maximum 18)",
|
||||
segs[0].length);
|
||||
}
|
||||
if (!is_sane(NEON_F, segs[0].source, segs[0].length)) {
|
||||
strcpy(symbol->errtxt, "515: Invalid input data (Version S encodes numeric input only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, segs[0].source, segs[0].length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 515,
|
||||
"Invalid character at position %d in input (Version S encodes digits only)", i);
|
||||
}
|
||||
|
||||
size = 9;
|
||||
@ -1142,18 +1141,19 @@ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
unsigned int ecc[22];
|
||||
int data_length;
|
||||
int data_cw, ecc_cw, block_width;
|
||||
int last_mode;
|
||||
int last_mode = 0; /* Suppress gcc 14 "-Wmaybe-uninitialized" false positive */
|
||||
|
||||
if (c1_total_length_segs(segs, seg_count) > 90) {
|
||||
strcpy(symbol->errtxt, "519: Input data too long for Version T");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
if ((i = c1_total_length_segs(segs, seg_count)) > 90) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 519, "Input length %d too long for Version T (maximum 90)",
|
||||
i);
|
||||
}
|
||||
|
||||
data_length = c1_encode_segs(symbol, segs, seg_count, gs1, target, &last_mode);
|
||||
|
||||
if (data_length == 0 || data_length > 38) {
|
||||
strcpy(symbol->errtxt, "516: Input data too long for Version T");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
assert(data_length); /* Can't exceed C1_MAX_CWS as input <= 90 */
|
||||
if (data_length > 38) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 516,
|
||||
"Input too long for Version T, requires %d codewords (maximum 38)", data_length);
|
||||
}
|
||||
|
||||
size = 10;
|
||||
@ -1234,8 +1234,8 @@ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
data_length = c1_encode_segs(symbol, segs, seg_count, gs1, target, &last_mode);
|
||||
|
||||
if (data_length == 0) {
|
||||
strcpy(symbol->errtxt, "517: Input data is too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 517,
|
||||
"Input too long, requires too many codewords (maximum " C1_MAX_CWS_S ")");
|
||||
}
|
||||
|
||||
for (i = 7; i >= 0; i--) {
|
||||
@ -1249,8 +1249,9 @@ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
}
|
||||
|
||||
if ((symbol->option_2 != 0) && (symbol->option_2 < size)) {
|
||||
strcpy(symbol->errtxt, "518: Input too long for selected symbol size");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 518,
|
||||
"Input too long for Version %1$c, requires %2$d codewords (maximum %3$d)",
|
||||
'A' + symbol->option_2 - 1, data_length, c1_data_length[symbol->option_2 - 1]);
|
||||
}
|
||||
data_cw = c1_data_length[size - 1];
|
||||
|
||||
@ -1577,16 +1578,14 @@ INTERNAL int codeone(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
|
||||
if (symbol->option_2 == 9) { /* Version S */
|
||||
if (symbol->eci || gs1) {
|
||||
sprintf(symbol->errtxt, "511: %s ignored for Version S",
|
||||
symbol->eci && gs1 ? "ECI and GS1 mode" : symbol->eci ? "ECI" : "GS1 mode");
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
return errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 511, "%s ignored for Version S",
|
||||
symbol->eci && gs1 ? "ECI and GS1 mode" : symbol->eci ? "ECI" : "GS1 mode");
|
||||
}
|
||||
} else if (symbol->eci && gs1) {
|
||||
strcpy(symbol->errtxt, "512: ECI ignored for GS1 mode");
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
return errtxt(ZINT_WARN_INVALID_OPTION, symbol, 512, "ECI ignored for GS1 mode");
|
||||
}
|
||||
|
||||
return error_number;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* code1.h - Lookup info for USS Code One */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -33,67 +33,96 @@
|
||||
#ifndef Z_CODE1_H
|
||||
#define Z_CODE1_H
|
||||
|
||||
static const char c40_shift[] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
|
||||
/* C40 shift to use per ASCII character (Table 11) */
|
||||
static const char c1_c40_shift[128] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
|
||||
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
|
||||
};
|
||||
|
||||
static const char c40_value[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||||
15, 16, 17, 18, 19, 20, 21, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
22, 23, 24, 25, 26, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
|
||||
/* C40 ASCII values (Table 11) */
|
||||
static const char c1_c40_value[128] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20,
|
||||
21, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 22, 23, 24, 25, 26,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
|
||||
};
|
||||
|
||||
static const char text_shift[] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3
|
||||
/* Text shift to use per ASCII character (Table 11) */
|
||||
static const char c1_text_shift[128] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2,
|
||||
3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3
|
||||
};
|
||||
|
||||
static const char text_value[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||||
15, 16, 17, 18, 19, 20, 21, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
|
||||
22, 23, 24, 25, 26, 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 27, 28, 29, 30, 31
|
||||
/* Text ASCII values (Table 11) */
|
||||
static const char c1_text_value[128] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20,
|
||||
21, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 22, 23, 24, 25, 26,
|
||||
0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 27, 28, 29, 30, 31
|
||||
};
|
||||
|
||||
static const unsigned short c1_height[] = {
|
||||
/* Height in X-dims per version A-H (Table 2) */
|
||||
static const unsigned char c1_height[8] = {
|
||||
16, 22, 28, 40, 52, 70, 104, 148
|
||||
};
|
||||
|
||||
static const unsigned short c1_width[] = {
|
||||
/* Width in X-dims per version A-H (Table 2) */
|
||||
static const unsigned char c1_width[8] = {
|
||||
18, 22, 32, 42, 54, 76, 98, 134
|
||||
};
|
||||
|
||||
static const unsigned short c1_data_length[] = {
|
||||
/* Data codewords per version A-H (Table 14) */
|
||||
static const unsigned short c1_data_length[8] = {
|
||||
10, 19, 44, 91, 182, 370, 732, 1480
|
||||
};
|
||||
|
||||
static const unsigned short c1_ecc_length[] = {
|
||||
/* EC codewords per version A-H (Table 14) */
|
||||
static const unsigned short c1_ecc_length[8] = {
|
||||
10, 16, 26, 44, 70, 140, 280, 560
|
||||
};
|
||||
|
||||
static const unsigned short c1_blocks[] = {
|
||||
/* Number of codewords to divide into odd/even blocks for EC per version A-H */
|
||||
static const unsigned char c1_blocks[8] = {
|
||||
1, 1, 1, 1, 1, 2, 4, 8
|
||||
};
|
||||
|
||||
static const unsigned short c1_data_blocks[] = {
|
||||
/* Data blocks per version A-H (Table 14) */
|
||||
static const unsigned char c1_data_blocks[8] = {
|
||||
10, 19, 44, 91, 182, 185, 183, 185
|
||||
};
|
||||
|
||||
static const unsigned short c1_ecc_blocks[] = {
|
||||
/* EC blocks per version A-H (Table 14) */
|
||||
static const unsigned char c1_ecc_blocks[8] = {
|
||||
10, 16, 26, 44, 70, 70, 70, 70
|
||||
};
|
||||
|
||||
static const unsigned short c1_grid_width[] = {
|
||||
/* Number of block columns per version A-H */
|
||||
static const unsigned char c1_grid_width[8] = {
|
||||
4, 5, 7, 9, 12, 17, 22, 30
|
||||
};
|
||||
|
||||
static const unsigned short c1_grid_height[] = {
|
||||
/* Number of block rows per version A-H */
|
||||
static const unsigned char c1_grid_height[8] = {
|
||||
5, 7, 10, 15, 21, 30, 46, 68
|
||||
};
|
||||
|
||||
|
1326
backend/code128.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2020-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2020-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -38,24 +38,13 @@ extern "C" {
|
||||
|
||||
/* Allow for a reasonable number of special Code Set escapes and for GS1 AI delimiters */
|
||||
#define C128_MAX 256
|
||||
|
||||
#define C128_LATCHA 'A'
|
||||
#define C128_LATCHB 'B'
|
||||
#define C128_LATCHC 'C'
|
||||
#define C128_SHIFTA 'a'
|
||||
#define C128_SHIFTB 'b'
|
||||
#define C128_ABORC '9'
|
||||
#define C128_AORB 'Z'
|
||||
#define C128_MAX_S "256" /* String version of above */
|
||||
|
||||
INTERNAL int code128(struct zint_symbol *symbol, unsigned char source[], int length);
|
||||
|
||||
INTERNAL int c128_parunmodd(const unsigned char llyth);
|
||||
INTERNAL void c128_dxsmooth(int list[2][C128_MAX], int *indexliste, const char *manual_set);
|
||||
INTERNAL void c128_set_a(const unsigned char source, int values[], int *bar_chars);
|
||||
INTERNAL int c128_set_b(const unsigned char source, int values[], int *bar_chars);
|
||||
INTERNAL void c128_set_c(const unsigned char source_a, const unsigned char source_b, int values[], int *bar_chars);
|
||||
INTERNAL void c128_put_in_set(int list[2][C128_MAX], const int indexliste, char set[C128_MAX],
|
||||
const unsigned char *source);
|
||||
|
||||
INTERNAL_DATA_EXTERN const char C128Table[107][6];
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* code16k.c - Handles Code 16k stacked symbology */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -39,23 +39,240 @@
|
||||
#include "common.h"
|
||||
#include "code128.h"
|
||||
|
||||
/* Note these previously defined in "code128.h" - keeping `C128_` prefix for now */
|
||||
#define C128_LATCHA 'A'
|
||||
#define C128_LATCHB 'B'
|
||||
#define C128_LATCHC 'C'
|
||||
#define C128_SHIFTA 'a'
|
||||
#define C128_SHIFTB 'b'
|
||||
#define C128_ABORC '9'
|
||||
#define C128_AORB 'Z'
|
||||
|
||||
/* Note using C128Table with extra entry at 106 (Triple Shift) for C16KTable */
|
||||
|
||||
/* EN 12323 Table 3 and Table 4 - Start patterns and stop patterns */
|
||||
static const char C16KStartStop[8][4] = {
|
||||
/* EN 12323 Table 3 and Table 4 - Start patterns and stop patterns */
|
||||
{'3','2','1','1'}, {'2','2','2','1'}, {'2','1','2','2'}, {'1','4','1','1'},
|
||||
{'1','1','3','2'}, {'1','2','3','1'}, {'1','1','1','4'}, {'3','1','1','2'}
|
||||
};
|
||||
|
||||
/* EN 12323 Table 5 - Start and stop values defining row numbers */
|
||||
static const int C16KStartValues[16] = {
|
||||
static const unsigned char C16KStartValues[16] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7
|
||||
};
|
||||
|
||||
static const int C16KStopValues[16] = {
|
||||
static const unsigned char C16KStopValues[16] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3
|
||||
};
|
||||
|
||||
/* Determine appropriate mode for a given character (was `c128_parunmodd()`) */
|
||||
static int c16k_parunmodd(const unsigned char llyth, const int check_fnc1) {
|
||||
int modd;
|
||||
|
||||
if (llyth <= 31) {
|
||||
modd = check_fnc1 && llyth == '\x1D' ? C128_ABORC : C128_SHIFTA;
|
||||
} else if ((llyth >= 48) && (llyth <= 57)) {
|
||||
modd = C128_ABORC;
|
||||
} else if (llyth <= 95) {
|
||||
modd = C128_AORB;
|
||||
} else if (llyth <= 127) {
|
||||
modd = C128_SHIFTB;
|
||||
} else if (llyth <= 159) {
|
||||
modd = C128_SHIFTA;
|
||||
} else if (llyth <= 223) {
|
||||
modd = C128_AORB;
|
||||
} else {
|
||||
modd = C128_SHIFTB;
|
||||
}
|
||||
|
||||
return modd;
|
||||
}
|
||||
|
||||
/* Bring together same type blocks (was `c128_grwp()`) */
|
||||
static void c16k_grwp(int list[2][C128_MAX], int *p_indexliste) {
|
||||
|
||||
if (*p_indexliste > 1) {
|
||||
int i = 1;
|
||||
while (i < *p_indexliste) {
|
||||
if (list[1][i - 1] == list[1][i]) {
|
||||
int j;
|
||||
/* Bring together */
|
||||
list[0][i - 1] = list[0][i - 1] + list[0][i];
|
||||
j = i + 1;
|
||||
|
||||
/* Decrease the list */
|
||||
while (j < *p_indexliste) {
|
||||
list[0][j - 1] = list[0][j];
|
||||
list[1][j - 1] = list[1][j];
|
||||
j++;
|
||||
}
|
||||
*p_indexliste = *p_indexliste - 1;
|
||||
i--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Implements rules from ISO/IEC 15417:2007 Annex E (was `c128_dxsmooth()`) */
|
||||
static void c16k_dxsmooth(int list[2][C128_MAX], int *p_indexliste) {
|
||||
int i, j, nextshift = 0 /*Suppresses gcc -Wmaybe-uninitialized false positive*/, nextshift_i = 0;
|
||||
const int indexliste = *p_indexliste;
|
||||
|
||||
for (i = 0; i < indexliste; i++) {
|
||||
int current = list[1][i]; /* Either C128_ABORC, C128_AORB, C128_SHIFTA or C128_SHIFTB */
|
||||
int length = list[0][i];
|
||||
if (i == nextshift_i) {
|
||||
nextshift = 0;
|
||||
/* Set next shift to aid deciding between latching to A or B - taken from Okapi, props Daniel Gredler */
|
||||
for (j = i + 1; j < indexliste; j++) {
|
||||
if (list[1][j] == C128_SHIFTA || list[1][j] == C128_SHIFTB) {
|
||||
nextshift = list[1][j];
|
||||
nextshift_i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0) { /* first block */
|
||||
if (current == C128_ABORC) {
|
||||
if ((indexliste == 1) && (length == 2)) {
|
||||
/* Rule 1a */
|
||||
list[1][i] = C128_LATCHC;
|
||||
current = C128_LATCHC;
|
||||
} else if (length >= 4) {
|
||||
/* Rule 1b */
|
||||
list[1][i] = C128_LATCHC;
|
||||
current = C128_LATCHC;
|
||||
} else {
|
||||
current = C128_AORB; /* Determine below */
|
||||
}
|
||||
}
|
||||
if (current == C128_AORB) {
|
||||
if (nextshift == C128_SHIFTA) {
|
||||
/* Rule 1c */
|
||||
list[1][i] = C128_LATCHA;
|
||||
} else {
|
||||
/* Rule 1d */
|
||||
list[1][i] = C128_LATCHB;
|
||||
}
|
||||
} else if (current == C128_SHIFTA) {
|
||||
/* Rule 1c */
|
||||
list[1][i] = C128_LATCHA;
|
||||
} else if (current == C128_SHIFTB) { /* Unless C128_LATCHX set above, can only be C128_SHIFTB */
|
||||
/* Rule 1d */
|
||||
list[1][i] = C128_LATCHB;
|
||||
}
|
||||
} else {
|
||||
int last = list[1][i - 1];
|
||||
if (current == C128_ABORC) {
|
||||
if (length >= 4) {
|
||||
/* Rule 3 - note Rule 3b (odd C blocks) dealt with later */
|
||||
list[1][i] = C128_LATCHC;
|
||||
current = C128_LATCHC;
|
||||
} else {
|
||||
current = C128_AORB; /* Determine below */
|
||||
}
|
||||
}
|
||||
if (current == C128_AORB) {
|
||||
if (last == C128_LATCHA || last == C128_SHIFTB) { /* Maintain state */
|
||||
list[1][i] = C128_LATCHA;
|
||||
} else if (last == C128_LATCHB || last == C128_SHIFTA) { /* Maintain state */
|
||||
list[1][i] = C128_LATCHB;
|
||||
} else if (nextshift == C128_SHIFTA) {
|
||||
list[1][i] = C128_LATCHA;
|
||||
} else {
|
||||
list[1][i] = C128_LATCHB;
|
||||
}
|
||||
} else if (current == C128_SHIFTA) {
|
||||
if (length > 1) {
|
||||
/* Rule 4 */
|
||||
list[1][i] = C128_LATCHA;
|
||||
} else if (last == C128_LATCHA || last == C128_SHIFTB) { /* Maintain state */
|
||||
list[1][i] = C128_LATCHA;
|
||||
} else if (last == C128_LATCHC) {
|
||||
list[1][i] = C128_LATCHA;
|
||||
}
|
||||
} else if (current == C128_SHIFTB) { /* Unless C128_LATCHX set above, can only be C128_SHIFTB */
|
||||
if (length > 1) {
|
||||
/* Rule 5 */
|
||||
list[1][i] = C128_LATCHB;
|
||||
} else if (last == C128_LATCHB || last == C128_SHIFTA) { /* Maintain state */
|
||||
list[1][i] = C128_LATCHB;
|
||||
} else if (last == C128_LATCHC) {
|
||||
list[1][i] = C128_LATCHB;
|
||||
}
|
||||
}
|
||||
} /* Rule 2 is implemented elsewhere, Rule 6 is implied */
|
||||
}
|
||||
|
||||
c16k_grwp(list, p_indexliste);
|
||||
}
|
||||
|
||||
/* Put set data into set[]. Resolves odd C blocks (was `c128_put_in_set()`) */
|
||||
static void c16k_put_in_set(int list[2][C128_MAX], const int indexliste, char set[C128_MAX],
|
||||
const unsigned char *source) {
|
||||
int read = 0;
|
||||
int i, j;
|
||||
int c_count = 0, have_nonc = 0;
|
||||
|
||||
for (i = 0; i < indexliste; i++) {
|
||||
for (j = 0; j < list[0][i]; j++) {
|
||||
set[read++] = list[1][i];
|
||||
}
|
||||
}
|
||||
/* Watch out for odd-length Mode C blocks */
|
||||
for (i = 0; i < read; i++) {
|
||||
if (set[i] == 'C') {
|
||||
if (source[i] == '\x1D') {
|
||||
if (c_count & 1) {
|
||||
have_nonc = 1;
|
||||
if (i > c_count) {
|
||||
set[i - c_count] = 'B';
|
||||
} else {
|
||||
set[i - 1] = 'B';
|
||||
}
|
||||
}
|
||||
c_count = 0;
|
||||
} else {
|
||||
c_count++;
|
||||
}
|
||||
} else {
|
||||
have_nonc = 1;
|
||||
if (c_count & 1) {
|
||||
if (i > c_count) {
|
||||
set[i - c_count] = 'B';
|
||||
} else {
|
||||
set[i - 1] = 'B';
|
||||
}
|
||||
}
|
||||
c_count = 0;
|
||||
}
|
||||
}
|
||||
if (c_count & 1) {
|
||||
if (i > c_count && have_nonc) {
|
||||
set[i - c_count] = 'B';
|
||||
if (c_count < 4) {
|
||||
/* Rule 1b */
|
||||
for (j = i - c_count + 1; j < i; j++) {
|
||||
set[j] = 'B';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
set[i - 1] = 'B';
|
||||
}
|
||||
}
|
||||
for (i = 1; i < read - 1; i++) {
|
||||
if (set[i] == 'C' && set[i - 1] != 'C' && set[i + 1] != 'C') {
|
||||
set[i] = set[i + 1];
|
||||
}
|
||||
}
|
||||
if (read > 1 && set[read - 1] == 'C' && set[read - 2] != 'C') {
|
||||
set[read - 1] = set[read - 2];
|
||||
}
|
||||
}
|
||||
|
||||
/* Code 16k EN 12323:2005 */
|
||||
INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
char width_pattern[40]; /* 4 (start) + 1 (guard) + 5*6 (chars) + 4 (stop) + 1 */
|
||||
int current_row, rows, looper, first_check, second_check;
|
||||
@ -71,13 +288,12 @@ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
|
||||
|
||||
if (length > C128_MAX) {
|
||||
strcpy(symbol->errtxt, "420: Input too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 420, "Input length %d too long (maximum " C128_MAX_S ")", length);
|
||||
}
|
||||
|
||||
if (symbol->option_1 == 1 || symbol->option_1 > 16) {
|
||||
strcpy(symbol->errtxt, "424: Minimum number of rows out of range (2 to 16)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 424, "Minimum number of rows '%d' out of range (2 to 16)",
|
||||
symbol->option_1);
|
||||
}
|
||||
|
||||
/* Detect extended ASCII characters */
|
||||
@ -90,7 +306,7 @@ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
indexliste = 0;
|
||||
indexchaine = 0;
|
||||
|
||||
mode = c128_parunmodd(source[indexchaine]);
|
||||
mode = c16k_parunmodd(source[indexchaine], gs1 /*check_fnc1*/);
|
||||
|
||||
do {
|
||||
list[1][indexliste] = mode;
|
||||
@ -100,18 +316,15 @@ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
if (indexchaine == length) {
|
||||
break;
|
||||
}
|
||||
mode = c128_parunmodd(source[indexchaine]);
|
||||
if ((gs1) && (source[indexchaine] == '[')) {
|
||||
mode = C128_ABORC;
|
||||
} /* FNC1 */
|
||||
mode = c16k_parunmodd(source[indexchaine], gs1 /*check_fnc1*/);
|
||||
}
|
||||
indexliste++;
|
||||
} while (indexchaine < length);
|
||||
|
||||
c128_dxsmooth(list, &indexliste, NULL /*manual_set*/);
|
||||
c16k_dxsmooth(list, &indexliste);
|
||||
|
||||
/* Put set data into set[], resolving odd C blocks */
|
||||
c128_put_in_set(list, indexliste, set, source);
|
||||
c16k_put_in_set(list, indexliste, set, source);
|
||||
|
||||
if (debug_print) {
|
||||
printf("Data: %.*s\n", length, source);
|
||||
@ -132,8 +345,7 @@ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
|
||||
if (symbol->output_options & READER_INIT) {
|
||||
if (gs1) {
|
||||
strcpy(symbol->errtxt, "422: Cannot use both GS1 mode and Reader Initialisation");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 422, "Cannot use Reader Initialisation in GS1 mode");
|
||||
}
|
||||
if (m == 2) {
|
||||
m = 5;
|
||||
@ -206,7 +418,7 @@ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
values[bar_characters++] = 98;
|
||||
}
|
||||
|
||||
if (!((gs1) && (source[read] == '['))) {
|
||||
if (!gs1 || source[read] != '\x1D') {
|
||||
switch (set[read]) { /* Encode data characters */
|
||||
case 'A':
|
||||
case 'a': c128_set_a(source[read], values, &bar_characters);
|
||||
@ -226,8 +438,8 @@ INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
}
|
||||
|
||||
if (bar_characters > 80 - 2) { /* Max rows 16 * 5 - 2 check chars */
|
||||
strcpy(symbol->errtxt, "421: Input too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 421,
|
||||
"Input too long, requires %d symbol characters (maximum 78)", bar_characters);
|
||||
}
|
||||
} while (read < length);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* code49.c - Handles Code 49 */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -53,8 +53,7 @@ INTERNAL int code49(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
int error_number = 0;
|
||||
|
||||
if (length > 81) {
|
||||
strcpy(symbol->errtxt, "430: Input too long (81 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 430, "Input length %d too long (maximum 81)", length);
|
||||
}
|
||||
if ((symbol->input_mode & 0x07) == GS1_MODE) {
|
||||
gs1 = 1;
|
||||
@ -65,10 +64,10 @@ INTERNAL int code49(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (source[i] > 127) {
|
||||
strcpy(symbol->errtxt, "431: Invalid character in input data, extended ASCII not allowed");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 431,
|
||||
"Invalid character at position %d in input, extended ASCII not allowed", i + 1);
|
||||
}
|
||||
if (gs1 && (source[i] == '[')) {
|
||||
if (gs1 && source[i] == '\x1D') {
|
||||
*d++ = '*'; /* FNC1 */
|
||||
} else {
|
||||
const char *const entry = c49_table7[source[i]];
|
||||
@ -219,8 +218,8 @@ INTERNAL int code49(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
}
|
||||
|
||||
if (codeword_count > 49) {
|
||||
strcpy(symbol->errtxt, "432: Input too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 432, "Input too long, requires %d codewords (maximum 49)",
|
||||
codeword_count);
|
||||
}
|
||||
|
||||
/* Place codewords in code character array (c grid) */
|
||||
|
376
backend/common.c
@ -1,7 +1,7 @@
|
||||
/* common.c - Contains functions needed for a number of barcodes */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -31,6 +31,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "common.h"
|
||||
|
||||
@ -87,7 +88,7 @@ INTERNAL int chr_cnt(const unsigned char source[], const int length, const unsig
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Flag table for `is_chr()` and `is_sane()` */
|
||||
/* Flag table for `is_chr()` and `not_sane()` */
|
||||
#define IS_CLS_F (IS_CLI_F | IS_SIL_F)
|
||||
static const unsigned short flgs[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00-1F*/
|
||||
@ -126,21 +127,22 @@ INTERNAL int is_chr(const unsigned int flg, const unsigned int c) {
|
||||
return c < 0x80 && (flgs[c] & flg) != 0;
|
||||
}
|
||||
|
||||
/* Verifies that a string only uses valid characters */
|
||||
INTERNAL int is_sane(const unsigned int flg, const unsigned char source[], const int length) {
|
||||
/* Verifies if a string only uses valid characters, returning 1-based position in `source` if not, 0 for success */
|
||||
INTERNAL int not_sane(const unsigned int flg, const unsigned char source[], const int length) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (!(flgs[source[i]] & flg)) {
|
||||
return 0;
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Replaces huge switch statements for looking up in tables */
|
||||
/* Verifies that a string only uses valid characters, and returns `test_string` position of each in `posns` array */
|
||||
INTERNAL int is_sane_lookup(const char test_string[], const int test_length, const unsigned char source[],
|
||||
/* Verifies if a string only uses valid characters as above, but also returns `test_string` position of each in
|
||||
`posns` array */
|
||||
INTERNAL int not_sane_lookup(const char test_string[], const int test_length, const unsigned char source[],
|
||||
const int length, int *posns) {
|
||||
int i, j;
|
||||
|
||||
@ -153,11 +155,11 @@ INTERNAL int is_sane_lookup(const char test_string[], const int test_length, con
|
||||
}
|
||||
}
|
||||
if (posns[i] == -1) {
|
||||
return 0;
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns the position of `data` in `set_string` */
|
||||
@ -185,6 +187,7 @@ INTERNAL int bin_append_posn(const int arg, const int length, char *binary, cons
|
||||
}
|
||||
|
||||
#ifndef Z_COMMON_INLINE
|
||||
|
||||
/* Returns true (1) if a module is dark/black, otherwise false (0) */
|
||||
INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord) {
|
||||
return (symbol->encoded_data[y_coord][x_coord >> 3] >> (x_coord & 0x07)) & 1;
|
||||
@ -204,13 +207,14 @@ INTERNAL int module_colour_is_set(const struct zint_symbol *symbol, const int y_
|
||||
INTERNAL void set_module_colour(struct zint_symbol *symbol, const int y_coord, const int x_coord, const int colour) {
|
||||
symbol->encoded_data[y_coord][x_coord] = colour;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Sets a dark/black module to white (i.e. unsets) */
|
||||
INTERNAL void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) {
|
||||
symbol->encoded_data[y_coord][x_coord >> 3] &= ~(1 << (x_coord & 0x07));
|
||||
}
|
||||
|
||||
#endif /* Z_COMMON_INLINE */
|
||||
|
||||
/* Expands from a width pattern to a bit pattern */
|
||||
INTERNAL void expand(struct zint_symbol *symbol, const char data[], const int length) {
|
||||
|
||||
@ -242,6 +246,294 @@ INTERNAL void expand(struct zint_symbol *symbol, const char data[], const int le
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for `errtxt()` & `errtxtf()` to set "err_id: " part of error message, returning length */
|
||||
static int errtxt_id_str(char *errtxt, int num) {
|
||||
int len = 0;
|
||||
if (num == -1) {
|
||||
errtxt[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
if (num < 0 || num > 9999) { /* Restrict to 4 digits */
|
||||
num = 9999;
|
||||
}
|
||||
if (num >= 1000) {
|
||||
errtxt[len++] = '0' + (num / 1000);
|
||||
num %= 1000;
|
||||
}
|
||||
errtxt[len++] = '0' + (num / 100);
|
||||
num %= 100;
|
||||
errtxt[len++] = '0' + (num / 10);
|
||||
num %= 10;
|
||||
errtxt[len++] = '0' + num;
|
||||
errtxt[len++] = ':';
|
||||
errtxt[len++] = ' ';
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Set `symbol->errtxt` to "err_id: msg", returning `error_number`. If `err_id` is -1, the "err_id: " prefix is
|
||||
omitted */
|
||||
INTERNAL int errtxt(const int error_number, struct zint_symbol *symbol, const int err_id, const char *msg) {
|
||||
const int max_len = (int) sizeof(symbol->errtxt) - 1;
|
||||
const int id_len = errtxt_id_str(symbol->errtxt, err_id);
|
||||
int msg_len = (int) strlen(msg);
|
||||
|
||||
if (id_len + msg_len > max_len) {
|
||||
if (!(symbol->debug & ZINT_DEBUG_TEST)) assert(0); /* Catch truncations */
|
||||
msg_len = max_len - id_len;
|
||||
}
|
||||
memcpy(symbol->errtxt + id_len, msg, msg_len);
|
||||
|
||||
symbol->errtxt[id_len + msg_len] = '\0';
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
static int errtxtf_dpad(const char *fmt); /* Forward reference */
|
||||
|
||||
/* Helper for `errtxtf()` to parse numbered specifier "n$" (where "n" 1-9), returning `fmt` advance increment */
|
||||
static int errtxtf_num_arg(const char *fmt, int *p_arg) {
|
||||
int ret = 0;
|
||||
int arg = -2;
|
||||
if (!errtxtf_dpad(fmt) && z_isdigit(fmt[0])) {
|
||||
arg = fmt[1] == '$' ? fmt[0] - '0' - 1 : -1;
|
||||
ret = 2;
|
||||
}
|
||||
if (p_arg) {
|
||||
*p_arg = arg;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Helper for `errtxtf()` to parse length precision, returning `fmt` advance increment */
|
||||
static int errtxtf_slen(const char *fmt, const int arg, int *p_arg_cnt, int *p_len) {
|
||||
int ret = 0;
|
||||
int len = -1;
|
||||
if (fmt[0] == '.') {
|
||||
if (z_isdigit(fmt[1]) && fmt[1] != '0') {
|
||||
len = fmt[1] - '0';
|
||||
for (ret = 2; z_isdigit(fmt[ret]); ret++) {
|
||||
len = len * 10 + fmt[ret] - '0';
|
||||
}
|
||||
if (fmt[ret] != 's') {
|
||||
len = -1;
|
||||
}
|
||||
} else if (fmt[1] == '*' && fmt[2] == 's' && arg < 0) {
|
||||
len = 0;
|
||||
ret = 2;
|
||||
} else if (fmt[1] == '*' && z_isdigit(fmt[2]) && fmt[3] == '$' && fmt[4] == 's') {
|
||||
if (arg == -1 || arg == fmt[2] - '0') {
|
||||
len = 0;
|
||||
if (p_arg_cnt) {
|
||||
(*p_arg_cnt)++;
|
||||
}
|
||||
}
|
||||
ret = 4;
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
if (p_len) {
|
||||
*p_len = len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Helper for `errtxtf()` to parse zero-padded minimum field length for "%d", returning `fmt` advance increment */
|
||||
static int errtxtf_dpad(const char *fmt) {
|
||||
/* Allow one leading zero plus one or two digits only */
|
||||
if (fmt[0] == '0' && z_isdigit(fmt[1])) {
|
||||
if (fmt[1] != '0' && fmt[2] == 'd') {
|
||||
return 2;
|
||||
}
|
||||
if (z_isdigit(fmt[1]) && fmt[1] != '0' && z_isdigit(fmt[2]) && fmt[3] == 'd') {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set `symbol->errtxt` to "err_id: msg" with restricted subset of `printf()` formatting, returning `error_number`.
|
||||
If `err_id` is -1, the "err_id: " prefix is omitted. Only the following specifiers are supported: "c", "d", "f",
|
||||
"g" and "s", with no modifiers apart from "<n>$" numbering for l10n ("<n>" 1-9), in which case all specifiers must
|
||||
be numbered, "%s" with length precisions: "%.*s", "%<n+1>$.*<n>$s", "%.<p>s" and "%<n>$.<p>s", and "%d" with
|
||||
zero-padded minimum field lengths: "%0<m>d" or %<n>$0<m>d" ("<m>" 1-99) */
|
||||
INTERNAL int errtxtf(const int error_number, struct zint_symbol *symbol, const int err_id, const char *fmt, ...) {
|
||||
const int max_len = (int) sizeof(symbol->errtxt) - 1;
|
||||
int p = errtxt_id_str(symbol->errtxt, err_id);
|
||||
const char *f;
|
||||
int i;
|
||||
int arg_cnt = 0;
|
||||
int have_num_arg = 0, have_unnum_arg = 0;
|
||||
va_list ap;
|
||||
int idxs[9] = {0}; /* Argument order */
|
||||
char specs[9] = {0}; /* Format specifiers */
|
||||
const char *ss[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* "%s" */
|
||||
int slens[9] = {0}; /* "%s" length precisions */
|
||||
int have_slens[9] = {0}; /* Bools for if "%s" has length precision */
|
||||
char dpads[9][3] = {{0}}; /* 2-digit minimum field length */
|
||||
char dfgs[9][100] = {{0}}; /* "%d", "%f" and "%g", allowing for padding up to 99 */
|
||||
int cs[9] = {0}; /* "%c" */
|
||||
|
||||
/* Get argument order and specifiers */
|
||||
for (f = fmt, i = 0; *f; f++) {
|
||||
if (*f == '%') {
|
||||
int inc, arg, len;
|
||||
if (*++f == '%') {
|
||||
continue;
|
||||
}
|
||||
if ((inc = errtxtf_num_arg(f, &arg))) {
|
||||
if (arg == -1) {
|
||||
if (!(symbol->debug & ZINT_DEBUG_TEST)) assert(0);
|
||||
return errtxt(ZINT_ERROR_ENCODING_PROBLEM, symbol, 0,
|
||||
"Internal error: invalid numbered format specifer");
|
||||
}
|
||||
if (i >= 9) {
|
||||
if (!(symbol->debug & ZINT_DEBUG_TEST)) assert(0);
|
||||
return errtxt(ZINT_ERROR_ENCODING_PROBLEM, symbol, 0,
|
||||
"Internal error: too many format specifiers (9 maximum)");
|
||||
}
|
||||
f += inc;
|
||||
have_num_arg = 1;
|
||||
idxs[i] = arg;
|
||||
} else {
|
||||
if (i >= 9) {
|
||||
if (!(symbol->debug & ZINT_DEBUG_TEST)) assert(0);
|
||||
return errtxt(ZINT_ERROR_ENCODING_PROBLEM, symbol, 0,
|
||||
"Internal error: too many format specifiers (9 maximum)");
|
||||
}
|
||||
have_unnum_arg = 1;
|
||||
idxs[i] = i;
|
||||
}
|
||||
if ((inc = errtxtf_slen(f, arg, &arg_cnt, &len))) {
|
||||
if (len == -1) {
|
||||
if (!(symbol->debug & ZINT_DEBUG_TEST)) assert(0);
|
||||
return errtxt(ZINT_ERROR_ENCODING_PROBLEM, symbol, 0, "Internal error: invalid length precision");
|
||||
}
|
||||
slens[idxs[i]] = len == 0 ? -1 : len; /* TODO: keep `slens` separate else last mentioned trumps */
|
||||
have_slens[idxs[i]] = 1;
|
||||
f += inc;
|
||||
}
|
||||
if ((inc = errtxtf_dpad(f))) {
|
||||
memcpy(dpads[idxs[i]], f + 1, inc - 1); /* TODO: keep `dpads` separate else last mentioned trumps */
|
||||
dpads[idxs[i]][inc - 1] = '\0';
|
||||
f += inc;
|
||||
}
|
||||
if (*f != 'c' && *f != 'd' && *f != 'f' && *f != 'g' && *f != 's') {
|
||||
if (!(symbol->debug & ZINT_DEBUG_TEST)) assert(0);
|
||||
return errtxt(ZINT_ERROR_ENCODING_PROBLEM, symbol, 0,
|
||||
"Internal error: unknown format specifier ('%c','%d','%f','%g','%s' only)");
|
||||
}
|
||||
specs[idxs[i++]] = *f;
|
||||
arg_cnt++;
|
||||
}
|
||||
}
|
||||
if (have_num_arg && have_unnum_arg) {
|
||||
if (!(symbol->debug & ZINT_DEBUG_TEST)) assert(0);
|
||||
return errtxt(ZINT_ERROR_ENCODING_PROBLEM, symbol, 0,
|
||||
"Internal error: mixed numbered and unnumbered format specifiers");
|
||||
}
|
||||
|
||||
/* Get arguments */
|
||||
va_start(ap, fmt);
|
||||
for (i = 0; i < arg_cnt; i++) {
|
||||
if (specs[i] == 'c') {
|
||||
cs[i] = va_arg(ap, int);
|
||||
} else if (specs[i] == 'd') {
|
||||
if (dpads[i][0]) {
|
||||
char dpad_fmt[30]; /* Make 30 to suppress gcc 14 "-Wformat-overflow=" false positive */
|
||||
sprintf(dpad_fmt, "%%0%sd", dpads[i]); /* TODO: keep `dpads` separate else last mentioned trumps */
|
||||
sprintf(dfgs[i], dpad_fmt, va_arg(ap, int));
|
||||
} else {
|
||||
sprintf(dfgs[i], "%d", va_arg(ap, int));
|
||||
}
|
||||
} else if (specs[i] == 'f' || specs[i] == 'g') {
|
||||
sprintf(dfgs[i], specs[i] == 'f' ? "%f" : "%g", va_arg(ap, double));
|
||||
} else if (specs[i] == 's') {
|
||||
if (have_slens[i] && slens[i] == -1) {
|
||||
slens[i] = va_arg(ap, int); /* TODO: keep `slens` separate else last mentioned trumps */
|
||||
}
|
||||
ss[i] = va_arg(ap, char *);
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
/* Populate `errtxt` */
|
||||
for (f = fmt, i = 0; *f && p < max_len; f++) {
|
||||
if (*f == '%') {
|
||||
int idx;
|
||||
if (*++f == '%') {
|
||||
symbol->errtxt[p++] = '%';
|
||||
continue;
|
||||
}
|
||||
f += errtxtf_num_arg(f, NULL /*p_arg*/);
|
||||
f += errtxtf_slen(f, -1 /*arg*/, NULL /*arg_cnt*/, NULL /*p_len*/);
|
||||
f += errtxtf_dpad(f);
|
||||
idx = idxs[i];
|
||||
if (specs[idx] == 'c') {
|
||||
symbol->errtxt[p++] = cs[idx];
|
||||
} else {
|
||||
int len;
|
||||
if (specs[idx] == 's') {
|
||||
if (have_slens[idx]) {
|
||||
const char *si = ss[idx];
|
||||
for (len = 0; len < slens[idx] && si[len]; len++);
|
||||
} else {
|
||||
len = (int) strlen(ss[idx]);
|
||||
}
|
||||
} else {
|
||||
len = (int) strlen(dfgs[idx]);
|
||||
}
|
||||
if (len) {
|
||||
if (p + len > max_len) {
|
||||
if (!(symbol->debug & ZINT_DEBUG_TEST)) assert(0); /* Catch truncations */
|
||||
len = max_len - p;
|
||||
}
|
||||
memcpy(symbol->errtxt + p, specs[idx] == 's' ? ss[idx] : dfgs[idx], len);
|
||||
p += len;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} else {
|
||||
symbol->errtxt[p++] = *f;
|
||||
}
|
||||
}
|
||||
if (*f) {
|
||||
if (!(symbol->debug & ZINT_DEBUG_TEST)) assert(0); /* Catch truncations */
|
||||
}
|
||||
|
||||
symbol->errtxt[p] = '\0';
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Helper to prepend/append to existing `symbol->errtxt` by calling `errtxtf(fmt)` with 2 arguments (copy of `errtxt`
|
||||
& `msg`) if `msg` not NULL, or 1 argument (just copy of `errtxt`) if `msg` NULL, returning `error_number` */
|
||||
INTERNAL int errtxt_adj(const int error_number, struct zint_symbol *symbol, const char *fmt, const char *msg) {
|
||||
char err_buf[sizeof(symbol->errtxt)];
|
||||
|
||||
err_buf[0] = '\0';
|
||||
|
||||
/* Suppress gcc 14 warning output may be truncated */
|
||||
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 14
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
#endif
|
||||
|
||||
strncat(err_buf, symbol->errtxt, sizeof(symbol->errtxt) - 1);
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 14
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
if (msg) {
|
||||
errtxtf(0, symbol, -1, fmt, err_buf, msg);
|
||||
} else {
|
||||
errtxtf(0, symbol, -1, fmt, err_buf);
|
||||
}
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Whether `symbology` can have row binding */
|
||||
INTERNAL int is_stackable(const int symbology) {
|
||||
if (symbology < BARCODE_PHARMA_TWO && symbology != BARCODE_POSTNET) {
|
||||
@ -487,7 +779,7 @@ INTERNAL int hrt_cpy_iso8859_1(struct zint_symbol *symbol, const unsigned char s
|
||||
symbol->text[j] = '\0';
|
||||
|
||||
if (warn_number) {
|
||||
strcpy(symbol->errtxt, "249: Human Readable Text truncated");
|
||||
errtxt(0, symbol, 249, "Human Readable Text truncated");
|
||||
}
|
||||
return warn_number;
|
||||
}
|
||||
@ -530,7 +822,7 @@ INTERNAL int set_height(struct zint_symbol *symbol, const float min_row_height,
|
||||
if (stripf(row_height) < stripf(min_row_height)) {
|
||||
error_number = ZINT_WARN_NONCOMPLIANT;
|
||||
if (!no_errtxt) {
|
||||
strcpy(symbol->errtxt, "247: Height not compliant with standards");
|
||||
errtxt(0, symbol, 247, "Height not compliant with standards");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -542,7 +834,7 @@ INTERNAL int set_height(struct zint_symbol *symbol, const float min_row_height,
|
||||
if (stripf(symbol->height) > stripf(max_height)) {
|
||||
error_number = ZINT_WARN_NONCOMPLIANT;
|
||||
if (!no_errtxt) {
|
||||
strcpy(symbol->errtxt, "248: Height not compliant with standards");
|
||||
errtxt(0, symbol, 248, "Height not compliant with standards");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -551,14 +843,16 @@ INTERNAL int set_height(struct zint_symbol *symbol, const float min_row_height,
|
||||
}
|
||||
|
||||
/* Prevent inlining of `stripf()` which can optimize away its effect */
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__attribute__((__noinline__))
|
||||
#endif
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1310 /* MSVC 2003 (VC++ 7.1) */
|
||||
__declspec(noinline)
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#define ZINT_NOINLINE __attribute__((__noinline__))
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1310 /* MSVC 2003 (VC++ 7.1) */
|
||||
#define ZINT_NOINLINE __declspec(noinline)
|
||||
#else
|
||||
#define ZINT_NOINLINE
|
||||
#endif
|
||||
|
||||
/* Removes excess precision from floats - see https://stackoverflow.com/q/503436 */
|
||||
INTERNAL float stripf(const float arg) {
|
||||
INTERNAL ZINT_NOINLINE float stripf(const float arg) {
|
||||
return *((volatile const float *) &arg);
|
||||
}
|
||||
|
||||
@ -590,25 +884,44 @@ INTERNAL void segs_cpy(const struct zint_symbol *symbol, const struct zint_seg s
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for ZINT_DEBUG_PRINT to put all but graphical ASCII in angle brackets */
|
||||
/* Helper for ZINT_DEBUG_PRINT to put all but graphical ASCII in hex escapes. Output to `buf` if non-NULL, else
|
||||
stdout */
|
||||
INTERNAL char *debug_print_escape(const unsigned char *source, const int first_len, char *buf) {
|
||||
int i, j = 0;
|
||||
for (i = 0; i < first_len; i++) {
|
||||
const unsigned char ch = source[i];
|
||||
if (ch < 32 || ch >= 127) {
|
||||
j += sprintf(buf + j, "<%03o>", ch & 0xFF);
|
||||
} else {
|
||||
buf[j++] = ch;
|
||||
int i;
|
||||
if (buf) {
|
||||
int j = 0;
|
||||
for (i = 0; i < first_len; i++) {
|
||||
const unsigned char ch = source[i];
|
||||
if (ch < 32 || ch >= 127) {
|
||||
j += sprintf(buf + j, "\\x%02X", ch & 0xFF);
|
||||
} else {
|
||||
buf[j++] = ch;
|
||||
}
|
||||
}
|
||||
buf[j] = '\0';
|
||||
} else {
|
||||
for (i = 0; i < first_len; i++) {
|
||||
const unsigned char ch = source[i];
|
||||
if (ch < 32 || ch >= 127) {
|
||||
printf("\\x%02X", ch & 0xFF);
|
||||
} else {
|
||||
fputc(ch, stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
buf[j] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef ZINT_TEST
|
||||
/* Suppress gcc warning null destination pointer [-Wformat-overflow=] false-positive */
|
||||
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 7
|
||||
#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;
|
||||
assert(sizeof(symbol->errtxt) >= 100);
|
||||
if (length > 30) { /* 30*3 < errtxt 92 (100 - "Warning ") chars */
|
||||
sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */
|
||||
cnt_len = (int) strlen(symbol->errtxt);
|
||||
@ -624,6 +937,7 @@ INTERNAL void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigne
|
||||
INTERNAL void debug_test_codeword_dump_short(struct zint_symbol *symbol, const short *codewords, const int length) {
|
||||
int i, max = 0, cnt_len, errtxt_len;
|
||||
char temp[20];
|
||||
assert(sizeof(symbol->errtxt) >= 100);
|
||||
errtxt_len = sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */
|
||||
for (i = 0, cnt_len = errtxt_len; i < length; i++) {
|
||||
cnt_len += sprintf(temp, "%d ", codewords[i]);
|
||||
@ -642,6 +956,7 @@ INTERNAL void debug_test_codeword_dump_short(struct zint_symbol *symbol, const s
|
||||
INTERNAL void debug_test_codeword_dump_int(struct zint_symbol *symbol, const int *codewords, const int length) {
|
||||
int i, max = 0, cnt_len, errtxt_len;
|
||||
char temp[20];
|
||||
assert(sizeof(symbol->errtxt) >= 100);
|
||||
errtxt_len = sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */
|
||||
for (i = 0, cnt_len = errtxt_len; i < length; i++) {
|
||||
cnt_len += sprintf(temp, "%d ", codewords[i]);
|
||||
@ -655,6 +970,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__) && __GNUC__ >= 7
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif /* ZINT_TEST */
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
259
backend/common.h
@ -1,7 +1,7 @@
|
||||
/* common.h - Header for all common functions in common.c */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -37,23 +37,16 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) ((int) (sizeof(x) / sizeof((x)[0])))
|
||||
#endif
|
||||
#include "zint.h"
|
||||
#include "zintconfig.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* 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
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <malloc.h>
|
||||
# define z_alloca(nmemb) _alloca(nmemb)
|
||||
#else
|
||||
# if defined(ZINT_IS_C89) || defined(__NuttX__) /* C89 or NuttX RTOS */
|
||||
# include <alloca.h>
|
||||
#ifndef _MSC_VER
|
||||
# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199000L
|
||||
# define ZINT_IS_C89
|
||||
# endif
|
||||
# define z_alloca(nmemb) alloca(nmemb)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -63,10 +56,111 @@ typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <stdint.h> /* Introduced C99 */
|
||||
#endif
|
||||
|
||||
/* `is_sane()` flags */
|
||||
/* Note if change following must also change "frontend/main.c" copy */
|
||||
|
||||
#define ARRAY_SIZE(x) ((int) (sizeof(x) / sizeof((x)[0])))
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <malloc.h>
|
||||
# define z_alloca(nmemb) _alloca(nmemb)
|
||||
#elif defined(__COMPCERT__)
|
||||
# define z_alloca(nmemb) malloc(nmemb) /* So links - leads to loads of leaks obs */
|
||||
#else
|
||||
# if (defined(__GNUC__) && !defined(alloca) && !defined(__NetBSD__)) || defined(__NuttX__) || defined(_AIX) \
|
||||
|| (defined(__sun) && defined(__SVR4) /*Solaris*/)
|
||||
# include <alloca.h>
|
||||
# endif
|
||||
# define z_alloca(nmemb) alloca(nmemb)
|
||||
#endif
|
||||
|
||||
/* End of "frontend/main.c" copy */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable: 4125) /* decimal digit terminates octal escape sequence */
|
||||
# pragma warning(disable: 4244) /* conversion from int to float */
|
||||
# if _MSC_VER > 1200 /* VC6 */
|
||||
# pragma warning(disable: 4996) /* function or variable may be unsafe */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
# define ZINT_FORMAT_PRINTF(fmt_idx, first_idx) __attribute__((__format__(printf, fmt_idx, first_idx)))
|
||||
#else
|
||||
# define ZINT_FORMAT_PRINTF(fmt_idx, first_idx)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(ZINT_TEST) && !defined(__MINGW32__)
|
||||
# define INTERNAL __attribute__((__visibility__("hidden")))
|
||||
#elif defined(ZINT_TEST)
|
||||
# define INTERNAL ZINT_EXTERN /* The test suite references INTERNAL functions, so they need to be exported */
|
||||
#else
|
||||
# define INTERNAL
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
|
||||
# define INTERNAL_DATA_EXTERN __attribute__((__visibility__("hidden"))) extern
|
||||
# define INTERNAL_DATA __attribute__((__visibility__("hidden")))
|
||||
#else
|
||||
# define INTERNAL_DATA_EXTERN extern
|
||||
# define INTERNAL_DATA
|
||||
#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
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER <= 1200) || defined(ZINT_IS_C89) /* VC6 or C89 */
|
||||
# define ceilf (float) ceil
|
||||
# define floorf (float) floor
|
||||
# define fmodf (float) fmod
|
||||
#endif
|
||||
/* `round()` (C99) not before MSVC 2013 (C++ 12.0) */
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1800) || defined(ZINT_IS_C89)
|
||||
# define round(arg) floor((arg) + 0.5)
|
||||
# define roundf(arg) floorf((arg) + 0.5f)
|
||||
#endif
|
||||
|
||||
/* Is float integral value? (https://stackoverflow.com/a/40404149) */
|
||||
#define isfintf(arg) (fmodf(arg, 1.0f) == 0.0f)
|
||||
|
||||
/* Simple versions of <ctype.h> functions with no dependence on locale */
|
||||
#define z_isdigit(c) ((c) <= '9' && (c) >= '0')
|
||||
#define z_isupper(c) ((c) >= 'A' && (c) <= 'Z')
|
||||
#define z_islower(c) ((c) >= 'a' && (c) <= 'z')
|
||||
|
||||
/* Helpers to cast away char pointer signedness */
|
||||
#define ustrlen(source) strlen((const char *) (source))
|
||||
#define ustrcpy(target, source) strcpy((char *) (target), (const char *) (source))
|
||||
#define ustrcat(target, source) strcat((char *) (target), (const char *) (source))
|
||||
#define ustrncat(target, source, count) strncat((char *) (target), (const char *) (source), (count))
|
||||
|
||||
/* Converts a character 0-9, A-F to its equivalent integer value */
|
||||
INTERNAL int ctoi(const char source);
|
||||
|
||||
/* Converts an integer value to its hexadecimal character */
|
||||
INTERNAL char itoc(const int source);
|
||||
|
||||
/* Converts decimal string of length <= 9 to integer value. Returns -1 if not numeric */
|
||||
INTERNAL int to_int(const unsigned char source[], const int length);
|
||||
|
||||
/* Converts lower case characters to upper case in string `source` */
|
||||
INTERNAL void to_upper(unsigned char source[], const int length);
|
||||
|
||||
/* Returns the number of times a character occurs in `source` */
|
||||
INTERNAL int chr_cnt(const unsigned char source[], const int length, const unsigned char c);
|
||||
|
||||
/* `is_chr()` & `not_sane()` flags */
|
||||
#define IS_SPC_F 0x0001 /* Space */
|
||||
#define IS_HSH_F 0x0002 /* Hash sign # */
|
||||
#define IS_AST_F 0x0004 /* Asterisk sign * */
|
||||
@ -90,99 +184,15 @@ typedef unsigned __int64 uint64_t;
|
||||
/* The most commonly used set */
|
||||
#define NEON_F IS_NUM_F /* NEON "0123456789" */
|
||||
|
||||
/* Simple versions of <ctype.h> functions with no dependence on locale */
|
||||
#define z_isdigit(c) ((c) <= '9' && (c) >= '0')
|
||||
#define z_isupper(c) ((c) >= 'A' && (c) <= 'Z')
|
||||
#define z_islower(c) ((c) >= 'a' && (c) <= 'z')
|
||||
|
||||
#include "zint.h"
|
||||
#include "zintconfig.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Helpers to cast away char pointer signedness */
|
||||
#define ustrlen(source) strlen((const char *) (source))
|
||||
#define ustrcpy(target, source) strcpy((char *) (target), (const char *) (source))
|
||||
#define ustrcat(target, source) strcat((char *) (target), (const char *) (source))
|
||||
#define ustrncat(target, source, count) strncat((char *) (target), (const char *) (source), (count))
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER == 1200) || defined(ZINT_IS_C89) /* VC6 or C89 */
|
||||
# define ceilf (float) ceil
|
||||
# define floorf (float) floor
|
||||
# define fmodf (float) fmod
|
||||
#endif
|
||||
/* `round()` (C99) not before MSVC 2013 (C++ 12.0) */
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1800) || defined(ZINT_IS_C89)
|
||||
# define round(arg) floor((arg) + 0.5)
|
||||
# define roundf(arg) floorf((arg) + 0.5f)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable: 4244) /* conversion from int to float */
|
||||
# if _MSC_VER != 1200 /* VC6 */
|
||||
# pragma warning(disable: 4996) /* function or variable may be unsafe */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Is float integral value? (https://stackoverflow.com/a/40404149) */
|
||||
#define isfintf(arg) (fmodf(arg, 1.0f) == 0.0f)
|
||||
|
||||
#if (defined(__GNUC__) || defined(__clang__)) && !defined(ZINT_TEST) && !defined(__MINGW32__)
|
||||
# define INTERNAL __attribute__ ((visibility ("hidden")))
|
||||
#elif defined(ZINT_TEST)
|
||||
# define INTERNAL ZINT_EXTERN /* The test suite references INTERNAL functions, so they need to be exported */
|
||||
#else
|
||||
# define INTERNAL
|
||||
#endif
|
||||
|
||||
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MINGW32__)
|
||||
# define INTERNAL_DATA_EXTERN __attribute__ ((visibility ("hidden"))) extern
|
||||
# define INTERNAL_DATA __attribute__ ((visibility ("hidden")))
|
||||
#else
|
||||
# define INTERNAL_DATA_EXTERN extern
|
||||
# define INTERNAL_DATA
|
||||
#endif
|
||||
|
||||
#define Z_COMMON_INLINE 1
|
||||
|
||||
#ifdef Z_COMMON_INLINE
|
||||
/* Returns true (1) if a module is dark/black, otherwise false (0) */
|
||||
# define module_is_set(s, y, x) (((s)->encoded_data[(y)][(x) >> 3] >> ((x) & 0x07)) & 1)
|
||||
|
||||
/* Sets a module to dark/black */
|
||||
# define set_module(s, y, x) do { (s)->encoded_data[(y)][(x) >> 3] |= 1 << ((x) & 0x07); } while (0)
|
||||
|
||||
/* Returns true (1-8) if a module is colour, otherwise false (0) */
|
||||
# define module_colour_is_set(s, y, x) ((s)->encoded_data[(y)][(x)])
|
||||
|
||||
/* Sets a module to a colour */
|
||||
# define set_module_colour(s, y, x, c) do { (s)->encoded_data[(y)][(x)] = (c); } while (0)
|
||||
#endif
|
||||
|
||||
/* Converts a character 0-9, A-F to its equivalent integer value */
|
||||
INTERNAL int ctoi(const char source);
|
||||
|
||||
/* Converts an integer value to its hexadecimal character */
|
||||
INTERNAL char itoc(const int source);
|
||||
|
||||
/* Converts decimal string of length <= 9 to integer value. Returns -1 if not numeric */
|
||||
INTERNAL int to_int(const unsigned char source[], const int length);
|
||||
|
||||
/* Converts lower case characters to upper case in string `source` */
|
||||
INTERNAL void to_upper(unsigned char source[], const int length);
|
||||
|
||||
/* Returns the number of times a character occurs in `source` */
|
||||
INTERNAL int chr_cnt(const unsigned char source[], const int length, const unsigned char c);
|
||||
|
||||
|
||||
/* Whether a character matches `flg` */
|
||||
INTERNAL int is_chr(const unsigned int flg, const unsigned int c);
|
||||
|
||||
/* Verifies that a string only uses valid characters */
|
||||
INTERNAL int is_sane(const unsigned int flg, const unsigned char source[], const int length);
|
||||
/* Verifies if a string only uses valid characters, returning 1-based position in `source` if not, 0 for success */
|
||||
INTERNAL int not_sane(const unsigned int flg, const unsigned char source[], const int length);
|
||||
|
||||
/* Verifies that a string only uses valid characters, and returns `test_string` position of each in `posns` array */
|
||||
INTERNAL int is_sane_lookup(const char test_string[], const int test_length, const unsigned char source[],
|
||||
/* Verifies if a string only uses valid characters as above, but also returns `test_string` position of each in
|
||||
`posns` array */
|
||||
INTERNAL int not_sane_lookup(const char test_string[], const int test_length, const unsigned char source[],
|
||||
const int length, int *posns);
|
||||
|
||||
/* Returns the position of `data` in `set_string` */
|
||||
@ -194,7 +204,18 @@ INTERNAL int posn(const char set_string[], const char data);
|
||||
INTERNAL int bin_append_posn(const int arg, const int length, char *binary, const int bin_posn);
|
||||
|
||||
|
||||
#ifndef Z_COMMON_INLINE
|
||||
#define Z_COMMON_INLINE 1
|
||||
|
||||
#ifdef Z_COMMON_INLINE
|
||||
|
||||
# define module_is_set(s, y, x) (((s)->encoded_data[y][(x) >> 3] >> ((x) & 0x07)) & 1)
|
||||
# define set_module(s, y, x) do { (s)->encoded_data[y][(x) >> 3] |= 1 << ((x) & 0x07); } while (0)
|
||||
# define module_colour_is_set(s, y, x) ((s)->encoded_data[y][x])
|
||||
# define set_module_colour(s, y, x, c) do { (s)->encoded_data[y][x] = (c); } while (0)
|
||||
# define unset_module(s, y, x) do { (s)->encoded_data[y][(x) >> 3] &= ~(1 << ((x) & 0x07)); } while (0)
|
||||
|
||||
#else /* Z_COMMON_INLINE */
|
||||
|
||||
/* Returns true (1) if a module is dark/black, otherwise false (0) */
|
||||
INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord);
|
||||
|
||||
@ -207,14 +228,34 @@ INTERNAL int module_colour_is_set(const struct zint_symbol *symbol, const int y_
|
||||
/* Sets a module to a colour */
|
||||
INTERNAL void set_module_colour(struct zint_symbol *symbol, const int y_coord, const int x_coord,
|
||||
const int colour);
|
||||
#endif
|
||||
|
||||
/* Sets a dark/black module to white (i.e. unsets) */
|
||||
INTERNAL void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord);
|
||||
|
||||
#endif /* Z_COMMON_INLINE */
|
||||
|
||||
|
||||
/* Expands from a width pattern to a bit pattern */
|
||||
INTERNAL void expand(struct zint_symbol *symbol, const char data[], const int length);
|
||||
|
||||
|
||||
/* Set `symbol->errtxt` to "err_id: msg", returning `error_number`. If `err_id` is -1, the "err_id: " prefix is
|
||||
omitted */
|
||||
INTERNAL int errtxt(const int error_number, struct zint_symbol *symbol, const int err_id, const char *msg);
|
||||
|
||||
/* Set `symbol->errtxt` to "err_id: msg" with restricted subset of `printf()` formatting, returning `error_number`.
|
||||
If `err_id` is -1, the "err_id: " prefix is omitted. Only the following specifiers are supported: "c", "d", "f",
|
||||
"g" and "s", with no modifiers apart from "<n>$" numbering for l10n ("<n>" 1-9), in which case all specifiers must
|
||||
be numbered, "%s" with length precisions: "%.*s", "%<n+1>$.*<n>$s", "%.<p>s" and "%<n>$.<p>s", and "%d" with
|
||||
zero-padded minimum field lengths: "%0<m>d" or %<n>$0<m>d" ("<m>" 1-99) */
|
||||
INTERNAL int errtxtf(const int error_number, struct zint_symbol *symbol, const int err_id, const char *fmt, ...)
|
||||
ZINT_FORMAT_PRINTF(4, 5);
|
||||
|
||||
/* Helper to prepend/append to existing `symbol->errtxt` by calling `errtxtf(fmt)` with 2 arguments (copy of `errtxt`
|
||||
& `msg`) if `msg` not NULL, or 1 argument (just copy of `errtxt`) if `msg` NULL, returning `error_number` */
|
||||
INTERNAL int errtxt_adj(const int error_number, struct zint_symbol *symbol, const char *fmt, const char *msg);
|
||||
|
||||
|
||||
/* Whether `symbology` can have row binding */
|
||||
INTERNAL int is_stackable(const int symbology);
|
||||
|
||||
@ -272,6 +313,8 @@ INTERNAL void segs_cpy(const struct zint_symbol *symbol, const struct zint_seg s
|
||||
struct zint_seg local_segs[]);
|
||||
|
||||
|
||||
/* Helper for ZINT_DEBUG_PRINT to put all but graphical ASCII in hex escapes. Output to `buf` if non-NULL, else
|
||||
stdout */
|
||||
INTERNAL char *debug_print_escape(const unsigned char *source, const int first_len, char *buf);
|
||||
|
||||
#ifdef ZINT_TEST
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* composite.c - Handles GS1 Composite Symbols */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -56,7 +56,6 @@
|
||||
#include "gs1.h"
|
||||
#include "general_field.h"
|
||||
|
||||
#define UINT unsigned short
|
||||
#include "composite.h"
|
||||
|
||||
INTERNAL int gs1_128_cc(struct zint_symbol *symbol, unsigned char source[], int length, const int cc_mode,
|
||||
@ -73,7 +72,7 @@ INTERNAL int dbar_ltd_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int length, const int cc_rows);
|
||||
INTERNAL int dbar_date(const unsigned char source[], const int length, const int src_posn);
|
||||
|
||||
static int _min(const int first, const int second) {
|
||||
static int cc_min(const int first, const int second) {
|
||||
|
||||
if (first <= second)
|
||||
return first;
|
||||
@ -82,23 +81,23 @@ static int _min(const int first, const int second) {
|
||||
}
|
||||
|
||||
/* gets bit in bitString at bitPos */
|
||||
static int getBit(const UINT *bitStr, const int bitPos) {
|
||||
static int cc_getBit(const unsigned short *bitStr, const int bitPos) {
|
||||
return !!(bitStr[bitPos >> 4] & (0x8000 >> (bitPos & 15)));
|
||||
}
|
||||
|
||||
/* converts bit string to base 928 values, codeWords[0] is highest order */
|
||||
static int encode928(const UINT bitString[], UINT codeWords[], const int bitLng) {
|
||||
static int cc_encode928(const unsigned short bitString[], unsigned short codeWords[], const int bitLng) {
|
||||
int i, j, b, cwNdx, cwLng;
|
||||
for (cwNdx = cwLng = b = 0; b < bitLng; b += 69, cwNdx += 7) {
|
||||
const int bitCnt = _min(bitLng - b, 69);
|
||||
const int bitCnt = cc_min(bitLng - b, 69);
|
||||
int cwCnt;
|
||||
cwLng += cwCnt = bitCnt / 10 + 1;
|
||||
for (i = 0; i < cwCnt; i++)
|
||||
codeWords[cwNdx + i] = 0; /* init 0 */
|
||||
for (i = 0; i < bitCnt; i++) {
|
||||
if (getBit(bitString, b + bitCnt - i - 1)) {
|
||||
if (cc_getBit(bitString, b + bitCnt - i - 1)) {
|
||||
for (j = 0; j < cwCnt; j++)
|
||||
codeWords[cwNdx + j] += pwr928[i][j + 7 - cwCnt];
|
||||
codeWords[cwNdx + j] += cc_pwr928[i][j + 7 - cwCnt];
|
||||
}
|
||||
}
|
||||
for (i = cwCnt - 1; i > 0; i--) {
|
||||
@ -117,8 +116,8 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w
|
||||
int LeftRAPStart, RightRAPStart, CentreRAPStart, StartCluster;
|
||||
int LeftRAP, RightRAP, CentreRAP, Cluster;
|
||||
int loop;
|
||||
UINT codeWords[28] = {0};
|
||||
UINT bitStr[13] = {0};
|
||||
unsigned short codeWords[28] = {0};
|
||||
unsigned short bitStr[13] = {0};
|
||||
char pattern[580];
|
||||
int bp = 0;
|
||||
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
|
||||
@ -140,7 +139,7 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w
|
||||
}
|
||||
|
||||
/* encode codeWords from bitStr */
|
||||
cwCnt = encode928(bitStr, codeWords, bitlen);
|
||||
cwCnt = cc_encode928(bitStr, codeWords, bitlen);
|
||||
|
||||
switch (cc_width) {
|
||||
case 2:
|
||||
@ -191,9 +190,9 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w
|
||||
break;
|
||||
}
|
||||
|
||||
rows = ccaVariants[variant];
|
||||
k = ccaVariants[17 + variant];
|
||||
offset = ccaVariants[34 + variant];
|
||||
rows = cc_aVariants[variant];
|
||||
k = cc_aVariants[17 + variant];
|
||||
offset = cc_aVariants[34 + variant];
|
||||
|
||||
/* Reed-Solomon error correction */
|
||||
|
||||
@ -201,9 +200,9 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w
|
||||
total = (codeWords[i] + rsCodeWords[k - 1]) % 929;
|
||||
for (j = k - 1; j >= 0; j--) {
|
||||
if (j == 0) {
|
||||
rsCodeWords[j] = (929 - (total * ccaCoeffs[offset + j]) % 929) % 929;
|
||||
rsCodeWords[j] = (929 - (total * cc_aCoeffs[offset + j]) % 929) % 929;
|
||||
} else {
|
||||
rsCodeWords[j] = (rsCodeWords[j - 1] + 929 - (total * ccaCoeffs[offset + j]) % 929) % 929;
|
||||
rsCodeWords[j] = (rsCodeWords[j - 1] + 929 - (total * cc_aCoeffs[offset + j]) % 929) % 929;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -220,10 +219,10 @@ static void cc_a(struct zint_symbol *symbol, const char source[], const int cc_w
|
||||
}
|
||||
|
||||
/* Place data into table */
|
||||
LeftRAPStart = aRAPTable[variant];
|
||||
CentreRAPStart = aRAPTable[variant + 17];
|
||||
RightRAPStart = aRAPTable[variant + 34];
|
||||
StartCluster = aRAPTable[variant + 51] / 3;
|
||||
LeftRAPStart = cc_aRAPTable[variant];
|
||||
CentreRAPStart = cc_aRAPTable[variant + 17];
|
||||
RightRAPStart = cc_aRAPTable[variant + 34];
|
||||
StartCluster = cc_aRAPTable[variant + 51] / 3;
|
||||
|
||||
LeftRAP = LeftRAPStart;
|
||||
CentreRAP = CentreRAPStart;
|
||||
@ -326,7 +325,7 @@ static void cc_b(struct zint_symbol *symbol, const char source[], const int cc_w
|
||||
/* "the CC-B component shall have codeword 920 in the first symbol character position" (section 9a) */
|
||||
chainemc[mclength++] = 920;
|
||||
|
||||
pdf_byteprocess(chainemc, &mclength, data_string, 0, length, 0, debug_print);
|
||||
pdf_byteprocess(chainemc, &mclength, data_string, 0, length, 0);
|
||||
|
||||
/* Now figure out which variant of the symbol to use and load values accordingly */
|
||||
|
||||
@ -540,7 +539,7 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w
|
||||
chainemc[mclength++] = 0; /* space for length descriptor */
|
||||
chainemc[mclength++] = 920; /* CC-C identifier */
|
||||
|
||||
pdf_byteprocess(chainemc, &mclength, data_string, 0, length, 0, debug_print);
|
||||
pdf_byteprocess(chainemc, &mclength, data_string, 0, length, 0);
|
||||
|
||||
chainemc[0] = mclength;
|
||||
|
||||
@ -652,7 +651,7 @@ static void cc_c(struct zint_symbol *symbol, const char source[], const int cc_w
|
||||
}
|
||||
}
|
||||
|
||||
static int calc_padding_cca(const int binary_length, const int cc_width) {
|
||||
static int cc_a_calc_padding(const int binary_length, const int cc_width) {
|
||||
int target_bitsize = 0;
|
||||
|
||||
switch (cc_width) {
|
||||
@ -704,7 +703,7 @@ static int calc_padding_cca(const int binary_length, const int cc_width) {
|
||||
return target_bitsize;
|
||||
}
|
||||
|
||||
static int calc_padding_ccb(const int binary_length, const int cc_width) {
|
||||
static int cc_b_calc_padding(const int binary_length, const int cc_width) {
|
||||
int target_bitsize = 0;
|
||||
|
||||
switch (cc_width) {
|
||||
@ -778,7 +777,7 @@ static int calc_padding_ccb(const int binary_length, const int cc_width) {
|
||||
return target_bitsize;
|
||||
}
|
||||
|
||||
static int calc_padding_ccc(const int binary_length, int *p_cc_width, const int linear_width, int *p_ecc_level) {
|
||||
static int cc_c_calc_padding(const int binary_length, int *p_cc_width, const int linear_width, int *p_ecc_level) {
|
||||
int target_bitsize = 0;
|
||||
int byte_length, codewords_used, ecc_level, ecc_codewords, rows;
|
||||
int codewords_total, target_codewords, target_bytesize;
|
||||
@ -944,7 +943,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour
|
||||
do {
|
||||
ninety[i] = source[i + 2];
|
||||
i++;
|
||||
} while ((length > i + 2) && ('[' != source[i + 2]));
|
||||
} while (i + 2 < length && source[i + 2] != '\x1D');
|
||||
}
|
||||
ninety[i] = '\0';
|
||||
ninety_len = i;
|
||||
@ -1014,7 +1013,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour
|
||||
|
||||
next_ai_posn = 2 + ninety_len;
|
||||
|
||||
if (next_ai_posn < length && source[next_ai_posn] == '[') {
|
||||
if (next_ai_posn < length && source[next_ai_posn] == '\x1D') {
|
||||
/* There are more AIs afterwards */
|
||||
if (next_ai_posn + 2 < length
|
||||
&& (source[next_ai_posn + 1] == '2') && (source[next_ai_posn + 2] == '1')) {
|
||||
@ -1075,12 +1074,12 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour
|
||||
} else if (z_isdigit(source[read_posn])) {
|
||||
bp = bin_append_posn(source[read_posn] + 4, 6, binary_string, bp);
|
||||
|
||||
} else if (source[read_posn] == '[') {
|
||||
} else if (source[read_posn] == '\x1D') {
|
||||
bp = bin_append_posn(31, 5, binary_string, bp);
|
||||
}
|
||||
|
||||
read_posn++;
|
||||
} while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0'));
|
||||
} while (source[read_posn - 1] != '\x1D' && source[read_posn - 1] != '\0');
|
||||
alpha_pad = 1; /* This is overwritten if a general field is encoded */
|
||||
}
|
||||
|
||||
@ -1103,7 +1102,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour
|
||||
if (fnc1_latch == 1) {
|
||||
/* Encodation method "10" has been used but it is not followed by
|
||||
AI 10, so a FNC1 character needs to be added */
|
||||
general_field[j] = '[';
|
||||
general_field[j] = '\x1D';
|
||||
j++;
|
||||
}
|
||||
|
||||
@ -1129,26 +1128,24 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour
|
||||
|
||||
if (!general_field_encode(general_field, j, &mode, &last_digit, binary_string, &bp)) {
|
||||
/* Invalid character in input data */
|
||||
strcpy(symbol->errtxt, "441: Invalid character in input data");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 441, "Invalid character in input (2D component)");
|
||||
}
|
||||
}
|
||||
|
||||
switch (cc_mode) {
|
||||
case 1:
|
||||
target_bitsize = calc_padding_cca(bp, *p_cc_width);
|
||||
target_bitsize = cc_a_calc_padding(bp, *p_cc_width);
|
||||
break;
|
||||
case 2:
|
||||
target_bitsize = calc_padding_ccb(bp, *p_cc_width);
|
||||
target_bitsize = cc_b_calc_padding(bp, *p_cc_width);
|
||||
break;
|
||||
case 3:
|
||||
target_bitsize = calc_padding_ccc(bp, p_cc_width, linear_width, p_ecc_level);
|
||||
target_bitsize = cc_c_calc_padding(bp, p_cc_width, linear_width, p_ecc_level);
|
||||
break;
|
||||
}
|
||||
|
||||
if (target_bitsize == 0) {
|
||||
strcpy(symbol->errtxt, "442: Input too long for selected 2D component");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 442, "Input too long (2D component)");
|
||||
}
|
||||
|
||||
remainder = target_bitsize - bp;
|
||||
@ -1173,19 +1170,18 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour
|
||||
|
||||
switch (cc_mode) {
|
||||
case 1:
|
||||
target_bitsize = calc_padding_cca(bp, *p_cc_width);
|
||||
target_bitsize = cc_a_calc_padding(bp, *p_cc_width);
|
||||
break;
|
||||
case 2:
|
||||
target_bitsize = calc_padding_ccb(bp, *p_cc_width);
|
||||
target_bitsize = cc_b_calc_padding(bp, *p_cc_width);
|
||||
break;
|
||||
case 3:
|
||||
target_bitsize = calc_padding_ccc(bp, p_cc_width, linear_width, p_ecc_level);
|
||||
target_bitsize = cc_c_calc_padding(bp, p_cc_width, linear_width, p_ecc_level);
|
||||
break;
|
||||
}
|
||||
|
||||
if (target_bitsize == 0) {
|
||||
strcpy(symbol->errtxt, "444: Input too long for selected 2D component");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 444, "Input too long (2D component)");
|
||||
}
|
||||
|
||||
if (bp < target_bitsize) {
|
||||
@ -1214,7 +1210,8 @@ static int cc_binary_string(struct zint_symbol *symbol, const unsigned char sour
|
||||
}
|
||||
|
||||
/* Calculate the width of the linear part (primary) */
|
||||
static int linear_dummy_run(int input_mode, unsigned char *source, const int length, const int debug, char *errtxt) {
|
||||
static int cc_linear_dummy_run(int input_mode, unsigned char *source, const int length, const int debug,
|
||||
char *errtxt) {
|
||||
struct zint_symbol dummy = {0};
|
||||
int error_number;
|
||||
int linear_width;
|
||||
@ -1235,8 +1232,6 @@ static int linear_dummy_run(int input_mode, unsigned char *source, const int len
|
||||
return linear_width;
|
||||
}
|
||||
|
||||
static const char in_linear_comp[] = " in linear component";
|
||||
|
||||
INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int error_number, cc_mode, cc_width = 0, ecc_level = 0;
|
||||
int j, i, k;
|
||||
@ -1255,31 +1250,28 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
error_number = 0;
|
||||
pri_len = (int) strlen(symbol->primary);
|
||||
if (pri_len == 0) {
|
||||
strcpy(symbol->errtxt, "445: No primary (linear) message");
|
||||
return ZINT_ERROR_INVALID_OPTION; /* TODO: change to more appropiate ZINT_ERROR_INVALID_DATA */
|
||||
/* TODO: change to more appropiate ZINT_ERROR_INVALID_DATA */
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 445, "No primary (linear) message");
|
||||
}
|
||||
|
||||
if (length > 2990) {
|
||||
strcpy(symbol->errtxt, "446: 2D component input data too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 446,
|
||||
"2D component input too long, requires %d characters (maximum 2990)", length);
|
||||
}
|
||||
|
||||
cc_mode = symbol->option_1;
|
||||
if ((cc_mode == 3) && (symbol->symbology != BARCODE_GS1_128_CC)) {
|
||||
/* CC-C can only be used with a GS1-128 linear part */
|
||||
strcpy(symbol->errtxt, "447: Invalid mode (CC-C only valid with GS1-128 linear component)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 447,
|
||||
"Invalid mode (CC-C only valid with GS1-128 linear component)");
|
||||
}
|
||||
|
||||
if (symbol->symbology == BARCODE_GS1_128_CC) {
|
||||
/* Do a test run of encoding the linear component to establish its width */
|
||||
linear_width = linear_dummy_run(symbol->input_mode, (unsigned char *) symbol->primary, pri_len,
|
||||
symbol->debug, symbol->errtxt);
|
||||
linear_width = cc_linear_dummy_run(symbol->input_mode, (unsigned char *) symbol->primary, pri_len,
|
||||
symbol->debug, symbol->errtxt);
|
||||
if (linear_width == 0) {
|
||||
if (strlen(symbol->errtxt) + strlen(in_linear_comp) < sizeof(symbol->errtxt)) {
|
||||
strcat(symbol->errtxt, in_linear_comp);
|
||||
}
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt_adj(ZINT_ERROR_INVALID_DATA, symbol, "%1$s%2$s", " (linear component)");
|
||||
}
|
||||
if (debug_print) {
|
||||
printf("GS1-128 linear width: %d\n", linear_width);
|
||||
@ -1294,10 +1286,8 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
int with_addon;
|
||||
unsigned char padded_pri[21];
|
||||
if (!ean_leading_zeroes(symbol, (unsigned char *) symbol->primary, padded_pri, &with_addon, NULL,
|
||||
NULL)) {
|
||||
sprintf(symbol->errtxt, "448: Input too long (%s) in linear component",
|
||||
with_addon ? "5 character maximum for add-on" : "13 character maximum");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
NULL)) {
|
||||
return errtxt_adj(ZINT_ERROR_TOO_LONG, symbol, "%1$s%2$s", " (linear component)");
|
||||
}
|
||||
padded_pri_len = (int) ustrlen(padded_pri);
|
||||
if (padded_pri_len <= 7) { /* EAN-8 */
|
||||
@ -1321,8 +1311,7 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
}
|
||||
}
|
||||
if (cc_width == 0) {
|
||||
strcpy(symbol->errtxt, "449: Input wrong length in linear component");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 449, "Input length %d wrong (linear component)", pri_len);
|
||||
}
|
||||
break;
|
||||
case BARCODE_GS1_128_CC: cc_width = 4;
|
||||
@ -1444,10 +1433,7 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
}
|
||||
|
||||
if (error_number) {
|
||||
strcpy(symbol->errtxt, linear->errtxt);
|
||||
if (strlen(symbol->errtxt) + strlen(in_linear_comp) < sizeof(symbol->errtxt)) {
|
||||
strcat(symbol->errtxt, in_linear_comp);
|
||||
}
|
||||
errtxtf(0, symbol, -1, "%1$s%2$s", linear->errtxt, " (linear component)");
|
||||
if (error_number >= ZINT_ERROR) {
|
||||
ZBarcode_Delete(linear);
|
||||
return error_number;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* composite.c - Tables for UCC.EAN Composite Symbols */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -34,7 +34,7 @@
|
||||
#define Z_COMPOSITE_H
|
||||
|
||||
/* CC-A component coefficients from ISO/IEC 24728:2006 Annex F */
|
||||
static const unsigned short ccaCoeffs[30] = {
|
||||
static const unsigned short cc_aCoeffs[30] = {
|
||||
/* k = 4 */
|
||||
522, 568, 723, 809,
|
||||
|
||||
@ -42,34 +42,34 @@ static const unsigned short ccaCoeffs[30] = {
|
||||
427, 919, 460, 155, 566,
|
||||
|
||||
/* k = 6 */
|
||||
861, 285, 19, 803, 17, 766,
|
||||
861, 285, 19, 803, 17, 766,
|
||||
|
||||
/* k = 7 */
|
||||
76, 925, 537, 597, 784, 691, 437,
|
||||
76, 925, 537, 597, 784, 691, 437,
|
||||
|
||||
/* k = 8 */
|
||||
237, 308, 436, 284, 646, 653, 428, 379
|
||||
};
|
||||
|
||||
/* rows, error codewords, k-offset of valid CC-A sizes from ISO/IEC 24723:2006 Table 9 */
|
||||
static const char ccaVariants[51] = {
|
||||
5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7,
|
||||
4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8,
|
||||
0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9, 15, 22
|
||||
static const char cc_aVariants[51] = {
|
||||
5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7,
|
||||
4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8,
|
||||
0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9, 15, 22
|
||||
};
|
||||
|
||||
/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24723:2006 tables 10 and 11 */
|
||||
static const char aRAPTable[68] = {
|
||||
39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29,
|
||||
0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 26, 14, 9,
|
||||
19, 33, 12, 40, 46, 23, 52, 23, 13, 17, 27, 33, 52, 3, 6, 46, 41,
|
||||
6, 0, 3, 3, 3, 0, 3, 3, 0, 3, 6, 6, 0, 0, 0, 0, 3
|
||||
static const char cc_aRAPTable[68] = {
|
||||
39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29,
|
||||
0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 26, 14, 9,
|
||||
19, 33, 12, 40, 46, 23, 52, 23, 13, 17, 27, 33, 52, 3, 6, 46, 41,
|
||||
6, 0, 3, 3, 3, 0, 3, 3, 0, 3, 6, 6, 0, 0, 0, 0, 3
|
||||
};
|
||||
|
||||
/* Row Address Patterns are as defined in pdf417.h */
|
||||
|
||||
/* Generated by tools/gen_pwr928_table.php */
|
||||
static const UINT pwr928[69][7] = {
|
||||
static const unsigned short cc_pwr928[69][7] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 1, },
|
||||
{ 0, 0, 0, 0, 0, 0, 2, },
|
||||
{ 0, 0, 0, 0, 0, 0, 4, },
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* dmatrix.c Handles Data Matrix ECC 200 symbols */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
developed from and including some functions from:
|
||||
IEC16022 bar code generation
|
||||
@ -224,8 +224,8 @@ static int dm_isX12(const unsigned char input) {
|
||||
}
|
||||
|
||||
/* Return true (1) if a character is valid in EDIFACT set */
|
||||
static int dm_isedifact(const unsigned char input, const int gs1) {
|
||||
return (input >= ' ' && input <= '^') && (!gs1 || input != '['); /* Can't encode GS1 FNC1/GS in EDIFACT */
|
||||
static int dm_isedifact(const unsigned char input) {
|
||||
return input >= ' ' && input <= '^';
|
||||
}
|
||||
|
||||
/* Does Annex J section (r)(6)(ii)(I) apply? */
|
||||
@ -367,7 +367,7 @@ static int dm_look_ahead_test(const unsigned char source[], const int length, co
|
||||
}
|
||||
|
||||
/* edifact ... step (p) */
|
||||
if (dm_isedifact(c, gs1)) {
|
||||
if (dm_isedifact(c)) {
|
||||
edf_count += DM_MULT_3_DIV_4; /* (p)(1) */
|
||||
} else {
|
||||
if (is_extended) {
|
||||
@ -378,7 +378,7 @@ static int dm_look_ahead_test(const unsigned char source[], const int length, co
|
||||
}
|
||||
|
||||
/* base 256 ... step (q) */
|
||||
if ((gs1 == 1) && (c == '[')) {
|
||||
if (gs1 == 1 && c == '\x1D') {
|
||||
/* FNC1 separator */
|
||||
b256_count += DM_MULT_4; /* (q)(1) */
|
||||
} else {
|
||||
@ -617,7 +617,7 @@ static int dm_codewords_remaining(struct zint_symbol *symbol, const int tp, cons
|
||||
static int dm_c40text_cnt(const int current_mode, const int gs1, unsigned char input) {
|
||||
int cnt;
|
||||
|
||||
if (gs1 && input == '[') {
|
||||
if (gs1 && input == '\x1D') {
|
||||
return 2;
|
||||
}
|
||||
cnt = 1;
|
||||
@ -683,7 +683,7 @@ static int dm_switch_mode(const int next_mode, unsigned char target[], int tp, i
|
||||
|
||||
#define DM_NUM_MODES 6
|
||||
|
||||
static const char *dm_smodes[] = { "?", "ASCII", "C40", "TEXT", "X12", "EDF", "B256" };
|
||||
static const char dm_smodes[DM_NUM_MODES + 1][6] = { "?", "ASCII", "C40", "TEXT", "X12", "EDF", "B256" };
|
||||
|
||||
/* The size of this structure could be significantly reduced using techniques pointed out by Alex Geller,
|
||||
but not done currently to avoid the processing overhead */
|
||||
@ -930,7 +930,7 @@ static void dm_addEdges(struct zint_symbol *symbol, const unsigned char source[]
|
||||
/* Not possible to unlatch a full EDF edge to something else */
|
||||
if (previous == NULL || previous->endMode != DM_EDIFACT) {
|
||||
|
||||
static const int c40text_modes[] = { DM_C40, DM_TEXT };
|
||||
static const char c40text_modes[] = { DM_C40, DM_TEXT };
|
||||
|
||||
if (z_isdigit(source[from]) && from + 1 < length && z_isdigit(source[from + 1])) {
|
||||
dm_addEdge(symbol, source, length, edges, DM_ASCII, from, 2, previous, 0);
|
||||
@ -954,15 +954,15 @@ static void dm_addEdges(struct zint_symbol *symbol, const unsigned char source[]
|
||||
dm_addEdge(symbol, source, length, edges, DM_X12, from, 3, previous, 0);
|
||||
}
|
||||
|
||||
if (gs1 != 1 || source[from] != '[') {
|
||||
if (gs1 != 1 || source[from] != '\x1D') {
|
||||
dm_addEdge(symbol, source, length, edges, DM_BASE256, from, 1, previous, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (dm_isedifact(source[from], gs1)) {
|
||||
if (dm_isedifact(source[from])) {
|
||||
/* We create 3 EDF edges, 2, 3 or 4 characters length. The 4-char normally doesn't have a latch to ASCII
|
||||
unless it is 2 characters away from the end of the input. */
|
||||
for (i = 1, pos = from + i; i < 4 && pos < length && dm_isedifact(source[pos], gs1); i++, pos++) {
|
||||
for (i = 1, pos = from + i; i < 4 && pos < length && dm_isedifact(source[pos]); i++, pos++) {
|
||||
dm_addEdge(symbol, source, length, edges, DM_EDIFACT, from, i + 1, previous, 0);
|
||||
}
|
||||
}
|
||||
@ -1059,8 +1059,7 @@ static int dm_minimalenc(struct zint_symbol *symbol, const unsigned char source[
|
||||
assert(length <= 10921); /* Can only handle (10921 + 1) * 6 = 65532 < 65536 (2*16) due to sizeof(previous) */
|
||||
|
||||
if (!dm_define_mode(symbol, modes, source, length, gs1, debug_print)) {
|
||||
strcpy(symbol->errtxt, "728: Insufficient memory for mode buffers");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 728, "Insufficient memory for mode buffers");
|
||||
}
|
||||
|
||||
while (sp < length) {
|
||||
@ -1116,7 +1115,7 @@ static int dm_minimalenc(struct zint_symbol *symbol, const unsigned char source[
|
||||
target[tp++] = (source[sp] - 128) + 1;
|
||||
if (debug_print) printf("FN4 A%02X ", target[tp - 1] - 1);
|
||||
} else {
|
||||
if (gs1 && (source[sp] == '[')) {
|
||||
if (gs1 && source[sp] == '\x1D') {
|
||||
if (gs1 == 2) {
|
||||
target[tp++] = 29 + 1; /* GS */
|
||||
if (debug_print) fputs("GS ", stdout);
|
||||
@ -1151,7 +1150,7 @@ static int dm_minimalenc(struct zint_symbol *symbol, const unsigned char source[
|
||||
shift_set = ct_shift[source[sp] - 128];
|
||||
value = ct_value[source[sp] - 128];
|
||||
} else {
|
||||
if (gs1 && (source[sp] == '[')) {
|
||||
if (gs1 && source[sp] == '\x1D') {
|
||||
if (gs1 == 2) {
|
||||
shift_set = ct_shift[29];
|
||||
value = ct_value[29]; /* GS */
|
||||
@ -1212,18 +1211,13 @@ static int dm_minimalenc(struct zint_symbol *symbol, const unsigned char source[
|
||||
|
||||
} else if (current_mode == DM_BASE256) {
|
||||
|
||||
if (gs1 == 2 && source[sp] == '[') {
|
||||
target[tp++] = 29; /* GS */
|
||||
} else {
|
||||
target[tp++] = source[sp];
|
||||
}
|
||||
sp++;
|
||||
target[tp++] = source[sp++];
|
||||
if (debug_print) printf("B%02X ", target[tp - 1]);
|
||||
}
|
||||
|
||||
if (tp > 1558) {
|
||||
strcpy(symbol->errtxt, "729: Data too long to fit in symbol");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 729,
|
||||
"Input too long, requires too many codewords (maximum 1558)");
|
||||
}
|
||||
|
||||
} /* while */
|
||||
@ -1292,7 +1286,7 @@ static int dm_isoenc(struct zint_symbol *symbol, const unsigned char source[], c
|
||||
target[tp++] = (source[sp] - 128) + 1;
|
||||
if (debug_print) printf("FN4 A%02X ", target[tp - 1] - 1);
|
||||
} else {
|
||||
if (gs1 && (source[sp] == '[')) {
|
||||
if (gs1 && source[sp] == '\x1D') {
|
||||
if (gs1 == 2) {
|
||||
target[tp++] = 29 + 1; /* GS */
|
||||
if (debug_print) fputs("GS ", stdout);
|
||||
@ -1339,7 +1333,7 @@ static int dm_isoenc(struct zint_symbol *symbol, const unsigned char source[], c
|
||||
shift_set = ct_shift[source[sp] - 128];
|
||||
value = ct_value[source[sp] - 128];
|
||||
} else {
|
||||
if (gs1 && (source[sp] == '[')) {
|
||||
if (gs1 && source[sp] == '\x1D') {
|
||||
if (gs1 == 2) {
|
||||
shift_set = ct_shift[29];
|
||||
value = ct_value[29]; /* GS */
|
||||
@ -1407,7 +1401,7 @@ static int dm_isoenc(struct zint_symbol *symbol, const unsigned char source[], c
|
||||
/* step (f) EDIFACT encodation */
|
||||
} else if (current_mode == DM_EDIFACT) {
|
||||
|
||||
if (!dm_isedifact(source[sp], gs1)) {
|
||||
if (!dm_isedifact(source[sp])) {
|
||||
next_mode = DM_ASCII;
|
||||
} else {
|
||||
next_mode = DM_EDIFACT;
|
||||
@ -1443,7 +1437,7 @@ static int dm_isoenc(struct zint_symbol *symbol, const unsigned char source[], c
|
||||
/* step (g) Base 256 encodation */
|
||||
} else if (current_mode == DM_BASE256) {
|
||||
|
||||
if (gs1 == 1 && source[sp] == '[') {
|
||||
if (gs1 == 1 && source[sp] == '\x1D') {
|
||||
next_mode = DM_ASCII;
|
||||
} else {
|
||||
next_mode = DM_BASE256;
|
||||
@ -1464,7 +1458,7 @@ static int dm_isoenc(struct zint_symbol *symbol, const unsigned char source[], c
|
||||
tp = dm_switch_mode(next_mode, target, tp, p_b256_start, debug_print);
|
||||
not_first = 0;
|
||||
} else {
|
||||
if (gs1 == 2 && source[sp] == '[') {
|
||||
if (gs1 == 2 && source[sp] == '\x1D') {
|
||||
target[tp++] = 29; /* GS */
|
||||
} else {
|
||||
target[tp++] = source[sp];
|
||||
@ -1476,8 +1470,8 @@ static int dm_isoenc(struct zint_symbol *symbol, const unsigned char source[], c
|
||||
}
|
||||
|
||||
if (tp > 1558) {
|
||||
strcpy(symbol->errtxt, "520: Data too long to fit in symbol");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 520,
|
||||
"Input too long, requires too many codewords (maximum 1558)");
|
||||
}
|
||||
|
||||
} /* while */
|
||||
@ -1587,7 +1581,7 @@ static int dm_encode(struct zint_symbol *symbol, const unsigned char source[], c
|
||||
target[tp++] = 235; /* FNC4 */
|
||||
target[tp++] = (source[sp] - 128) + 1;
|
||||
if (debug_print) printf("FN4 A%02X ", target[tp - 1] - 1);
|
||||
} else if (gs1 && source[sp] == '[') {
|
||||
} else if (gs1 && source[sp] == '\x1D') {
|
||||
if (gs1 == 2) {
|
||||
target[tp++] = 29 + 1; /* GS */
|
||||
if (debug_print) fputs("GS ", stdout);
|
||||
@ -1687,21 +1681,21 @@ static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co
|
||||
const struct zint_seg *last_seg = &segs[seg_count - 1];
|
||||
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
|
||||
|
||||
if (segs_length(segs, seg_count) > 3116) { /* Max is 3166 digits */
|
||||
strcpy(symbol->errtxt, "719: Data too long to fit in symbol");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
if ((i = segs_length(segs, seg_count)) > 3116) { /* Max is 3166 digits */
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 719, "Input length %d too long (maximum 3116)", i);
|
||||
}
|
||||
|
||||
if (symbol->structapp.count) {
|
||||
int id1, id2;
|
||||
|
||||
if (symbol->structapp.count < 2 || symbol->structapp.count > 16) {
|
||||
strcpy(symbol->errtxt, "720: Structured Append count out of range (2-16)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 720,
|
||||
"Structured Append count '%d' out of range (2 to 16)", symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
|
||||
sprintf(symbol->errtxt, "721: Structured Append index out of range (1-%d)", symbol->structapp.count);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 721,
|
||||
"Structured Append index '%1$d' out of range (1 to count %2$d)",
|
||||
symbol->structapp.index, symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.id[0]) {
|
||||
int id, id_len, id1_err, id2_err;
|
||||
@ -1709,14 +1703,13 @@ static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co
|
||||
for (id_len = 1; id_len < 7 && symbol->structapp.id[id_len]; id_len++);
|
||||
|
||||
if (id_len > 6) { /* ID1 * 1000 + ID2 */
|
||||
strcpy(symbol->errtxt, "722: Structured Append ID too long (6 digit maximum)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 722,
|
||||
"Structured Append ID length %d too long (6 digit maximum)", id_len);
|
||||
}
|
||||
|
||||
id = to_int((const unsigned char *) symbol->structapp.id, id_len);
|
||||
if (id == -1) {
|
||||
strcpy(symbol->errtxt, "723: Invalid Structured Append ID (digits only)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 723, "Invalid Structured Append ID (digits only)");
|
||||
}
|
||||
id1 = id / 1000;
|
||||
id2 = id % 1000;
|
||||
@ -1724,19 +1717,19 @@ static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co
|
||||
id2_err = id2 < 1 || id2 > 254;
|
||||
if (id1_err || id2_err) {
|
||||
if (id1_err && id2_err) {
|
||||
sprintf(symbol->errtxt,
|
||||
"724: Structured Append ID1 '%03d' and ID2 '%03d' out of range (001-254) (ID '%03d%03d')",
|
||||
id1, id2, id1, id2);
|
||||
} else if (id1_err) {
|
||||
sprintf(symbol->errtxt,
|
||||
"725: Structured Append ID1 '%03d' out of range (001-254) (ID '%03d%03d')",
|
||||
id1, id1, id2);
|
||||
} else {
|
||||
sprintf(symbol->errtxt,
|
||||
"726: Structured Append ID2 '%03d' out of range (001-254) (ID '%03d%03d')",
|
||||
id2, id1, id2);
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 724,
|
||||
"Structured Append ID1 '%1$03d' and ID2 '%2$03d' out of range (001 to 254)"
|
||||
" (ID \"%3$03d%4$03d\")",
|
||||
id1, id2, id1, id2);
|
||||
}
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
if (id1_err) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 725,
|
||||
"Structured Append ID1 '%1$03d' out of range (001 to 254) (ID \"%2$03d%3$03d\")",
|
||||
id1, id1, id2);
|
||||
}
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 726,
|
||||
"Structured Append ID2 '%1$03d' out of range (001 to 254) (ID \"%2$03d%3$03d\")",
|
||||
id2, id1, id2);
|
||||
}
|
||||
} else {
|
||||
id1 = id2 = 1;
|
||||
@ -1766,12 +1759,11 @@ static int dm_encode_segs(struct zint_symbol *symbol, struct zint_seg segs[], co
|
||||
|
||||
if (symbol->output_options & READER_INIT) {
|
||||
if (gs1) {
|
||||
strcpy(symbol->errtxt, "521: Cannot encode in GS1 mode and Reader Initialisation at the same time");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 521, "Cannot use Reader Initialisation in GS1 mode");
|
||||
}
|
||||
if (symbol->structapp.count) {
|
||||
strcpy(symbol->errtxt, "727: Cannot have Structured Append and Reader Initialisation at the same time");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 727,
|
||||
"Cannot have Structured Append and Reader Initialisation at the same time");
|
||||
}
|
||||
target[tp++] = 234; /* Reader Programming */
|
||||
if (debug_print) fputs("RP ", stdout);
|
||||
@ -1842,7 +1834,7 @@ static void dm_add_tail(unsigned char target[], int tp, const int tail_length) {
|
||||
static int dm_ecc200(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
|
||||
int i, skew = 0;
|
||||
unsigned char binary[2200];
|
||||
int binlen;
|
||||
int binlen = 0; /* Suppress clang-tidy-20 uninitialized value false positive */
|
||||
int symbolsize;
|
||||
int taillength, error_number;
|
||||
int H, W, FH, FW, datablock, bytes, rsblock;
|
||||
@ -1859,11 +1851,12 @@ static int dm_ecc200(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
if (binlen > dm_matrixbytes[symbolsize]) {
|
||||
if ((symbol->option_2 >= 1) && (symbol->option_2 <= DMSIZESCOUNT)) {
|
||||
/* The symbol size was given by --ver (option_2) */
|
||||
strcpy(symbol->errtxt, "522: Input too long for selected symbol size");
|
||||
} else {
|
||||
strcpy(symbol->errtxt, "523: Data too long to fit in symbol");
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 522,
|
||||
"Input too long for Version %1$d, requires %2$d codewords (maximum %3$d)",
|
||||
symbol->option_2, binlen, dm_matrixbytes[symbolsize]);
|
||||
}
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 523, "Input too long, requires %d codewords (maximum 1558)",
|
||||
binlen);
|
||||
}
|
||||
|
||||
H = dm_matrixH[symbolsize];
|
||||
@ -1886,7 +1879,7 @@ static int dm_ecc200(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
}
|
||||
|
||||
/* ecc code */
|
||||
if (symbolsize == INTSYMBOL144 && !(symbol->option_3 & DM_ISO_144)) {
|
||||
if (symbolsize == DMINTSYMBOL144 && !(symbol->option_3 & DM_ISO_144)) {
|
||||
skew = 1;
|
||||
}
|
||||
dm_ecc(binary, bytes, datablock, rsblock, skew);
|
||||
@ -1906,8 +1899,7 @@ static int dm_ecc200(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
const int NR = H - 2 * (H / FH);
|
||||
int x, y, *places;
|
||||
if (!(places = (int *) calloc(NC * NR, sizeof(int)))) {
|
||||
strcpy(symbol->errtxt, "718: Insufficient memory for placement array");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 718, "Insufficient memory for placement array");
|
||||
}
|
||||
dm_placement(places, NR, NC);
|
||||
for (y = 0; y < H; y += FH) {
|
||||
@ -1955,18 +1947,13 @@ static int dm_ecc200(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
}
|
||||
|
||||
INTERNAL int datamatrix(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
|
||||
int error_number;
|
||||
|
||||
if (symbol->option_1 <= 1) {
|
||||
/* ECC 200 */
|
||||
error_number = dm_ecc200(symbol, segs, seg_count);
|
||||
} else {
|
||||
/* ECC 000 - 140 */
|
||||
strcpy(symbol->errtxt, "524: Older Data Matrix standards are no longer supported");
|
||||
error_number = ZINT_ERROR_INVALID_OPTION;
|
||||
return dm_ecc200(symbol, segs, seg_count);
|
||||
}
|
||||
|
||||
return error_number;
|
||||
/* ECC 000 - 140 */
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 524, "Older Data Matrix standards are no longer supported");
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* dmatrix.h - Handles Data Matrix ECC 200 */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -46,198 +46,211 @@
|
||||
#define DM_EDIFACT 5
|
||||
#define DM_BASE256 6
|
||||
|
||||
static const char dm_c40_shift[] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
|
||||
/* C40 shift to use per ASCII character (Table C.1) */
|
||||
static const char dm_c40_shift[128] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
|
||||
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
|
||||
};
|
||||
|
||||
static const char dm_c40_value[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||||
15, 16, 17, 18, 19, 20, 21, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
22, 23, 24, 25, 26, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
|
||||
/* C40 ASCII values (Table C.1) */
|
||||
static const char dm_c40_value[128] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20,
|
||||
21, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 22, 23, 24, 25, 26,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
|
||||
};
|
||||
|
||||
static const char dm_text_shift[] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3
|
||||
/* Text shift to use per ASCII character (Table C.2) */
|
||||
static const char dm_text_shift[128] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2,
|
||||
3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3
|
||||
};
|
||||
|
||||
static const char dm_text_value[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||||
15, 16, 17, 18, 19, 20, 21, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
|
||||
22, 23, 24, 25, 26, 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 27, 28, 29, 30, 31
|
||||
};
|
||||
|
||||
/* Position in option array [symbol option value - 1]
|
||||
The position in the option array is by increasing total data codewords with square first
|
||||
The last comment value is the total data codewords value.
|
||||
The index of this array is the --vers parameter value -1 and is given as first comment value */
|
||||
|
||||
static const unsigned short dm_intsymbol[] = {
|
||||
/* Standard DM */
|
||||
0, /* 1: 10x10 , 3*/ 1, /* 2: 12x12 , 5*/ 3, /* 3: 14x14 , 8*/ 5, /* 4: 16x16 , 12*/
|
||||
7, /* 5: 18x18 , 18*/ 9, /* 6: 20x20 , 22*/ 12, /* 7: 22x22 , 30*/ 15, /* 8: 24x24 , 36*/
|
||||
18, /* 9: 26x26 , 44*/ 23, /* 10: 32x32 , 62*/ 31, /* 11: 36x36 , 86*/ 34, /* 12: 40x40 ,114*/
|
||||
36, /* 13: 44x44 ,144*/ 37, /* 14: 48x48 ,174*/ 38, /* 15: 52x52 ,204*/ 39, /* 16: 64x64 ,280*/
|
||||
40, /* 17: 72x72 ,368*/ 41, /* 18: 80x80 ,456*/ 42, /* 19: 88x88 ,576*/ 43, /* 20: 96x96 ,696*/
|
||||
44, /* 21:104x104,816*/ 45, /* 22:120x120,1050*/46, /* 23:132x132,1304*/47, /* 24:144x144,1558*/
|
||||
2, /* 25: 8x18 , 5*/ 4, /* 26: 8x32 , 10*/ 6, /* 27: 12x26 , 16*/ 10, /* 28: 12x36 , 22*/
|
||||
13, /* 29: 16x36 , 32*/ 20, /* 30: 16x48 , 49*/
|
||||
/* DMRE */
|
||||
8, /* 31: 8x48 , 18*/ 11, /* 32: 8x64 , 24*/ 14, /* 33: 8x80 , 32*/ 16, /* 34: 8x96 , 38*/
|
||||
21, /* 35: 8x120, 49*/ 25, /* 36: 8x144, 63*/ 17, /* 37: 12x64 , 43*/ 26, /* 38: 12x88 , 64*/
|
||||
24, /* 39: 16x64 , 62*/ 19, /* 40: 20x36 , 44*/ 22, /* 41: 20x44 , 56*/ 30, /* 42: 20x64 , 84*/
|
||||
28, /* 43: 22x48 , 72*/ 29, /* 44: 24x48 , 80*/ 33, /* 45: 24x64 ,108*/ 27, /* 46: 26x40 , 70*/
|
||||
32, /* 47: 26x48 , 90*/ 35, /* 48: 26x64 ,118*/
|
||||
/* Text ASCII values (Table C.2) */
|
||||
static const char dm_text_value[128] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20,
|
||||
21, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 22, 23, 24, 25, 26,
|
||||
0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 27, 28, 29, 30, 31
|
||||
};
|
||||
|
||||
/* Number of DM Sizes */
|
||||
#define DMSIZESCOUNT 48
|
||||
/* Number of 144x144 for special interlace */
|
||||
#define INTSYMBOL144 47
|
||||
#define DMINTSYMBOL144 47
|
||||
|
||||
/* Is the current code a DMRE code ?
|
||||
This is the case, if dm_intsymbol index >= 30 */
|
||||
/* Total data codewords (Table 7) in ascending order */
|
||||
static const unsigned short dm_matrixbytes[DMSIZESCOUNT] = {
|
||||
/* 0*/ 3 /*10x10*/, 5 /*12x12*/, 5 /*8x18*/, 8 /*14x14*/,
|
||||
/* 4*/ 10 /*8x32*/, 12 /*16x16*/, 16 /*12x26*/, 18 /*18x18*/,
|
||||
/* 8*/ 18 /*8x48*/, 22 /*20x20*/, 22 /*12x36*/, 24 /*8x64*/,
|
||||
/*12*/ 30 /*22x22*/, 32 /*16x36*/, 32 /*8x80*/, 36 /*24x24*/,
|
||||
/*16*/ 38 /*8x96*/, 43 /*12x64*/, 44 /*26x26*/, 44 /*20x36*/,
|
||||
/*20*/ 49 /*16x48*/, 49 /*8x120*/, 56 /*20x44*/, 62 /*32x32*/,
|
||||
/*24*/ 62 /*16x64*/, 63 /*8x144*/, 64 /*12x88*/, 70 /*26x40*/,
|
||||
/*28*/ 72 /*22x48*/, 80 /*24x48*/, 84 /*20x64*/, 86 /*36x36*/,
|
||||
/*32*/ 90 /*26x48*/, 108 /*24x64*/, 114 /*40x40*/, 118 /*26x64*/,
|
||||
/*36*/ 144 /*44x44*/, 174 /*48x48*/, 204 /*52x52*/, 280 /*64x64*/,
|
||||
/*40*/ 368 /*72x72*/, 456 /*80x80*/, 576 /*88x88*/, 696 /*96x96*/,
|
||||
/*44*/ 816 /*104x104*/, 1050 /*120x120*/, 1304 /*132x132*/, 1558 /*144x144*/
|
||||
};
|
||||
|
||||
static const char dm_isDMRE[] = {
|
||||
/* 0*/ 0, /* 10x10, 3*/ 0, /* 12x12 , 5*/ 0, /* 8x18 , 5*/ 0, /* 14x14 , 8*/
|
||||
/* 4*/ 0, /* 8x32 , 10*/ 0, /* 16x16 , 12*/ 0, /* 12x26 , 16*/ 0, /* 18x18 , 18*/
|
||||
/* 8*/ 1, /* 8x48 , 18*/ 0, /* 20x20 , 22*/ 0, /* 12x36 , 22*/ 1, /* 8x64 , 24*/
|
||||
/*12*/ 0, /* 22x22 , 30*/ 0, /* 16x36 , 32*/ 1, /* 8x80 , 32*/ 0, /* 24x24 , 36*/
|
||||
/*16*/ 1, /* 8x96 , 38*/ 1, /* 12x64 , 43*/ 0, /* 26x26 , 44*/ 1, /* 20x36 , 44*/
|
||||
/*20*/ 0, /* 16x48 , 49*/ 1, /* 8x120, 49*/ 1, /* 20x44 , 56*/ 0, /* 32x32 , 62*/
|
||||
/*24*/ 1, /* 16x64 , 62*/ 1, /* 8x144, 63*/ 1, /* 12x88 , 64*/ 1, /* 26x40 , 70*/
|
||||
/*28*/ 1, /* 22x48 , 72*/ 1, /* 24x48 , 80*/ 1, /* 20x64 , 84*/ 0, /* 36x36 , 86*/
|
||||
/*32*/ 1, /* 26x48 , 90*/ 1, /* 24x64 ,108*/ 0, /* 40x40 ,114*/ 1, /* 26x64 ,118*/
|
||||
/*36*/ 0, /* 44x44 ,144*/ 0, /* 48x48 ,174*/ 0, /* 52x52 ,204*/ 0, /* 64x64 ,280*/
|
||||
/*40*/ 0, /* 72x72 ,368*/ 0, /* 80x80 ,456*/ 0, /* 88x88 ,576*/ 0, /* 96x96 ,696*/
|
||||
/*44*/ 0, /*104x104,816*/ 0, /*120x120,1050*/0, /*132x132,1304*/0 /*144x144,1558*/
|
||||
/* Index into `dm_matrixbytes` array in `symbol->option_2` (CLI `--vers`) order,
|
||||
i.e. square symbols first, then standard rectangular, then DMRE.
|
||||
The bracketed comment value is the total data codewords value. */
|
||||
static const unsigned char dm_intsymbol[DMSIZESCOUNT] = {
|
||||
/* Standard DM square */
|
||||
/* 1-4*/ 0 /*10x10 (3)*/, 1 /*12x12 (5)*/, 3 /*14x14 (8)*/, 5 /*16x16 (12)*/,
|
||||
/* 5-8*/ 7 /*18x18 (18)*/, 9 /*20x20 (22)*/, 12 /*22x22 (30)*/, 15 /*24x24 (36)*/,
|
||||
/* 9-12*/ 18 /*26x26 (44)*/, 23 /*32x32 (62)*/, 31 /*36x36 (86)*/, 34 /*40x40 (114)*/,
|
||||
/*13-16*/ 36 /*44x44 (144)*/, 37 /*48x48 (174)*/, 38 /*52x52 (204)*/, 39 /*64x64 (280)*/,
|
||||
/*17-20*/ 40 /*72x72 (368)*/, 41 /*80x80 (456)*/, 42 /*88x88 (576)*/, 43 /*96x96 (696)*/,
|
||||
/*21-24*/ 44 /*104x104 (816)*/, 45 /*120x120 (1050)*/, 46 /*132x132 (1304)*/, 47 /*144x144 (1558)*/,
|
||||
|
||||
/* Standard DM rectangular */
|
||||
/*25-28*/ 2 /*8x18 (5)*/, 4 /*8x32 (10)*/, 6 /*12x26 (16)*/, 10 /*12x36 (22)*/,
|
||||
/*29-30*/ 13 /*16x36 (32)*/, 20 /*16x48 (49)*/,
|
||||
|
||||
/* DMRE */
|
||||
/*31-34*/ 8 /*8x48 (18)*/, 11 /*8x64 (24)*/, 14 /*8x80 (32)*/, 16 /*8x96 (38)*/,
|
||||
/*35-38*/ 21 /*8x120 (49)*/, 25 /*8x144 (63)*/, 17 /*12x64 (43)*/, 26 /*12x88 (64)*/,
|
||||
/*39-42*/ 24 /*16x64 (62)*/, 19 /*20x36 (44)*/, 22 /*20x44 (56)*/, 30 /*20x64 (84)*/,
|
||||
/*43-46*/ 28 /*22x48 (72)*/, 29 /*24x48 (80)*/, 33 /*24x64 (108)*/, 27 /*26x40 (70)*/,
|
||||
/*47-48*/ 32 /*26x48 (90)*/, 35 /*26x64 (118)*/
|
||||
};
|
||||
|
||||
/* Following arrays in total data codewords order (`dm_matrixbytes`) */
|
||||
|
||||
/* Whether the version is DMRE */
|
||||
static const char dm_isDMRE[DMSIZESCOUNT] = {
|
||||
/* 0*/ 0 /*10x10 (3)*/, 0 /*12x12 (5)*/, 0 /*8x18 (5)*/, 0 /*14x14 (8)*/,
|
||||
/* 4*/ 0 /*8x32 (10)*/, 0 /*16x16 (12)*/, 0 /*12x26 (16)*/, 0 /*18x18 (18)*/,
|
||||
/* 8*/ 1 /*8x48 (18)*/, 0 /*20x20 (22)*/, 0 /*12x36 (22)*/, 1 /*8x64 (24)*/,
|
||||
/*12*/ 0 /*22x22 (30)*/, 0 /*16x36 (32)*/, 1 /*8x80 (32)*/, 0 /*24x24 (36)*/,
|
||||
/*16*/ 1 /*8x96 (38)*/, 1 /*12x64 (43)*/, 0 /*26x26 (44)*/, 1 /*20x36 (44)*/,
|
||||
/*20*/ 0 /*16x48 (49)*/, 1 /*8x120 (49)*/, 1 /*20x44 (56)*/, 0 /*32x32 (62)*/,
|
||||
/*24*/ 1 /*16x64 (62)*/, 1 /*8x144 (63)*/, 1 /*12x88 (64)*/, 1 /*26x40 (70)*/,
|
||||
/*28*/ 1 /*22x48 (72)*/, 1 /*24x48 (80)*/, 1 /*20x64 (84)*/, 0 /*36x36 (86)*/,
|
||||
/*32*/ 1 /*26x48 (90)*/, 1 /*24x64 (108)*/, 0 /*40x40 (114)*/, 1 /*26x64 (118)*/,
|
||||
/*36*/ 0 /*44x44 (144)*/, 0 /*48x48 (174)*/, 0 /*52x52 (204)*/, 0 /*64x64 (280)*/,
|
||||
/*40*/ 0 /*72x72 (368)*/, 0 /*80x80 (456)*/, 0 /*88x88 (576)*/, 0 /*96x96 (696)*/,
|
||||
/*44*/ 0 /*104x104 (816)*/, 0 /*120x120 (1050)*/, 0 /*132x132 (1304)*/, 0 /*144x144 (1558)*/
|
||||
};
|
||||
|
||||
/* Horizontal matrix size */
|
||||
|
||||
static const unsigned short dm_matrixH[] = {
|
||||
/* 0*/ 10, /* 10x10 , 3*/ 12, /* 12x12 , 5 */ 8, /* 8x18 , 5*/ 14, /* 14x14 , 8*/
|
||||
/* 4*/ 8, /* 8x32 , 10*/ 16, /* 16x16 , 12*/ 12, /* 12x26 , 16*/ 18, /* 18x18 , 18*/
|
||||
/* 8*/ 8, /* 8x48 , 18*/ 20, /* 20x20 , 22*/ 12, /* 12x36 , 22*/ 8, /* 8x64 , 24*/
|
||||
/*12*/ 22, /* 22x22 , 30*/ 16, /* 16x36 , 32*/ 8, /* 8x80 , 32*/ 24, /* 24x24 , 36*/
|
||||
/*16*/ 8, /* 8x96 , 38*/ 12, /* 12x64 , 43*/ 26, /* 26x26 , 44*/ 20, /* 20x36 , 44*/
|
||||
/*20*/ 16, /* 16x48 , 49*/ 8, /* 8x120, 49*/ 20, /* 20x44 , 56*/ 32, /* 32x32 , 62*/
|
||||
/*24*/ 16, /* 16x64 , 62*/ 8, /* 8x144, 63*/ 12, /* 12x88 , 64*/ 26, /* 26x40 , 70*/
|
||||
/*28*/ 22, /* 22x48 , 72*/ 24, /* 24x48 , 80*/ 20, /* 20x64 , 84*/ 36, /* 36x36 , 86*/
|
||||
/*32*/ 26, /* 26x48 , 90*/ 24, /* 24x64 ,108*/ 40, /* 40x40 ,114*/ 26, /* 26x64 ,118*/
|
||||
/*36*/ 44, /* 44x44 ,144*/ 48, /* 48x48 ,174*/ 52, /* 52x52 ,204*/ 64, /* 64x64 ,280*/
|
||||
/*40*/ 72, /* 72x72 ,368*/ 80, /* 80x80 ,456*/ 88, /* 88x88 ,576*/ 96, /* 96x96 ,696*/
|
||||
/*44*/104, /*104x104,816*/ 120,/*120x120,1050*/132,/*132x132,1304*/144 /*144x144,1558*/
|
||||
static const unsigned char dm_matrixH[DMSIZESCOUNT] = {
|
||||
/* 0*/ 10 /*10x10*/, 12 /*12x12 */, 8 /*8x18*/, 14 /*14x14*/,
|
||||
/* 4*/ 8 /*8x32*/, 16 /*16x16*/, 12 /*12x26*/, 18 /*18x18*/,
|
||||
/* 8*/ 8 /*8x48*/, 20 /*20x20*/, 12 /*12x36*/, 8 /*8x64*/,
|
||||
/*12*/ 22 /*22x22*/, 16 /*16x36*/, 8 /*8x80*/, 24 /*24x24*/,
|
||||
/*16*/ 8 /*8x96*/, 12 /*12x64*/, 26 /*26x26*/, 20 /*20x36*/,
|
||||
/*20*/ 16 /*16x48*/, 8 /*8x120*/, 20 /*20x44*/, 32 /*32x32*/,
|
||||
/*24*/ 16 /*16x64*/, 8 /*8x144*/, 12 /*12x88*/, 26 /*26x40*/,
|
||||
/*28*/ 22 /*22x48*/, 24 /*24x48*/, 20 /*20x64*/, 36 /*36x36*/,
|
||||
/*32*/ 26 /*26x48*/, 24 /*24x64*/, 40 /*40x40*/, 26 /*26x64*/,
|
||||
/*36*/ 44 /*44x44*/, 48 /*48x48*/, 52 /*52x52*/, 64 /*64x64*/,
|
||||
/*40*/ 72 /*72x72*/, 80 /*80x80*/, 88 /*88x88*/, 96 /*96x96*/,
|
||||
/*44*/ 104 /*104x104*/, 120 /*120x120*/, 132 /*132x132*/, 144 /*144x144*/
|
||||
};
|
||||
|
||||
/* Vertical matrix sizes */
|
||||
|
||||
static const unsigned short dm_matrixW[] = {
|
||||
/* 0*/ 10, /* 10x10 */ 12, /* 12x12 */ 18, /* 8x18 */ 14, /* 14x14 */
|
||||
/* 4*/ 32, /* 8x32 */ 16, /* 16x16 */ 26, /* 12x26 */ 18, /* 18x18 */
|
||||
/* 8*/ 48, /* 8x48 */ 20, /* 20x20 */ 36, /* 12x36 */ 64, /* 8x64 */
|
||||
/*12*/ 22, /* 22x22 */ 36, /* 16x36 */ 80, /* 8x80 */ 24, /* 24x24 */
|
||||
/*16*/ 96, /* 8x96 */ 64, /* 12x64 */ 26, /* 26x26 */ 36, /* 20x36 */
|
||||
/*20*/ 48, /* 16x48 */120, /* 8x120*/ 44, /* 20x44 */ 32, /* 32x32 */
|
||||
/*24*/ 64, /* 16x64 */144, /* 8x144*/ 88, /* 12x88 */ 40, /* 26x40 */
|
||||
/*28*/ 48, /* 22x48 */ 48, /* 24x48 */ 64, /* 20x64 */ 36, /* 36x36 */
|
||||
/*32*/ 48, /* 26x48 */ 64, /* 24x64 */ 40, /* 40x40 */ 64, /* 26x64 */
|
||||
/*36*/ 44, /* 44x44 */ 48, /* 48x48 */ 52, /* 52x52 */ 64, /* 64x64 */
|
||||
/*40*/ 72, /* 72x72 */ 80, /* 80x80 */ 88, /* 88x88 */ 96, /* 96x96 */
|
||||
/*44*/104, /*104x104*/120, /*120x120*/ 132, /*132x132*/144 /*144x144*/
|
||||
|
||||
static const unsigned char dm_matrixW[DMSIZESCOUNT] = {
|
||||
/* 0*/ 10 /*10x10*/, 12 /*12x12*/, 18 /*8x18*/, 14 /*14x14*/,
|
||||
/* 4*/ 32 /*8x32*/, 16 /*16x16*/, 26 /*12x26*/, 18 /*18x18*/,
|
||||
/* 8*/ 48 /*8x48*/, 20 /*20x20*/, 36 /*12x36*/, 64 /*8x64*/,
|
||||
/*12*/ 22 /*22x22*/, 36 /*16x36*/, 80 /*8x80*/, 24 /*24x24*/,
|
||||
/*16*/ 96 /*8x96*/, 64 /*12x64*/, 26 /*26x26*/, 36 /*20x36*/,
|
||||
/*20*/ 48 /*16x48*/, 120 /*8x120*/, 44 /*20x44*/, 32 /*32x32*/,
|
||||
/*24*/ 64 /*16x64*/, 144 /*8x144*/, 88 /*12x88*/, 40 /*26x40*/,
|
||||
/*28*/ 48 /*22x48*/, 48 /*24x48*/, 64 /*20x64*/, 36 /*36x36*/,
|
||||
/*32*/ 48 /*26x48*/, 64 /*24x64*/, 40 /*40x40*/, 64 /*26x64*/,
|
||||
/*36*/ 44 /*44x44*/, 48 /*48x48*/, 52 /*52x52*/, 64 /*64x64*/,
|
||||
/*40*/ 72 /*72x72*/, 80 /*80x80*/, 88 /*88x88*/, 96 /*96x96*/,
|
||||
/*44*/ 104 /*104x104*/, 120 /*120x120*/, 132 /*132x132*/, 144 /*144x144*/
|
||||
};
|
||||
|
||||
/* Horizontal submodule size (including subfinder) */
|
||||
|
||||
static const unsigned short dm_matrixFH[] = {
|
||||
/* 0*/ 10, /* 10x10 */ 12, /* 12x12 */ 8, /* 8x18 */ 14, /* 14x14 */
|
||||
/* 4*/ 8, /* 8x32 */ 16, /* 16x16 */ 12, /* 12x26 */ 18, /* 18x18 */
|
||||
/* 8*/ 8, /* 8x48 */ 20, /* 20x20 */ 12, /* 12x36 */ 8, /* 8x64 */
|
||||
/*12*/ 22, /* 22x22 */ 16, /* 16x36 */ 8, /* 8x80 */ 24, /* 24x24 */
|
||||
/*16*/ 8, /* 8x96 */ 12, /* 12x64 */ 26, /* 26x26 */ 20, /* 20x36 */
|
||||
/*20*/ 16, /* 16x48 */ 8, /* 8x120*/ 20, /* 20x44 */ 16, /* 32x32 */
|
||||
/*24*/ 16, /* 16x64 */ 8, /* 8x144*/ 12, /* 12x88 */ 26, /* 26x40 */
|
||||
/*28*/ 22, /* 22x48 */ 24, /* 24x48 */ 20, /* 20x64 */ 18, /* 36x36 */
|
||||
/*32*/ 26, /* 26x48 */ 24, /* 24x64 */ 20, /* 40x40 */ 26, /* 26x64 */
|
||||
/*36*/ 22, /* 44x44 */ 24, /* 48x48 */ 26, /* 52x52 */ 16, /* 64x64 */
|
||||
/*40*/ 18, /* 72x72 */ 20, /* 80x80 */ 22, /* 88x88 */ 24, /* 96x96 */
|
||||
/*44*/ 26, /*104x104*/ 20, /*120x120*/ 22, /*132x132*/ 24 /*144x144*/
|
||||
/* Horizontal submodule size (including subfinder) - see Table 7 Data region H + 2 */
|
||||
static const unsigned char dm_matrixFH[DMSIZESCOUNT] = {
|
||||
/* 0*/ 10 /*10x10*/, 12 /*12x12*/, 8 /*8x18*/, 14 /*14x14*/,
|
||||
/* 4*/ 8 /*8x32*/, 16 /*16x16*/, 12 /*12x26*/, 18 /*18x18*/,
|
||||
/* 8*/ 8 /*8x48*/, 20 /*20x20*/, 12 /*12x36*/, 8 /*8x64*/,
|
||||
/*12*/ 22 /*22x22*/, 16 /*16x36*/, 8 /*8x80*/, 24 /*24x24*/,
|
||||
/*16*/ 8 /*8x96*/, 12 /*12x64*/, 26 /*26x26*/, 20 /*20x36*/,
|
||||
/*20*/ 16 /*16x48*/, 8 /*8x120*/, 20 /*20x44*/, 16 /*32x32*/,
|
||||
/*24*/ 16 /*16x64*/, 8 /*8x144*/, 12 /*12x88*/, 26 /*26x40*/,
|
||||
/*28*/ 22 /*22x48*/, 24 /*24x48*/, 20 /*20x64*/, 18 /*36x36*/,
|
||||
/*32*/ 26 /*26x48*/, 24 /*24x64*/, 20 /*40x40*/, 26 /*26x64*/,
|
||||
/*36*/ 22 /*44x44*/, 24 /*48x48*/, 26 /*52x52*/, 16 /*64x64*/,
|
||||
/*40*/ 18 /*72x72*/, 20 /*80x80*/, 22 /*88x88*/, 24 /*96x96*/,
|
||||
/*44*/ 26 /*104x104*/, 20 /*120x120*/, 22 /*132x132*/, 24 /*144x144*/
|
||||
};
|
||||
|
||||
/* Vertical submodule size (including subfinder) */
|
||||
|
||||
static const unsigned short dm_matrixFW[] = {
|
||||
/* 0*/ 10, /* 10x10 */ 12, /* 12x12 */ 18, /* 8x18 */ 14, /* 14x14 */
|
||||
/* 4*/ 16, /* 8x32 */ 16, /* 16x16 */ 26, /* 12x26 */ 18, /* 18x18 */
|
||||
/* 8*/ 24, /* 8x48 */ 20, /* 20x20 */ 18, /* 12x36 */ 16, /* 8x64 */
|
||||
/*12*/ 22, /* 22x22 */ 18, /* 16x36 */ 20, /* 8x80 */ 24, /* 24x24 */
|
||||
/*16*/ 24, /* 8x96 */ 16, /* 12x64 */ 26, /* 26x26 */ 18, /* 20x36 */
|
||||
/*20*/ 24, /* 16x48 */ 20, /* 8x120*/ 22, /* 20x44 */ 16, /* 32x32 */
|
||||
/*24*/ 16, /* 16x64 */ 24, /* 8x144*/ 22, /* 12x88 */ 20, /* 26x40 */
|
||||
/*28*/ 24, /* 22x48 */ 24, /* 24x48 */ 16, /* 20x64 */ 18, /* 36x36 */
|
||||
/*32*/ 24, /* 26x48 */ 16, /* 24x64 */ 20, /* 40x40 */ 16, /* 26x64 */
|
||||
/*36*/ 22, /* 44x44 */ 24, /* 48x48 */ 26, /* 52x52 */ 16, /* 64x64 */
|
||||
/*40*/ 18, /* 72x72 */ 20, /* 80x80 */ 22, /* 88x88 */ 24, /* 96x96 */
|
||||
/*44*/ 26, /*104x104*/ 20, /*120x120*/ 22, /*132x132*/ 24 /*144x144*/
|
||||
};
|
||||
|
||||
/* Total Data Codewords */
|
||||
|
||||
static const unsigned short dm_matrixbytes[] = {
|
||||
/* 0*/ 3, /* 10x10 */ 5, /* 12x12 */ 5, /* 8x18 */ 8, /* 14x14 */
|
||||
/* 4*/ 10, /* 8x32 */ 12, /* 16x16 */ 16, /* 12x26 */ 18, /* 18x18 */
|
||||
/* 8*/ 18, /* 8x48 */ 22, /* 20x20 */ 22, /* 12x36 */ 24, /* 8x64 */
|
||||
/*12*/ 30, /* 22x22 */ 32, /* 16x36 */ 32, /* 8x80 */ 36, /* 24x24 */
|
||||
/*16*/ 38, /* 8x96 */ 43, /* 12x64 */ 44, /* 26x26 */ 44, /* 20x36 */
|
||||
/*20*/ 49, /* 16x48 */ 49, /* 8x120*/ 56, /* 20x44 */ 62, /* 32x32 */
|
||||
/*24*/ 62, /* 16x64 */ 63, /* 8x144*/ 64, /* 12x88 */ 70, /* 26x40 */
|
||||
/*28*/ 72, /* 22x48 */ 80, /* 24x48 */ 84, /* 20x64 */ 86, /* 36x36 */
|
||||
/*32*/ 90, /* 26x48 */ 108, /* 24x64 */ 114, /* 40x40 */ 118, /* 26x64 */
|
||||
/*36*/ 144, /* 44x44 */ 174, /* 48x48 */ 204, /* 52x52 */ 280, /* 64x64 */
|
||||
/*40*/ 368, /* 72x72 */ 456, /* 80x80 */ 576, /* 88x88 */ 696, /* 96x96 */
|
||||
/*44*/ 816, /*104x104*/1050, /*120x120*/1304, /*132x132*/1558 /*144x144*/
|
||||
/* Vertical submodule size (including subfinder) - see Table 7 Data region W + 2 */
|
||||
static const unsigned char dm_matrixFW[DMSIZESCOUNT] = {
|
||||
/* 0*/ 10 /*10x10*/, 12 /*12x12*/, 18 /*8x18*/, 14 /*14x14*/,
|
||||
/* 4*/ 16 /*8x32*/, 16 /*16x16*/, 26 /*12x26*/, 18 /*18x18*/,
|
||||
/* 8*/ 24 /*8x48*/, 20 /*20x20*/, 18 /*12x36*/, 16 /*8x64*/,
|
||||
/*12*/ 22 /*22x22*/, 18 /*16x36*/, 20 /*8x80*/, 24 /*24x24*/,
|
||||
/*16*/ 24 /*8x96*/, 16 /*12x64*/, 26 /*26x26*/, 18 /*20x36*/,
|
||||
/*20*/ 24 /*16x48*/, 20 /*8x120*/, 22 /*20x44*/, 16 /*32x32*/,
|
||||
/*24*/ 16 /*16x64*/, 24 /*8x144*/, 22 /*12x88*/, 20 /*26x40*/,
|
||||
/*28*/ 24 /*22x48*/, 24 /*24x48*/, 16 /*20x64*/, 18 /*36x36*/,
|
||||
/*32*/ 24 /*26x48*/, 16 /*24x64*/, 20 /*40x40*/, 16 /*26x64*/,
|
||||
/*36*/ 22 /*44x44*/, 24 /*48x48*/, 26 /*52x52*/, 16 /*64x64*/,
|
||||
/*40*/ 18 /*72x72*/, 20 /*80x80*/, 22 /*88x88*/, 24 /*96x96*/,
|
||||
/*44*/ 26 /*104x104*/, 20 /*120x120*/, 22 /*132x132*/, 24 /*144x144*/
|
||||
};
|
||||
|
||||
/* Data Codewords per RS-Block */
|
||||
|
||||
static const unsigned short dm_matrixdatablock[] = {
|
||||
/* 0*/ 3, /* 10x10 */ 5, /* 12x12 */ 5, /* 8x18 */ 8, /* 14x14 */
|
||||
/* 4*/ 10, /* 8x32 */ 12, /* 16x16 */ 16, /* 12x26 */ 18, /* 18x18 */
|
||||
/* 8*/ 18, /* 8x48 */ 22, /* 20x20 */ 22, /* 12x36 */ 24, /* 8x64 */
|
||||
/*12*/ 30, /* 22x22 */ 32, /* 16x36 */ 32, /* 8x80 */ 36, /* 24x24 */
|
||||
/*16*/ 38, /* 8x96 */ 43, /* 12x64 */ 44, /* 26x26 */ 44, /* 20x36 */
|
||||
/*20*/ 49, /* 16x48 */ 49, /* 8x120*/ 56, /* 20x44 */ 62, /* 32x32 */
|
||||
/*24*/ 62, /* 16x64 */ 63, /* 8x144*/ 64, /* 12x88 */ 70, /* 26x40 */
|
||||
/*28*/ 72, /* 22x48 */ 80, /* 24x48 */ 84, /* 20x64 */ 86, /* 36x36 */
|
||||
/*32*/ 90, /* 26x48 */ 108, /* 24x64 */ 114, /* 40x40 */ 118, /* 26x64 */
|
||||
/*36*/ 144, /* 44x44 */ 174, /* 48x48 */ 102, /* 52x52 */ 140, /* 64x64 */
|
||||
/*40*/ 92, /* 72x72 */ 114, /* 80x80 */ 144, /* 88x88 */ 174, /* 96x96 */
|
||||
/*44*/ 136, /*104x104*/ 175, /*120x120*/ 163, /*132x132*/ 156 /* 144x144*/
|
||||
static const unsigned char dm_matrixdatablock[DMSIZESCOUNT] = {
|
||||
/* 0*/ 3 /*10x10*/, 5 /*12x12*/, 5 /*8x18*/, 8 /*14x14*/,
|
||||
/* 4*/ 10 /*8x32*/, 12 /*16x16*/, 16 /*12x26*/, 18 /*18x18*/,
|
||||
/* 8*/ 18 /*8x48*/, 22 /*20x20*/, 22 /*12x36*/, 24 /*8x64*/,
|
||||
/*12*/ 30 /*22x22*/, 32 /*16x36*/, 32 /*8x80*/, 36 /*24x24*/,
|
||||
/*16*/ 38 /*8x96*/, 43 /*12x64*/, 44 /*26x26*/, 44 /*20x36*/,
|
||||
/*20*/ 49 /*16x48*/, 49 /*8x120*/, 56 /*20x44*/, 62 /*32x32*/,
|
||||
/*24*/ 62 /*16x64*/, 63 /*8x144*/, 64 /*12x88*/, 70 /*26x40*/,
|
||||
/*28*/ 72 /*22x48*/, 80 /*24x48*/, 84 /*20x64*/, 86 /*36x36*/,
|
||||
/*32*/ 90 /*26x48*/, 108 /*24x64*/, 114 /*40x40*/, 118 /*26x64*/,
|
||||
/*36*/ 144 /*44x44*/, 174 /*48x48*/, 102 /*52x52*/, 140 /*64x64*/,
|
||||
/*40*/ 92 /*72x72*/, 114 /*80x80*/, 144 /*88x88*/, 174 /*96x96*/,
|
||||
/*44*/ 136 /*104x104*/, 175 /*120x120*/, 163 /*132x132*/, 156 /*144x144*/
|
||||
};
|
||||
|
||||
/* ECC Codewords per RS-Block */
|
||||
|
||||
static const unsigned short dm_matrixrsblock[] = {
|
||||
/* 0*/ 5, /* 10x10 */ 7, /* 12x12 */ 7, /* 8x18 */ 10, /* 14x14 */
|
||||
/* 4*/ 11, /* 8x32 */ 12, /* 16x16 */ 14, /* 12x26 */ 14, /* 18x18 */
|
||||
/* 8*/ 15, /* 8x48 */ 18, /* 20x20 */ 18, /* 12x36 */ 18, /* 8x64 */
|
||||
/*12*/ 20, /* 22x22 */ 24, /* 16x36 */ 22, /* 8x80 */ 24, /* 24x24 */
|
||||
/*16*/ 28, /* 8x96 */ 27, /* 12x64 */ 28, /* 26x26 */ 28, /* 20x36 */
|
||||
/*20*/ 28, /* 16x48 */ 32, /* 8x120*/ 34, /* 20x44 */ 36, /* 32x32 */
|
||||
/*24*/ 36, /* 16x64 */ 36, /* 8x144*/ 36, /* 12x88 */ 38, /* 26x40 */
|
||||
/*28*/ 38, /* 22x48 */ 41, /* 24x48 */ 42, /* 20x64 */ 42, /* 36x36 */
|
||||
/*32*/ 42, /* 26x48 */ 46, /* 24x64 */ 48, /* 40x40 */ 50, /* 26x64 */
|
||||
/*36*/ 56, /* 44x44 */ 68, /* 48x48 */ 42, /* 52x52 */ 56, /* 64x64 */
|
||||
/*40*/ 36, /* 72x72 */ 48, /* 80x80 */ 56, /* 88x88 */ 68, /* 96x96 */
|
||||
/*44*/ 56, /*104x104*/ 68, /*120x120*/ 62, /*132x132*/ 62 /*144x144*/
|
||||
static const unsigned char dm_matrixrsblock[DMSIZESCOUNT] = {
|
||||
/* 0*/ 5 /*10x10*/, 7 /*12x12*/, 7 /*8x18*/, 10 /*14x14*/,
|
||||
/* 4*/ 11 /*8x32*/, 12 /*16x16*/, 14 /*12x26*/, 14 /*18x18*/,
|
||||
/* 8*/ 15 /*8x48*/, 18 /*20x20*/, 18 /*12x36*/, 18 /*8x64*/,
|
||||
/*12*/ 20 /*22x22*/, 24 /*16x36*/, 22 /*8x80*/, 24 /*24x24*/,
|
||||
/*16*/ 28 /*8x96*/, 27 /*12x64*/, 28 /*26x26*/, 28 /*20x36*/,
|
||||
/*20*/ 28 /*16x48*/, 32 /*8x120*/, 34 /*20x44*/, 36 /*32x32*/,
|
||||
/*24*/ 36 /*16x64*/, 36 /*8x144*/, 36 /*12x88*/, 38 /*26x40*/,
|
||||
/*28*/ 38 /*22x48*/, 41 /*24x48*/, 42 /*20x64*/, 42 /*36x36*/,
|
||||
/*32*/ 42 /*26x48*/, 46 /*24x64*/, 48 /*40x40*/, 50 /*26x64*/,
|
||||
/*36*/ 56 /*44x44*/, 68 /*48x48*/, 42 /*52x52*/, 56 /*64x64*/,
|
||||
/*40*/ 36 /*72x72*/, 48 /*80x80*/, 56 /*88x88*/, 68 /*96x96*/,
|
||||
/*44*/ 56 /*104x104*/, 68 /*120x120*/, 62 /*132x132*/, 62 /*144x144*/
|
||||
};
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* dotcode.c - Handles DotCode */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2017-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2017-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -658,8 +658,8 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dc_datum_c(source, length, position) || (source[position] == '[' && gs1)) {
|
||||
if (source[position] == '[') {
|
||||
if (dc_datum_c(source, length, position) || (gs1 && source[position] == '\x1D')) {
|
||||
if (source[position] == '\x1D') {
|
||||
codeword_array[ap++] = 107; /* FNC1 */
|
||||
position++;
|
||||
} else {
|
||||
@ -747,7 +747,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
}
|
||||
|
||||
/* Step D2 */
|
||||
if ((source[position] == '[') && gs1) {
|
||||
if (gs1 && source[position] == '\x1D') {
|
||||
codeword_array[ap++] = 107; /* FNC1 */
|
||||
position++;
|
||||
if (debug_print) fputs("D2/1 ", stdout);
|
||||
@ -841,7 +841,7 @@ static int dc_encode_message(struct zint_symbol *symbol, const unsigned char sou
|
||||
}
|
||||
|
||||
/* Step E2 */
|
||||
if ((source[position] == '[') && gs1) {
|
||||
if (gs1 && source[position] == '\x1D') {
|
||||
/* Note: this branch probably never reached as no reason to be in Code Set A for GS1 data */
|
||||
codeword_array[ap++] = 107; /* FNC1 */
|
||||
position++;
|
||||
@ -1229,8 +1229,8 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
unsigned char *masked_codeword_array;
|
||||
|
||||
if (symbol->eci > 811799) {
|
||||
strcpy(symbol->errtxt, "525: Invalid ECI");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 525, "ECI code '%d' out of range (0 to 811799)",
|
||||
symbol->eci);
|
||||
}
|
||||
|
||||
user_mask = (symbol->option_3 >> 8) & 0x0F; /* User mask is mask + 1, so >= 1 and <= 8 */
|
||||
@ -1240,16 +1240,16 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
|
||||
if (symbol->structapp.count) {
|
||||
if (symbol->structapp.count < 2 || symbol->structapp.count > 35) {
|
||||
strcpy(symbol->errtxt, "730: Structured Append count out of range (2-35)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 730,
|
||||
"Structured Append count '%d' out of range (2 to 35)", symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
|
||||
sprintf(symbol->errtxt, "731: Structured Append index out of range (1-%d)", symbol->structapp.count);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 731,
|
||||
"Structured Append index '%1$d' out of range (1 to count %2$d)",
|
||||
symbol->structapp.index, symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.id[0]) {
|
||||
strcpy(symbol->errtxt, "732: Structured Append ID not available for DotCode");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 732, "Structured Append ID not available for DotCode");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1258,14 +1258,14 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
if (gs1 && warn_number == 0) {
|
||||
for (i = 0; i < seg_count; i++) {
|
||||
if (segs[i].eci) {
|
||||
strcpy(symbol->errtxt, "733: Using ECI in GS1 mode not supported by GS1 standards");
|
||||
warn_number = ZINT_WARN_NONCOMPLIANT;
|
||||
warn_number = errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 733,
|
||||
"Using ECI in GS1 mode not supported by GS1 standards");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (warn_number == 0 && symbol->structapp.count) {
|
||||
strcpy(symbol->errtxt, "734: Using Structured Append in GS1 mode not supported by GS1 standards");
|
||||
warn_number = ZINT_WARN_NONCOMPLIANT;
|
||||
warn_number = errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 734,
|
||||
"Using Structured Append in GS1 mode not supported by GS1 standards");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1337,9 +1337,9 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
|
||||
if ((height > 200) || (width > 200)) {
|
||||
if (height > 200 && width > 200) {
|
||||
sprintf(symbol->errtxt, "526: Symbol size %dx%d (WxH) is too large", width, height);
|
||||
errtxtf(0, symbol, 526, "Symbol size '%1$dx%2$d' (WxH) is too large", width, height);
|
||||
} else {
|
||||
sprintf(symbol->errtxt, "528: Symbol %s %d is too large",
|
||||
errtxtf(0, symbol, 528, "Symbol %1$s '%2$d' is too large",
|
||||
width > 200 ? "width" : "height", width > 200 ? width : height);
|
||||
}
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
@ -1347,10 +1347,10 @@ INTERNAL int dotcode(struct zint_symbol *symbol, struct zint_seg segs[], const i
|
||||
|
||||
if ((height < 5) || (width < 5)) {
|
||||
if (height < 5 && width < 5) { /* Won't happen as if width < 5, min height is 19 */
|
||||
sprintf(symbol->errtxt, "527: Symbol size %dx%d (WxH) is too small", width, height); /* Not reached */
|
||||
errtxtf(0, symbol, 527, "Symbol size '%1$dx%2$d' (WxH) is too small", width, height); /* Not reached */
|
||||
} else {
|
||||
sprintf(symbol->errtxt, "529: Symbol %s %d is too small",
|
||||
width < 5 ? "width" : "height", width < 5 ? width : height);
|
||||
errtxtf(0, symbol, 529, "Symbol %1$s '%2$d' is too small",
|
||||
width < 5 ? "width" : "height", width < 5 ? width : height);
|
||||
}
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* eci.c - Extended Channel Interpretations */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -764,7 +764,7 @@ INTERNAL int utf8_to_eci(const int eci, const unsigned char source[], unsigned c
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find the lowest single-byte ECI mode which will encode a given set of Unicode text */
|
||||
/* Find the lowest single-byte ECI mode which will encode a given set of Unicode text, assuming valid UTF-8 */
|
||||
INTERNAL int get_best_eci(const unsigned char source[], int length) {
|
||||
int eci = 3;
|
||||
/* Note: attempting single-byte conversions only, so get_eci_length() unnecessary */
|
||||
@ -782,14 +782,12 @@ INTERNAL int get_best_eci(const unsigned char source[], int length) {
|
||||
eci++;
|
||||
} while (eci < 25);
|
||||
|
||||
if (!is_valid_utf8(source, length)) {
|
||||
return 0;
|
||||
}
|
||||
assert(is_valid_utf8(source, length));
|
||||
|
||||
return 26; /* If all of these fail, use UTF-8! */
|
||||
}
|
||||
|
||||
/* Call `get_best_eci()` for each segment. Returns 0 on failure, first ECI set on success */
|
||||
/* Call `get_best_eci()` for each segment, assuming valid UTF-8. Returns 0 on failure, first ECI set on success */
|
||||
INTERNAL int get_best_eci_segs(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
|
||||
const int default_eci = symbol->symbology == BARCODE_GRIDMATRIX ? 29 : symbol->symbology == BARCODE_UPNQR ? 4 : 3;
|
||||
int first_eci_set = 0;
|
||||
@ -797,10 +795,7 @@ INTERNAL int get_best_eci_segs(struct zint_symbol *symbol, struct zint_seg segs[
|
||||
|
||||
for (i = 0; i < seg_count; i++) {
|
||||
if (segs[i].eci == 0) {
|
||||
int eci = get_best_eci(segs[i].source, segs[i].length);
|
||||
if (eci == 0) {
|
||||
return 0;
|
||||
}
|
||||
const int eci = get_best_eci(segs[i].source, segs[i].length);
|
||||
if (eci == default_eci) {
|
||||
if (i != 0 && segs[i - 1].eci != 0 && segs[i - 1].eci != default_eci) {
|
||||
segs[i].eci = eci;
|
||||
@ -839,8 +834,7 @@ INTERNAL int sjis_utf8(struct zint_symbol *symbol, const unsigned char source[],
|
||||
|
||||
for (i = 0, length = *p_length; i < length; i++) {
|
||||
if (!u_sjis_int(utfdata[i], ddata + i)) {
|
||||
strcpy(symbol->errtxt, "800: Invalid character in input data");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 800, "Invalid character in input");
|
||||
}
|
||||
}
|
||||
|
||||
@ -934,8 +928,7 @@ INTERNAL int gb2312_utf8(struct zint_symbol *symbol, const unsigned char source[
|
||||
ddata[i] = utfdata[i];
|
||||
} else {
|
||||
if (!u_gb2312_int(utfdata[i], ddata + i)) {
|
||||
strcpy(symbol->errtxt, "810: Invalid character in input data");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 810, "Invalid character in input");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1038,8 +1031,7 @@ INTERNAL int gb18030_utf8(struct zint_symbol *symbol, const unsigned char source
|
||||
} else {
|
||||
ret = u_gb18030_int(utfdata[i], ddata + j, ddata + j + 1);
|
||||
if (ret == 0) { /* Should never happen, as GB 18030 is a UTF i.e. maps all Unicode codepoints */
|
||||
strcpy(symbol->errtxt, "820: Invalid character in input data"); /* Not reached */
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 820, "Invalid character in input"); /* Not reached */
|
||||
}
|
||||
if (ret == 4) {
|
||||
j++;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* eci.c - Extended Channel Interpretations to Unicode tables */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
INTERNAL int is_eci_convertible(const int eci);
|
||||
INTERNAL int is_eci_convertible_segs(const struct zint_seg segs[], const int seg_count, int convertible[]);
|
||||
@ -75,7 +75,7 @@ INTERNAL int gb18030_utf8_to_eci(const int eci, const unsigned char source[], in
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
#endif /* Z_ECI_H */
|
||||
|
444
backend/emf.c
@ -1,7 +1,7 @@
|
||||
/* emf.c - Support for Microsoft Enhanced Metafile Format */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2016-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2016-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -37,16 +37,13 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "filemem.h"
|
||||
#include "output.h"
|
||||
#include "emf.h"
|
||||
|
||||
/* Multiply truncating to 3 decimal places (avoids rounding differences on various platforms) */
|
||||
#define mul3dpf(m, arg) stripf(roundf((m) * (arg) * 1000.0f) / 1000.0f)
|
||||
#define emf_mul3dpf(m, arg) stripf(roundf((m) * (arg) * 1000.0f) / 1000.0f)
|
||||
|
||||
static int emf_count_rectangles(const struct zint_symbol *symbol) {
|
||||
int rectangles = 0;
|
||||
@ -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;
|
||||
@ -203,6 +200,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
emr_exttextoutw_t text[6];
|
||||
float text_fsizes[6];
|
||||
int text_haligns[6];
|
||||
int text_bumped_lens[6];
|
||||
|
||||
emr_header_t emr_header;
|
||||
emr_eof_t emr_eof;
|
||||
@ -241,8 +239,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
const int ih_ultra_offset = symbol->symbology == BARCODE_ULTRA ? 8 : 0;
|
||||
|
||||
if (symbol->vector == NULL) {
|
||||
strcpy(symbol->errtxt, "643: Vector header NULL");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 643, "Vector header NULL");
|
||||
}
|
||||
|
||||
(void) out_colour_get_rgb(symbol->fgcolour, &fgred, &fggrn, &fgblu, NULL /*alpha*/);
|
||||
@ -306,74 +303,76 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
}
|
||||
|
||||
/* Header */
|
||||
emr_header.type = 0x00000001; /* EMR_HEADER */
|
||||
emr_header.size = 108; /* Including extensions */
|
||||
emr_header.emf_header.bounds.left = emr_header.emf_header.bounds.top = 0;
|
||||
emr_header.emf_header.bounds.right = sideways ? bounds_pxy : bounds_pxx;
|
||||
emr_header.emf_header.bounds.bottom = sideways ? bounds_pxx : bounds_pxy;
|
||||
emr_header.emf_header.frame.left = emr_header.emf_header.frame.top = 0;
|
||||
emr_header.emf_header.frame.right = sideways ? frame_cmmy : frame_cmmx;
|
||||
emr_header.emf_header.frame.bottom = sideways ? frame_cmmx : frame_cmmy;
|
||||
emr_header.emf_header.record_signature = 0x464d4520; /* ENHMETA_SIGNATURE */
|
||||
emr_header.emf_header.version = 0x00010000;
|
||||
emr_header.emf_header.handles = (fsize2 != 0.0f ? 5 : 4) + ih_ultra_offset; /* Number of graphics objects */
|
||||
emr_header.emf_header.reserved = 0x0000;
|
||||
emr_header.emf_header.n_description = 0;
|
||||
emr_header.emf_header.off_description = 0;
|
||||
emr_header.emf_header.n_pal_entries = 0;
|
||||
emr_header.emf_header.device.cx = sideways ? device_pxy : device_pxx;
|
||||
emr_header.emf_header.device.cy = sideways ? device_pxx : device_pxy;
|
||||
emr_header.emf_header.millimeters.cx = sideways ? mmy : mmx;
|
||||
emr_header.emf_header.millimeters.cy = sideways ? mmx : mmy;
|
||||
out_le_u32(emr_header.type, 0x00000001); /* EMR_HEADER */
|
||||
out_le_u32(emr_header.size, 108); /* Including extensions */
|
||||
out_le_i32(emr_header.emf_header.bounds.left, 0);
|
||||
out_le_i32(emr_header.emf_header.bounds.top, 0);
|
||||
out_le_i32(emr_header.emf_header.bounds.right, sideways ? bounds_pxy : bounds_pxx);
|
||||
out_le_i32(emr_header.emf_header.bounds.bottom, sideways ? bounds_pxx : bounds_pxy);
|
||||
out_le_i32(emr_header.emf_header.frame.left, 0);
|
||||
out_le_i32(emr_header.emf_header.frame.top, 0);
|
||||
out_le_i32(emr_header.emf_header.frame.right, sideways ? frame_cmmy : frame_cmmx);
|
||||
out_le_i32(emr_header.emf_header.frame.bottom, sideways ? frame_cmmx : frame_cmmy);
|
||||
out_le_u32(emr_header.emf_header.record_signature, 0x464d4520); /* ENHMETA_SIGNATURE */
|
||||
out_le_u32(emr_header.emf_header.version, 0x00010000);
|
||||
out_le_u16(emr_header.emf_header.handles, (fsize2 != 0.0f ? 5 : 4) + ih_ultra_offset); /* No. of graphics objs */
|
||||
out_le_u16(emr_header.emf_header.reserved, 0x0000);
|
||||
out_le_u32(emr_header.emf_header.n_description, 0);
|
||||
out_le_u32(emr_header.emf_header.off_description, 0);
|
||||
out_le_u32(emr_header.emf_header.n_pal_entries, 0);
|
||||
out_le_u32(emr_header.emf_header.device.cx, sideways ? device_pxy : device_pxx);
|
||||
out_le_u32(emr_header.emf_header.device.cy, sideways ? device_pxx : device_pxy);
|
||||
out_le_u32(emr_header.emf_header.millimeters.cx, sideways ? mmy : mmx);
|
||||
out_le_u32(emr_header.emf_header.millimeters.cy, sideways ? mmx : mmy);
|
||||
/* HeaderExtension1 */
|
||||
emr_header.emf_header.cb_pixel_format = 0x0000; /* None set */
|
||||
emr_header.emf_header.off_pixel_format = 0x0000; /* None set */
|
||||
emr_header.emf_header.b_open_gl = 0x0000; /* OpenGL not present */
|
||||
out_le_u32(emr_header.emf_header.cb_pixel_format, 0x0000); /* None set */
|
||||
out_le_u32(emr_header.emf_header.off_pixel_format, 0x0000); /* None set */
|
||||
out_le_u32(emr_header.emf_header.b_open_gl, 0x0000); /* OpenGL not present */
|
||||
/* HeaderExtension2 */
|
||||
emr_header.emf_header.micrometers.cx = sideways ? microny : micronx;
|
||||
emr_header.emf_header.micrometers.cy = sideways ? micronx : microny;
|
||||
out_le_u32(emr_header.emf_header.micrometers.cx, sideways ? microny : micronx);
|
||||
out_le_u32(emr_header.emf_header.micrometers.cy, sideways ? micronx : microny);
|
||||
bytecount = 108;
|
||||
recordcount = 1;
|
||||
|
||||
emr_mapmode.type = 0x00000011; /* EMR_SETMAPMODE */
|
||||
emr_mapmode.size = 12;
|
||||
emr_mapmode.mapmode = 0x01; /* MM_TEXT */
|
||||
out_le_u32(emr_mapmode.type, 0x00000011); /* EMR_SETMAPMODE */
|
||||
out_le_u32(emr_mapmode.size, 12);
|
||||
out_le_u32(emr_mapmode.mapmode, 0x01); /* MM_TEXT */
|
||||
bytecount += 12;
|
||||
recordcount++;
|
||||
|
||||
if (rotate_angle) {
|
||||
emr_setworldtransform.type = 0x00000023; /* EMR_SETWORLDTRANSFORM */
|
||||
emr_setworldtransform.size = 32;
|
||||
emr_setworldtransform.m11 = rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? -1.0f : 0.0f;
|
||||
emr_setworldtransform.m12 = rotate_angle == 90 ? 1.0f : rotate_angle == 180 ? 0.0f : -1.0f;
|
||||
emr_setworldtransform.m21 = rotate_angle == 90 ? -1.0f : rotate_angle == 180 ? 0.0f : 1.0f;
|
||||
emr_setworldtransform.m22 = rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? -1.0f : 0.0f;
|
||||
emr_setworldtransform.dx = rotate_angle == 90 ? height : rotate_angle == 180 ? width : 0.0f;
|
||||
emr_setworldtransform.dy = rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? height : width;
|
||||
out_le_u32(emr_setworldtransform.type, 0x00000023); /* EMR_SETWORLDTRANSFORM */
|
||||
out_le_u32(emr_setworldtransform.size, 32);
|
||||
out_le_float(emr_setworldtransform.m11, rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? -1.0f : 0.0f);
|
||||
out_le_float(emr_setworldtransform.m12, rotate_angle == 90 ? 1.0f : rotate_angle == 180 ? 0.0f : -1.0f);
|
||||
out_le_float(emr_setworldtransform.m21, rotate_angle == 90 ? -1.0f : rotate_angle == 180 ? 0.0f : 1.0f);
|
||||
out_le_float(emr_setworldtransform.m22, rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? -1.0f : 0.0f);
|
||||
out_le_float(emr_setworldtransform.dx, rotate_angle == 90 ? height : rotate_angle == 180 ? width : 0.0f);
|
||||
out_le_float(emr_setworldtransform.dy, rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? height : width);
|
||||
bytecount += 32;
|
||||
recordcount++;
|
||||
}
|
||||
|
||||
/* Create Brushes */
|
||||
emr_createbrushindirect_bg.type = 0x00000027; /* EMR_CREATEBRUSHINDIRECT */
|
||||
emr_createbrushindirect_bg.size = 24;
|
||||
emr_createbrushindirect_bg.ih_brush = 0;
|
||||
emr_createbrushindirect_bg.log_brush.brush_style = 0x0000; /* BS_SOLID */
|
||||
out_le_u32(emr_createbrushindirect_bg.type, 0x00000027); /* EMR_CREATEBRUSHINDIRECT */
|
||||
out_le_u32(emr_createbrushindirect_bg.size, 24);
|
||||
out_le_u32(emr_createbrushindirect_bg.ih_brush, 0);
|
||||
out_le_u32(emr_createbrushindirect_bg.log_brush.brush_style, 0x0000); /* BS_SOLID */
|
||||
emr_createbrushindirect_bg.log_brush.color.red = bgred;
|
||||
emr_createbrushindirect_bg.log_brush.color.green = bggrn;
|
||||
emr_createbrushindirect_bg.log_brush.color.blue = bgblu;
|
||||
emr_createbrushindirect_bg.log_brush.color.reserved = 0;
|
||||
emr_createbrushindirect_bg.log_brush.brush_hatch = 0x0006; /* HS_SOLIDCLR */
|
||||
out_le_u32(emr_createbrushindirect_bg.log_brush.brush_hatch, 0x0006); /* HS_SOLIDCLR */
|
||||
bytecount += 24;
|
||||
recordcount++;
|
||||
|
||||
if (symbol->symbology == BARCODE_ULTRA) {
|
||||
static const char ultra_chars[] = "0CBMRYGKW";
|
||||
static const char ultra_chars[] = { '0', 'C', 'B', 'M', 'R', 'Y', 'G', 'K', 'W' };
|
||||
for (i = 0; i < 9; i++) {
|
||||
emr_createbrushindirect_colour[i].type = 0x00000027; /* EMR_CREATEBRUSHINDIRECT */
|
||||
emr_createbrushindirect_colour[i].size = 24;
|
||||
emr_createbrushindirect_colour[i].ih_brush = 1 + i;
|
||||
emr_createbrushindirect_colour[i].log_brush.brush_style = 0x0000; /* BS_SOLID */
|
||||
out_le_u32(emr_createbrushindirect_colour[i].type, 0x00000027); /* EMR_CREATEBRUSHINDIRECT */
|
||||
out_le_u32(emr_createbrushindirect_colour[i].size, 24);
|
||||
out_le_u32(emr_createbrushindirect_colour[i].ih_brush, 1 + i);
|
||||
out_le_u32(emr_createbrushindirect_colour[i].log_brush.brush_style, 0x0000); /* BS_SOLID */
|
||||
if (i == 0) {
|
||||
emr_createbrushindirect_colour[i].log_brush.color.red = fgred;
|
||||
emr_createbrushindirect_colour[i].log_brush.color.green = fggrn;
|
||||
@ -385,53 +384,53 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
&emr_createbrushindirect_colour[i].log_brush.color.blue);
|
||||
}
|
||||
emr_createbrushindirect_colour[i].log_brush.color.reserved = 0;
|
||||
emr_createbrushindirect_colour[i].log_brush.brush_hatch = 0x0006; /* HS_SOLIDCLR */
|
||||
out_le_u32(emr_createbrushindirect_colour[i].log_brush.brush_hatch, 0x0006); /* HS_SOLIDCLR */
|
||||
}
|
||||
bytecount += colours_used * 24;
|
||||
recordcount += colours_used;
|
||||
} else {
|
||||
emr_createbrushindirect_fg.type = 0x00000027; /* EMR_CREATEBRUSHINDIRECT */
|
||||
emr_createbrushindirect_fg.size = 24;
|
||||
emr_createbrushindirect_fg.ih_brush = 1;
|
||||
emr_createbrushindirect_fg.log_brush.brush_style = 0x0000; /* BS_SOLID */
|
||||
out_le_u32(emr_createbrushindirect_fg.type, 0x00000027); /* EMR_CREATEBRUSHINDIRECT */
|
||||
out_le_u32(emr_createbrushindirect_fg.size, 24);
|
||||
out_le_u32(emr_createbrushindirect_fg.ih_brush, 1);
|
||||
out_le_u32(emr_createbrushindirect_fg.log_brush.brush_style, 0x0000); /* BS_SOLID */
|
||||
emr_createbrushindirect_fg.log_brush.color.red = fgred;
|
||||
emr_createbrushindirect_fg.log_brush.color.green = fggrn;
|
||||
emr_createbrushindirect_fg.log_brush.color.blue = fgblu;
|
||||
emr_createbrushindirect_fg.log_brush.color.reserved = 0;
|
||||
emr_createbrushindirect_fg.log_brush.brush_hatch = 0x0006; /* HS_SOLIDCLR */
|
||||
out_le_u32(emr_createbrushindirect_fg.log_brush.brush_hatch, 0x0006); /* HS_SOLIDCLR */
|
||||
bytecount += 24;
|
||||
recordcount++;
|
||||
}
|
||||
|
||||
emr_selectobject_bgbrush.type = 0x00000025; /* EMR_SELECTOBJECT */
|
||||
emr_selectobject_bgbrush.size = 12;
|
||||
out_le_u32(emr_selectobject_bgbrush.type, 0x00000025); /* EMR_SELECTOBJECT */
|
||||
out_le_u32(emr_selectobject_bgbrush.size, 12);
|
||||
emr_selectobject_bgbrush.ih_object = emr_createbrushindirect_bg.ih_brush;
|
||||
bytecount += 12;
|
||||
recordcount++;
|
||||
|
||||
if (symbol->symbology == BARCODE_ULTRA) {
|
||||
for (i = 0; i < 9; i++) {
|
||||
emr_selectobject_colour[i].type = 0x00000025; /* EMR_SELECTOBJECT */
|
||||
emr_selectobject_colour[i].size = 12;
|
||||
out_le_u32(emr_selectobject_colour[i].type, 0x00000025); /* EMR_SELECTOBJECT */
|
||||
out_le_u32(emr_selectobject_colour[i].size, 12);
|
||||
emr_selectobject_colour[i].ih_object = emr_createbrushindirect_colour[i].ih_brush;
|
||||
}
|
||||
bytecount += colours_used * 12;
|
||||
recordcount += colours_used;
|
||||
} else {
|
||||
emr_selectobject_fgbrush.type = 0x00000025; /* EMR_SELECTOBJECT */
|
||||
emr_selectobject_fgbrush.size = 12;
|
||||
out_le_u32(emr_selectobject_fgbrush.type, 0x00000025); /* EMR_SELECTOBJECT */
|
||||
out_le_u32(emr_selectobject_fgbrush.size, 12);
|
||||
emr_selectobject_fgbrush.ih_object = emr_createbrushindirect_fg.ih_brush;
|
||||
bytecount += 12;
|
||||
recordcount++;
|
||||
}
|
||||
|
||||
/* Create Pens */
|
||||
emr_createpen.type = 0x00000026; /* EMR_CREATEPEN */
|
||||
emr_createpen.size = 28;
|
||||
emr_createpen.ih_pen = 2 + ih_ultra_offset;
|
||||
emr_createpen.log_pen.pen_style = 0x00000005; /* PS_NULL */
|
||||
emr_createpen.log_pen.width.x = 1;
|
||||
emr_createpen.log_pen.width.y = 0; /* ignored */
|
||||
out_le_u32(emr_createpen.type, 0x00000026); /* EMR_CREATEPEN */
|
||||
out_le_u32(emr_createpen.size, 28);
|
||||
out_le_u32(emr_createpen.ih_pen, 2 + ih_ultra_offset);
|
||||
out_le_u32(emr_createpen.log_pen.pen_style, 0x00000005); /* PS_NULL */
|
||||
out_le_i32(emr_createpen.log_pen.width.x, 1);
|
||||
out_le_i32(emr_createpen.log_pen.width.y, 0); /* ignored */
|
||||
emr_createpen.log_pen.color_ref.red = 0;
|
||||
emr_createpen.log_pen.color_ref.green = 0;
|
||||
emr_createpen.log_pen.color_ref.blue = 0;
|
||||
@ -439,20 +438,20 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
bytecount += 28;
|
||||
recordcount++;
|
||||
|
||||
emr_selectobject_pen.type = 0x00000025; /* EMR_SELECTOBJECT */
|
||||
emr_selectobject_pen.size = 12;
|
||||
out_le_u32(emr_selectobject_pen.type, 0x00000025); /* EMR_SELECTOBJECT */
|
||||
out_le_u32(emr_selectobject_pen.size, 12);
|
||||
emr_selectobject_pen.ih_object = emr_createpen.ih_pen;
|
||||
bytecount += 12;
|
||||
recordcount++;
|
||||
|
||||
if (draw_background) {
|
||||
/* Make background from a rectangle */
|
||||
background.type = 0x0000002b; /* EMR_RECTANGLE */
|
||||
background.size = 24;
|
||||
background.box.top = 0;
|
||||
background.box.left = 0;
|
||||
background.box.right = width;
|
||||
background.box.bottom = height;
|
||||
out_le_u32(background.type, 0x0000002b); /* EMR_RECTANGLE */
|
||||
out_le_u32(background.size, 24);
|
||||
out_le_i32(background.box.top, 0);
|
||||
out_le_i32(background.box.left, 0);
|
||||
out_le_i32(background.box.right, width);
|
||||
out_le_i32(background.box.bottom, height);
|
||||
bytecount += 24;
|
||||
recordcount++;
|
||||
}
|
||||
@ -461,12 +460,12 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
rect = symbol->vector->rectangles;
|
||||
this_rectangle = 0;
|
||||
while (rect) {
|
||||
rectangle[this_rectangle].type = 0x0000002b; /* EMR_RECTANGLE */
|
||||
rectangle[this_rectangle].size = 24;
|
||||
rectangle[this_rectangle].box.top = (int32_t) rect->y;
|
||||
rectangle[this_rectangle].box.bottom = (int32_t) stripf(rect->y + rect->height);
|
||||
rectangle[this_rectangle].box.left = (int32_t) rect->x;
|
||||
rectangle[this_rectangle].box.right = (int32_t) stripf(rect->x + rect->width);
|
||||
out_le_u32(rectangle[this_rectangle].type, 0x0000002b); /* EMR_RECTANGLE */
|
||||
out_le_u32(rectangle[this_rectangle].size, 24);
|
||||
out_le_i32(rectangle[this_rectangle].box.top, rect->y);
|
||||
out_le_i32(rectangle[this_rectangle].box.bottom, stripf(rect->y + rect->height));
|
||||
out_le_i32(rectangle[this_rectangle].box.left, rect->x);
|
||||
out_le_i32(rectangle[this_rectangle].box.right, stripf(rect->x + rect->width));
|
||||
this_rectangle++;
|
||||
bytecount += 24;
|
||||
recordcount++;
|
||||
@ -482,26 +481,26 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
causes various different rendering issues for LibreOffice Draw and Inkscape, so using following hack */
|
||||
if (previous_diameter != circ->diameter + circ->width) { /* Drawing MaxiCode bullseye using overlayed discs */
|
||||
previous_diameter = circ->diameter + circ->width;
|
||||
radius = mul3dpf(0.5f, previous_diameter);
|
||||
radius = emf_mul3dpf(0.5f, previous_diameter);
|
||||
}
|
||||
circle[this_circle].type = 0x0000002a; /* EMR_ELLIPSE */
|
||||
circle[this_circle].size = 24;
|
||||
circle[this_circle].box.top = (int32_t) stripf(circ->y - radius);
|
||||
circle[this_circle].box.bottom = (int32_t) stripf(circ->y + radius);
|
||||
circle[this_circle].box.left = (int32_t) stripf(circ->x - radius);
|
||||
circle[this_circle].box.right = (int32_t) stripf(circ->x + radius);
|
||||
out_le_u32(circle[this_circle].type, 0x0000002a); /* EMR_ELLIPSE */
|
||||
out_le_u32(circle[this_circle].size, 24);
|
||||
out_le_i32(circle[this_circle].box.top, stripf(circ->y - radius));
|
||||
out_le_i32(circle[this_circle].box.bottom, stripf(circ->y + radius));
|
||||
out_le_i32(circle[this_circle].box.left, stripf(circ->x - radius));
|
||||
out_le_i32(circle[this_circle].box.right, stripf(circ->x + radius));
|
||||
this_circle++;
|
||||
bytecount += 24;
|
||||
recordcount++;
|
||||
|
||||
if (symbol->symbology == BARCODE_MAXICODE) { /* Drawing MaxiCode bullseye using overlayed discs */
|
||||
float inner_radius = radius - circ->width;
|
||||
circle[this_circle].type = 0x0000002a; /* EMR_ELLIPSE */
|
||||
circle[this_circle].size = 24;
|
||||
circle[this_circle].box.top = (int32_t) stripf(circ->y - inner_radius);
|
||||
circle[this_circle].box.bottom = (int32_t) stripf(circ->y + inner_radius);
|
||||
circle[this_circle].box.left = (int32_t) stripf(circ->x - inner_radius);
|
||||
circle[this_circle].box.right = (int32_t) stripf(circ->x + inner_radius);
|
||||
out_le_u32(circle[this_circle].type, 0x0000002a); /* EMR_ELLIPSE */
|
||||
out_le_u32(circle[this_circle].size, 24);
|
||||
out_le_i32(circle[this_circle].box.top, stripf(circ->y - inner_radius));
|
||||
out_le_i32(circle[this_circle].box.bottom, stripf(circ->y + inner_radius));
|
||||
out_le_i32(circle[this_circle].box.left, stripf(circ->x - inner_radius));
|
||||
out_le_i32(circle[this_circle].box.right, stripf(circ->x + inner_radius));
|
||||
this_circle++;
|
||||
bytecount += 24;
|
||||
recordcount++;
|
||||
@ -515,30 +514,30 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
hex = symbol->vector->hexagons;
|
||||
this_hexagon = 0;
|
||||
while (hex) {
|
||||
hexagon[this_hexagon].type = 0x00000003; /* EMR_POLYGON */
|
||||
hexagon[this_hexagon].size = 76;
|
||||
hexagon[this_hexagon].count = 6;
|
||||
out_le_u32(hexagon[this_hexagon].type, 0x00000003); /* EMR_POLYGON */
|
||||
out_le_u32(hexagon[this_hexagon].size, 76);
|
||||
out_le_u32(hexagon[this_hexagon].count, 6);
|
||||
|
||||
if (previous_diameter != hex->diameter) {
|
||||
previous_diameter = hex->diameter;
|
||||
radius = mul3dpf(0.5f, previous_diameter);
|
||||
half_radius = mul3dpf(0.25f, previous_diameter);
|
||||
half_sqrt3_radius = mul3dpf(0.43301270189221932338f, previous_diameter);
|
||||
radius = emf_mul3dpf(0.5f, previous_diameter);
|
||||
half_radius = emf_mul3dpf(0.25f, previous_diameter);
|
||||
half_sqrt3_radius = emf_mul3dpf(0.43301270189221932338f, previous_diameter);
|
||||
}
|
||||
|
||||
/* Note rotation done via world transform */
|
||||
hexagon[this_hexagon].a_points_a.x = (int32_t) hex->x;
|
||||
hexagon[this_hexagon].a_points_a.y = (int32_t) stripf(hex->y + radius);
|
||||
hexagon[this_hexagon].a_points_b.x = (int32_t) stripf(hex->x + half_sqrt3_radius);
|
||||
hexagon[this_hexagon].a_points_b.y = (int32_t) stripf(hex->y + half_radius);
|
||||
hexagon[this_hexagon].a_points_c.x = (int32_t) stripf(hex->x + half_sqrt3_radius);
|
||||
hexagon[this_hexagon].a_points_c.y = (int32_t) stripf(hex->y - half_radius);
|
||||
hexagon[this_hexagon].a_points_d.x = (int32_t) hex->x;
|
||||
hexagon[this_hexagon].a_points_d.y = (int32_t) stripf(hex->y - radius);
|
||||
hexagon[this_hexagon].a_points_e.x = (int32_t) stripf(hex->x - half_sqrt3_radius);
|
||||
hexagon[this_hexagon].a_points_e.y = (int32_t) stripf(hex->y - half_radius);
|
||||
hexagon[this_hexagon].a_points_f.x = (int32_t) stripf(hex->x - half_sqrt3_radius);
|
||||
hexagon[this_hexagon].a_points_f.y = (int32_t) stripf(hex->y + half_radius);
|
||||
out_le_i32(hexagon[this_hexagon].a_points_a.x, hex->x);
|
||||
out_le_i32(hexagon[this_hexagon].a_points_a.y, stripf(hex->y + radius));
|
||||
out_le_i32(hexagon[this_hexagon].a_points_b.x, stripf(hex->x + half_sqrt3_radius));
|
||||
out_le_i32(hexagon[this_hexagon].a_points_b.y, stripf(hex->y + half_radius));
|
||||
out_le_i32(hexagon[this_hexagon].a_points_c.x, stripf(hex->x + half_sqrt3_radius));
|
||||
out_le_i32(hexagon[this_hexagon].a_points_c.y, stripf(hex->y - half_radius));
|
||||
out_le_i32(hexagon[this_hexagon].a_points_d.x, hex->x);
|
||||
out_le_i32(hexagon[this_hexagon].a_points_d.y, stripf(hex->y - radius));
|
||||
out_le_i32(hexagon[this_hexagon].a_points_e.x, stripf(hex->x - half_sqrt3_radius));
|
||||
out_le_i32(hexagon[this_hexagon].a_points_e.y, stripf(hex->y - half_radius));
|
||||
out_le_i32(hexagon[this_hexagon].a_points_f.x, stripf(hex->x - half_sqrt3_radius));
|
||||
out_le_i32(hexagon[this_hexagon].a_points_f.y, stripf(hex->y + half_radius));
|
||||
|
||||
hexagon[this_hexagon].bounds.top = hexagon[this_hexagon].a_points_d.y;
|
||||
hexagon[this_hexagon].bounds.bottom = hexagon[this_hexagon].a_points_a.y;
|
||||
@ -554,12 +553,12 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
if (symbol->vector->strings) {
|
||||
bold = (symbol->output_options & BOLD_TEXT) && !is_upcean(symbol->symbology);
|
||||
memset(&emr_extcreatefontindirectw, 0, sizeof(emr_extcreatefontindirectw));
|
||||
emr_extcreatefontindirectw.type = 0x00000052; /* EMR_EXTCREATEFONTINDIRECTW */
|
||||
emr_extcreatefontindirectw.size = 104;
|
||||
emr_extcreatefontindirectw.ih_fonts = 3 + ih_ultra_offset;
|
||||
emr_extcreatefontindirectw.elw.height = (int32_t) fsize;
|
||||
emr_extcreatefontindirectw.elw.width = 0; /* automatic */
|
||||
emr_extcreatefontindirectw.elw.weight = bold ? 700 : 400;
|
||||
out_le_u32(emr_extcreatefontindirectw.type, 0x00000052); /* EMR_EXTCREATEFONTINDIRECTW */
|
||||
out_le_u32(emr_extcreatefontindirectw.size, 104);
|
||||
out_le_u32(emr_extcreatefontindirectw.ih_fonts, 3 + ih_ultra_offset);
|
||||
out_le_i32(emr_extcreatefontindirectw.elw.height, fsize);
|
||||
out_le_i32(emr_extcreatefontindirectw.elw.width, 0); /* automatic */
|
||||
out_le_i32(emr_extcreatefontindirectw.elw.weight, bold ? 700 : 400);
|
||||
emr_extcreatefontindirectw.elw.char_set = 0x00; /* ANSI_CHARSET */
|
||||
emr_extcreatefontindirectw.elw.out_precision = 0x00; /* OUT_DEFAULT_PRECIS */
|
||||
emr_extcreatefontindirectw.elw.clip_precision = 0x00; /* CLIP_DEFAULT_PRECIS */
|
||||
@ -568,21 +567,21 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
bytecount += 104;
|
||||
recordcount++;
|
||||
|
||||
emr_selectobject_font.type = 0x00000025; /* EMR_SELECTOBJECT */
|
||||
emr_selectobject_font.size = 12;
|
||||
out_le_u32(emr_selectobject_font.type, 0x00000025); /* EMR_SELECTOBJECT */
|
||||
out_le_u32(emr_selectobject_font.size, 12);
|
||||
emr_selectobject_font.ih_object = emr_extcreatefontindirectw.ih_fonts;
|
||||
bytecount += 12;
|
||||
recordcount++;
|
||||
|
||||
if (fsize2) {
|
||||
memcpy(&emr_extcreatefontindirectw2, &emr_extcreatefontindirectw, sizeof(emr_extcreatefontindirectw));
|
||||
emr_extcreatefontindirectw2.ih_fonts = 4 + ih_ultra_offset;
|
||||
emr_extcreatefontindirectw2.elw.height = (int32_t) fsize2;
|
||||
out_le_u32(emr_extcreatefontindirectw2.ih_fonts, 4 + ih_ultra_offset);
|
||||
out_le_i32(emr_extcreatefontindirectw2.elw.height, fsize2);
|
||||
bytecount += 104;
|
||||
recordcount++;
|
||||
|
||||
emr_selectobject_font2.type = 0x00000025; /* EMR_SELECTOBJECT */
|
||||
emr_selectobject_font2.size = 12;
|
||||
out_le_u32(emr_selectobject_font2.type, 0x00000025); /* EMR_SELECTOBJECT */
|
||||
out_le_u32(emr_selectobject_font2.size, 12);
|
||||
emr_selectobject_font2.ih_object = emr_extcreatefontindirectw2.ih_fonts;
|
||||
bytecount += 12;
|
||||
recordcount++;
|
||||
@ -590,22 +589,22 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
|
||||
/* Note select aligns counted below in strings loop */
|
||||
|
||||
emr_settextalign_centre.type = 0x00000016; /* EMR_SETTEXTALIGN */
|
||||
emr_settextalign_centre.size = 12;
|
||||
emr_settextalign_centre.text_alignment_mode = 0x0006 | 0x0018; /* TA_CENTER | TA_BASELINE */
|
||||
out_le_u32(emr_settextalign_centre.type, 0x00000016); /* EMR_SETTEXTALIGN */
|
||||
out_le_u32(emr_settextalign_centre.size, 12);
|
||||
out_le_u32(emr_settextalign_centre.text_alignment_mode, 0x0006 | 0x0018); /* TA_CENTER | TA_BASELINE */
|
||||
if (halign_left) {
|
||||
emr_settextalign_left.type = 0x00000016; /* EMR_SETTEXTALIGN */
|
||||
emr_settextalign_left.size = 12;
|
||||
emr_settextalign_left.text_alignment_mode = 0x0000 | 0x0018; /* TA_LEFT | TA_BASELINE */
|
||||
out_le_u32(emr_settextalign_left.type, 0x00000016); /* EMR_SETTEXTALIGN */
|
||||
out_le_u32(emr_settextalign_left.size, 12);
|
||||
out_le_u32(emr_settextalign_left.text_alignment_mode, 0x0000 | 0x0018); /* TA_LEFT | TA_BASELINE */
|
||||
}
|
||||
if (halign_right) {
|
||||
emr_settextalign_right.type = 0x00000016; /* EMR_SETTEXTALIGN */
|
||||
emr_settextalign_right.size = 12;
|
||||
emr_settextalign_right.text_alignment_mode = 0x0002 | 0x0018; /* TA_RIGHT | TA_BASELINE */
|
||||
out_le_u32(emr_settextalign_right.type, 0x00000016); /* EMR_SETTEXTALIGN */
|
||||
out_le_u32(emr_settextalign_right.size, 12);
|
||||
out_le_u32(emr_settextalign_right.text_alignment_mode, 0x0002 | 0x0018); /* TA_RIGHT | TA_BASELINE */
|
||||
}
|
||||
|
||||
emr_settextcolor.type = 0x0000018; /* EMR_SETTEXTCOLOR */
|
||||
emr_settextcolor.size = 12;
|
||||
out_le_u32(emr_settextcolor.type, 0x0000018); /* EMR_SETTEXTCOLOR */
|
||||
out_le_u32(emr_settextcolor.size, 12);
|
||||
emr_settextcolor.color.red = fgred;
|
||||
emr_settextcolor.color.green = fggrn;
|
||||
emr_settextcolor.color.blue = fgblu;
|
||||
@ -622,7 +621,6 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
current_halign = -1;
|
||||
while (string) {
|
||||
int utfle_len;
|
||||
int bumped_len;
|
||||
if (string->fsize != current_fsize) {
|
||||
string = string->next;
|
||||
continue;
|
||||
@ -636,45 +634,44 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
}
|
||||
assert(string->length > 0);
|
||||
utfle_len = emf_utfle_length(string->text, string->length);
|
||||
bumped_len = emf_bump_up(utfle_len);
|
||||
if (!(this_string[this_text] = (unsigned char *) malloc(bumped_len))) {
|
||||
text_bumped_lens[this_text] = emf_bump_up(utfle_len);
|
||||
if (!(this_string[this_text] = (unsigned char *) malloc(text_bumped_lens[this_text]))) {
|
||||
for (i = 0; i < this_text; i++) {
|
||||
free(this_string[i]);
|
||||
}
|
||||
strcpy(symbol->errtxt, "641: Insufficient memory for EMF string buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 641, "Insufficient memory for EMF string buffer");
|
||||
}
|
||||
memset(this_string[this_text], 0, bumped_len);
|
||||
text[this_text].type = 0x00000054; /* EMR_EXTTEXTOUTW */
|
||||
text[this_text].size = 76 + bumped_len;
|
||||
text[this_text].bounds.top = 0; /* ignored */
|
||||
text[this_text].bounds.left = 0; /* ignored */
|
||||
text[this_text].bounds.right = 0xffffffff; /* ignored */
|
||||
text[this_text].bounds.bottom = 0xffffffff; /* ignored */
|
||||
text[this_text].i_graphics_mode = 0x00000002; /* GM_ADVANCED */
|
||||
text[this_text].ex_scale = 1.0f;
|
||||
text[this_text].ey_scale = 1.0f;
|
||||
memset(this_string[this_text], 0, text_bumped_lens[this_text]);
|
||||
out_le_u32(text[this_text].type, 0x00000054); /* EMR_EXTTEXTOUTW */
|
||||
out_le_u32(text[this_text].size, 76 + text_bumped_lens[this_text]);
|
||||
out_le_i32(text[this_text].bounds.top, 0); /* ignored */
|
||||
out_le_i32(text[this_text].bounds.left, 0); /* ignored */
|
||||
out_le_i32(text[this_text].bounds.right, 0xffffffff); /* ignored */
|
||||
out_le_i32(text[this_text].bounds.bottom, 0xffffffff); /* ignored */
|
||||
out_le_u32(text[this_text].i_graphics_mode, 0x00000002); /* GM_ADVANCED */
|
||||
out_le_float(text[this_text].ex_scale, 1.0f);
|
||||
out_le_float(text[this_text].ey_scale, 1.0f);
|
||||
/* 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 */
|
||||
text[this_text].w_emr_text.reference.x = (int32_t) (string->x + gws_left_fudge);
|
||||
out_le_i32(text[this_text].w_emr_text.reference.x, string->x + gws_left_fudge);
|
||||
} 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 */
|
||||
text[this_text].w_emr_text.reference.x = (int32_t) (string->x - gws_right_fudge);
|
||||
out_le_i32(text[this_text].w_emr_text.reference.x, string->x - gws_right_fudge);
|
||||
} else {
|
||||
text[this_text].w_emr_text.reference.x = (int32_t) string->x;
|
||||
out_le_i32(text[this_text].w_emr_text.reference.x, string->x);
|
||||
}
|
||||
text[this_text].w_emr_text.reference.y = (int32_t) string->y;
|
||||
text[this_text].w_emr_text.chars = utfle_len;
|
||||
text[this_text].w_emr_text.off_string = 76;
|
||||
text[this_text].w_emr_text.options = 0;
|
||||
text[this_text].w_emr_text.rectangle.top = 0;
|
||||
text[this_text].w_emr_text.rectangle.left = 0;
|
||||
text[this_text].w_emr_text.rectangle.right = 0xffffffff;
|
||||
text[this_text].w_emr_text.rectangle.bottom = 0xffffffff;
|
||||
text[this_text].w_emr_text.off_dx = 0;
|
||||
out_le_i32(text[this_text].w_emr_text.reference.y, string->y);
|
||||
out_le_u32(text[this_text].w_emr_text.chars, utfle_len);
|
||||
out_le_u32(text[this_text].w_emr_text.off_string, 76);
|
||||
out_le_u32(text[this_text].w_emr_text.options, 0);
|
||||
out_le_i32(text[this_text].w_emr_text.rectangle.top, 0);
|
||||
out_le_i32(text[this_text].w_emr_text.rectangle.left, 0);
|
||||
out_le_i32(text[this_text].w_emr_text.rectangle.right, 0xffffffff);
|
||||
out_le_i32(text[this_text].w_emr_text.rectangle.bottom, 0xffffffff);
|
||||
out_le_u32(text[this_text].w_emr_text.off_dx, 0);
|
||||
emf_utfle_copy(this_string[this_text], string->text, string->length);
|
||||
bytecount += 76 + bumped_len;
|
||||
bytecount += 76 + text_bumped_lens[this_text];
|
||||
recordcount++;
|
||||
|
||||
this_text++;
|
||||
@ -685,10 +682,10 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
assert(this_text == string_count);
|
||||
|
||||
/* Create EOF record */
|
||||
emr_eof.type = 0x0000000e; /* EMR_EOF */
|
||||
emr_eof.size = 20; /* Assuming no palette entries */
|
||||
emr_eof.n_pal_entries = 0;
|
||||
emr_eof.off_pal_entries = 0;
|
||||
out_le_u32(emr_eof.type, 0x0000000e); /* EMR_EOF */
|
||||
out_le_u32(emr_eof.size, 20); /* Assuming no palette entries */
|
||||
out_le_u32(emr_eof.n_pal_entries, 0);
|
||||
out_le_u32(emr_eof.off_pal_entries, 0);
|
||||
emr_eof.size_last = emr_eof.size;
|
||||
bytecount += 20;
|
||||
recordcount++;
|
||||
@ -699,70 +696,60 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
|
||||
}
|
||||
|
||||
/* Put final counts in header */
|
||||
emr_header.emf_header.bytes = bytecount;
|
||||
emr_header.emf_header.records = recordcount;
|
||||
out_le_u32(emr_header.emf_header.bytes, bytecount);
|
||||
out_le_u32(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")) {
|
||||
return errtxtf(ZINT_ERROR_FILE_ACCESS, symbol, 640, "Could not open EMF output file (%1$d: %2$s)", fmp->err,
|
||||
strerror(fmp->err));
|
||||
}
|
||||
|
||||
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], text_bumped_lens[i], 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)) {
|
||||
errtxtf(0, symbol, 644, "Incomplete write of EMF output (%1$d: %2$s)", 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)) {
|
||||
return errtxtf(ZINT_ERROR_FILE_WRITE, symbol, 941, "Failure on closing EMF output file (%1$d: %2$s)",
|
||||
fmp->err, strerror(fmp->err));
|
||||
}
|
||||
return error_number;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* emf.h - header structure for Microsoft EMF */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2016-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2016-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -35,45 +35,47 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef OUT_USE_PRAGMA_PACK
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
typedef struct rect_l {
|
||||
int32_t left;
|
||||
int32_t top;
|
||||
int32_t right;
|
||||
int32_t bottom;
|
||||
} rect_l_t;
|
||||
} OUT_PACK rect_l_t;
|
||||
|
||||
typedef struct size_l {
|
||||
uint32_t cx;
|
||||
uint32_t cy;
|
||||
} size_l_t;
|
||||
} OUT_PACK size_l_t;
|
||||
|
||||
typedef struct point_l {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} point_l_t;
|
||||
} OUT_PACK point_l_t;
|
||||
|
||||
typedef struct color_ref {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
uint8_t reserved;
|
||||
} color_ref_t;
|
||||
} OUT_PACK color_ref_t;
|
||||
|
||||
typedef struct log_brush_ex {
|
||||
uint32_t brush_style;
|
||||
color_ref_t color;
|
||||
uint32_t brush_hatch;
|
||||
} log_brush_ex_t;
|
||||
} OUT_PACK log_brush_ex_t;
|
||||
|
||||
typedef struct log_pen {
|
||||
uint32_t pen_style;
|
||||
point_l_t width;
|
||||
color_ref_t color_ref;
|
||||
} log_pen_t;
|
||||
} OUT_PACK log_pen_t;
|
||||
|
||||
typedef struct log_font {
|
||||
int32_t height;
|
||||
@ -90,7 +92,7 @@ extern "C" {
|
||||
uint8_t quality;
|
||||
uint8_t pitch_and_family;
|
||||
unsigned char facename[64];
|
||||
} log_font_t;
|
||||
} OUT_PACK log_font_t;
|
||||
|
||||
typedef struct emr_text {
|
||||
point_l_t reference;
|
||||
@ -99,7 +101,7 @@ extern "C" {
|
||||
uint32_t options;
|
||||
rect_l_t rectangle;
|
||||
uint32_t off_dx;
|
||||
} emr_text_t;
|
||||
} OUT_PACK emr_text_t;
|
||||
|
||||
typedef struct emf_header {
|
||||
rect_l_t bounds;
|
||||
@ -121,19 +123,19 @@ extern "C" {
|
||||
uint32_t b_open_gl;
|
||||
/* HeaderExtension2 Object */
|
||||
size_l_t micrometers;
|
||||
} emf_header_t;
|
||||
} OUT_PACK emf_header_t;
|
||||
|
||||
typedef struct emr_header {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
emf_header_t emf_header;
|
||||
} emr_header_t;
|
||||
} OUT_PACK emr_header_t;
|
||||
|
||||
typedef struct emr_mapmode {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t mapmode;
|
||||
} emr_mapmode_t;
|
||||
} OUT_PACK emr_mapmode_t;
|
||||
|
||||
typedef struct emr_setworldtransform {
|
||||
uint32_t type;
|
||||
@ -144,39 +146,39 @@ extern "C" {
|
||||
float m22;
|
||||
float dx;
|
||||
float dy;
|
||||
} emr_setworldtransform_t;
|
||||
} OUT_PACK emr_setworldtransform_t;
|
||||
|
||||
typedef struct emr_createbrushindirect {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t ih_brush;
|
||||
log_brush_ex_t log_brush;
|
||||
} emr_createbrushindirect_t;
|
||||
} OUT_PACK emr_createbrushindirect_t;
|
||||
|
||||
typedef struct emr_createpen {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t ih_pen;
|
||||
log_pen_t log_pen;
|
||||
} emr_createpen_t;
|
||||
} OUT_PACK emr_createpen_t;
|
||||
|
||||
typedef struct emr_selectobject {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t ih_object;
|
||||
} emr_selectobject_t;
|
||||
} OUT_PACK emr_selectobject_t;
|
||||
|
||||
typedef struct emr_rectangle {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
rect_l_t box;
|
||||
} emr_rectangle_t;
|
||||
} OUT_PACK emr_rectangle_t;
|
||||
|
||||
typedef struct emr_ellipse {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
rect_l_t box;
|
||||
} emr_ellipse_t;
|
||||
} OUT_PACK emr_ellipse_t;
|
||||
|
||||
typedef struct emr_polygon {
|
||||
uint32_t type;
|
||||
@ -189,26 +191,26 @@ extern "C" {
|
||||
point_l_t a_points_d;
|
||||
point_l_t a_points_e;
|
||||
point_l_t a_points_f;
|
||||
} emr_polygon_t;
|
||||
} OUT_PACK emr_polygon_t;
|
||||
|
||||
typedef struct emr_extcreatefontindirectw {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t ih_fonts;
|
||||
log_font_t elw;
|
||||
} emr_extcreatefontindirectw_t;
|
||||
} OUT_PACK emr_extcreatefontindirectw_t;
|
||||
|
||||
typedef struct emr_settextalign {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t text_alignment_mode;
|
||||
} emr_settextalign_t;
|
||||
} OUT_PACK emr_settextalign_t;
|
||||
|
||||
typedef struct emr_settextcolor {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
color_ref_t color;
|
||||
} emr_settextcolor_t;
|
||||
} OUT_PACK emr_settextcolor_t;
|
||||
|
||||
typedef struct emr_exttextoutw {
|
||||
uint32_t type;
|
||||
@ -218,7 +220,7 @@ extern "C" {
|
||||
float ex_scale;
|
||||
float ey_scale;
|
||||
emr_text_t w_emr_text;
|
||||
} emr_exttextoutw_t;
|
||||
} OUT_PACK emr_exttextoutw_t;
|
||||
|
||||
typedef struct emr_eof {
|
||||
uint32_t type;
|
||||
@ -226,20 +228,22 @@ extern "C" {
|
||||
uint32_t n_pal_entries;
|
||||
uint32_t off_pal_entries;
|
||||
uint32_t size_last;
|
||||
} emr_eof_t;
|
||||
} OUT_PACK emr_eof_t;
|
||||
|
||||
typedef struct box {
|
||||
emr_rectangle_t top;
|
||||
emr_rectangle_t bottom;
|
||||
emr_rectangle_t left;
|
||||
emr_rectangle_t right;
|
||||
} box_t;
|
||||
} OUT_PACK box_t;
|
||||
|
||||
#ifdef OUT_USE_PRAGMA_PACK
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
#endif /* Z_EMF_H */
|
||||
|
464
backend/filemem.c
Normal file
@ -0,0 +1,464 @@
|
||||
/* filemem.c - write to file/memory abstraction */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2023-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the project nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#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) != nitems) {
|
||||
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 file or memory, 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 */
|
||||
va_end(ap);
|
||||
return ret ? 1 : fm_seterr(fmp, errno);
|
||||
}
|
||||
|
||||
/* 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; if file and `err` not set, test `ferror()` also */
|
||||
INTERNAL int fm_error(struct filemem *restrict const fmp) {
|
||||
assert(fmp);
|
||||
if (fmp->err == 0 && !(fmp->flags & BARCODE_MEMORY_FILE) && ferror(fmp->fp)) {
|
||||
(void) fm_seterr(fmp, EIO);
|
||||
}
|
||||
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 : */
|
103
backend/filemem.h
Normal file
@ -0,0 +1,103 @@
|
||||
/* filemem.h - write to file/memory abstraction */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2023-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the project nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
#ifndef Z_FILEMEM_H
|
||||
#define Z_FILEMEM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include <stdio.h>
|
||||
#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 file or memory, returning 1 on success, 0 on failure */
|
||||
INTERNAL int fm_printf(struct filemem *restrict const fmp, const char *format, ...) ZINT_FORMAT_PRINTF(2, 3);
|
||||
|
||||
/* 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; if file and `err` not set, test `ferror()` also */
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
#endif /* Z_FILEMEM_H */
|
@ -1,7 +1,7 @@
|
||||
/* general_field.c - Handles general field compaction (GS1 DataBar and composites) */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2019-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -39,13 +39,13 @@ static const char isoiec_puncs[] = "!\"%&'()*+,-./:;<=>?_ "; /* Note contains sp
|
||||
|
||||
/* Returns type of char at `i`. FNC1 counted as NUMERIC. Returns 0 if invalid char */
|
||||
static int general_field_type(const char *general_field, const int i) {
|
||||
if (general_field[i] == '[' || z_isdigit(general_field[i])) {
|
||||
if (general_field[i] == '\x1D' || z_isdigit(general_field[i])) {
|
||||
return NUMERIC;
|
||||
}
|
||||
if (z_isupper(general_field[i]) || posn(alphanum_puncs, general_field[i]) != -1) {
|
||||
return ALPHANUMERIC;
|
||||
}
|
||||
if (is_sane(IS_ISOIEC_F, (const unsigned char *) general_field + i, 1)) {
|
||||
if (!not_sane(IS_ISOIEC_F, (const unsigned char *) general_field + i, 1)) {
|
||||
return ISOIEC;
|
||||
}
|
||||
return 0;
|
||||
@ -113,8 +113,8 @@ INTERNAL int general_field_encode(const char *general_field, const int general_f
|
||||
bp = bin_append_posn(0, 4, binary_string, bp); /* Alphanumeric latch "0000" */
|
||||
mode = ALPHANUMERIC;
|
||||
} else {
|
||||
d1 = general_field[i] == '[' ? 10 : ctoi(general_field[i]);
|
||||
d2 = general_field[i + 1] == '[' ? 10 : ctoi(general_field[i + 1]);
|
||||
d1 = general_field[i] == '\x1D' ? 10 : ctoi(general_field[i]);
|
||||
d2 = general_field[i + 1] == '\x1D' ? 10 : ctoi(general_field[i + 1]);
|
||||
bp = bin_append_posn((11 * d1) + d2 + 8, 7, binary_string, bp);
|
||||
i += 2;
|
||||
}
|
||||
@ -132,7 +132,7 @@ INTERNAL int general_field_encode(const char *general_field, const int general_f
|
||||
}
|
||||
break;
|
||||
case ALPHANUMERIC:
|
||||
if (general_field[i] == '[') {
|
||||
if (general_field[i] == '\x1D') {
|
||||
/* 7.2.5.5.2/5.4.2 a) */
|
||||
bp = bin_append_posn(15, 5, binary_string, bp); /* "01111" */
|
||||
mode = NUMERIC;
|
||||
@ -162,7 +162,7 @@ INTERNAL int general_field_encode(const char *general_field, const int general_f
|
||||
}
|
||||
break;
|
||||
case ISOIEC:
|
||||
if (general_field[i] == '[') {
|
||||
if (general_field[i] == '\x1D') {
|
||||
/* 7.2.5.5.3/5.4.3 a) */
|
||||
bp = bin_append_posn(15, 5, binary_string, bp); /* "01111" */
|
||||
mode = NUMERIC;
|
||||
|
442
backend/gif.c
@ -1,7 +1,7 @@
|
||||
/* gif.c - Handles output to gif file */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -32,58 +32,43 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#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 */
|
||||
/* Set LZW buffer paging size to this in expectation that compressed data will fit for typical scalings */
|
||||
#define GIF_LZW_PAGE_SIZE 0x100000 /* Megabyte */
|
||||
|
||||
typedef struct s_statestruct {
|
||||
struct gif_state {
|
||||
struct filemem *fmp;
|
||||
unsigned char *pOut;
|
||||
const unsigned char *pIn;
|
||||
unsigned int InLen;
|
||||
unsigned int OutLength;
|
||||
unsigned int OutPosCur;
|
||||
unsigned int OutByteCountPos;
|
||||
const unsigned char *pInEnd;
|
||||
size_t OutLength;
|
||||
size_t OutPosCur;
|
||||
size_t OutByteCountPos;
|
||||
unsigned short ClearCode;
|
||||
unsigned short FreeCode;
|
||||
char fByteCountByteSet;
|
||||
char fOutPaged;
|
||||
unsigned char OutBitsFree;
|
||||
unsigned short NodeAxon[4096];
|
||||
unsigned short NodeNext[4096];
|
||||
unsigned char NodePix[4096];
|
||||
unsigned char colourCode[10];
|
||||
unsigned char colourPaletteIndex[10];
|
||||
int colourCount;
|
||||
} statestruct;
|
||||
unsigned char map[256];
|
||||
};
|
||||
|
||||
/* Transform a Pixel to a lzw colourmap index and move to next pixel.
|
||||
* All colour values are listed in colourCode with corresponding palette index
|
||||
*/
|
||||
static unsigned char NextPaletteIndex(statestruct *pState)
|
||||
{
|
||||
unsigned char pixelColour;
|
||||
int colourIndex;
|
||||
pixelColour = *(pState->pIn);
|
||||
(pState->pIn)++;
|
||||
(pState->InLen)--;
|
||||
for (colourIndex = 0; colourIndex < pState->colourCount; colourIndex++) {
|
||||
if (pixelColour == pState->colourCode[colourIndex])
|
||||
return pState->colourPaletteIndex[colourIndex];
|
||||
|
||||
}
|
||||
return 0; /* Not reached */
|
||||
}
|
||||
|
||||
|
||||
static int BufferNextByte(statestruct *pState) {
|
||||
static void gif_BufferNextByte(struct gif_state *pState) {
|
||||
(pState->OutPosCur)++;
|
||||
if (pState->fOutPaged && pState->OutPosCur + 2 >= pState->OutLength) {
|
||||
/* Keep last 256 bytes so `OutByteCountPos` within range */
|
||||
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;
|
||||
}
|
||||
/* Check if this position is a byte count position
|
||||
* fg_f_bytecountbyte_set indicates, if byte count position bytes should be
|
||||
* `fByteCountByteSet` indicates, if byte count position bytes should be
|
||||
* inserted in general.
|
||||
* If this is true, and the distance to the last byte count position is 256
|
||||
* (e.g. 255 bytes in between), a byte count byte is inserted, and the value
|
||||
@ -94,34 +79,22 @@ static int BufferNextByte(statestruct *pState) {
|
||||
pState->OutByteCountPos = pState->OutPosCur;
|
||||
(pState->OutPosCur)++;
|
||||
}
|
||||
if (pState->OutPosCur >= pState->OutLength) {
|
||||
unsigned char *pOut;
|
||||
pState->OutLength += GIF_LZW_PAGE_SIZE;
|
||||
/* Note pState->pOut not free()d by realloc() on failure */
|
||||
if (!(pOut = (unsigned char *) realloc(pState->pOut, pState->OutLength))) {
|
||||
return 1;
|
||||
}
|
||||
pState->pOut = pOut;
|
||||
}
|
||||
|
||||
(pState->pOut)[pState->OutPosCur] = 0x00;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int AddCodeToBuffer(statestruct *pState, unsigned short CodeIn, unsigned char CodeBits) {
|
||||
static void gif_AddCodeToBuffer(struct gif_state *pState, unsigned short CodeIn, unsigned char CodeBits) {
|
||||
/* Check, if we may fill up the current byte completely */
|
||||
if (CodeBits >= pState->OutBitsFree) {
|
||||
(pState->pOut)[pState->OutPosCur] |= (unsigned char) (CodeIn << (8 - pState->OutBitsFree));
|
||||
if (BufferNextByte(pState))
|
||||
return -1;
|
||||
gif_BufferNextByte(pState);
|
||||
CodeIn = (unsigned short) (CodeIn >> pState->OutBitsFree);
|
||||
CodeBits -= pState->OutBitsFree;
|
||||
pState->OutBitsFree = 8;
|
||||
/* Write a full byte if there are at least 8 code bits left */
|
||||
if (CodeBits >= pState->OutBitsFree) {
|
||||
(pState->pOut)[pState->OutPosCur] = (unsigned char) CodeIn;
|
||||
if (BufferNextByte(pState))
|
||||
return -1;
|
||||
gif_BufferNextByte(pState);
|
||||
CodeIn = (unsigned short) (CodeIn >> 8);
|
||||
CodeBits -= 8;
|
||||
}
|
||||
@ -131,17 +104,16 @@ static int AddCodeToBuffer(statestruct *pState, unsigned short CodeIn, unsigned
|
||||
(pState->pOut)[pState->OutPosCur] |= (unsigned char) (CodeIn << (8 - pState->OutBitsFree));
|
||||
pState->OutBitsFree -= CodeBits;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void FlushStringTable(statestruct *pState) {
|
||||
static void gif_FlushStringTable(struct gif_state *pState) {
|
||||
unsigned short Pos;
|
||||
for (Pos = 0; Pos < pState->ClearCode; Pos++) {
|
||||
(pState->NodeAxon)[Pos] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned short FindPixelOutlet(statestruct *pState, unsigned short HeadNode, unsigned char Byte) {
|
||||
static unsigned short gif_FindPixelOutlet(struct gif_state *pState, unsigned short HeadNode, unsigned char Byte) {
|
||||
unsigned short Outlet;
|
||||
|
||||
Outlet = (pState->NodeAxon)[HeadNode];
|
||||
@ -153,26 +125,27 @@ static unsigned short FindPixelOutlet(statestruct *pState, unsigned short HeadNo
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int NextCode(statestruct *pState, unsigned char *pPixelValueCur, unsigned char CodeBits) {
|
||||
static int gif_NextCode(struct gif_state *pState, unsigned char *pPixelValueCur, unsigned char CodeBits) {
|
||||
unsigned short UpNode;
|
||||
unsigned short DownNode;
|
||||
/* start with the root node for last pixel chain */
|
||||
UpNode = *pPixelValueCur;
|
||||
if ((pState->InLen) == 0)
|
||||
return AddCodeToBuffer(pState, UpNode, CodeBits);
|
||||
|
||||
*pPixelValueCur = NextPaletteIndex(pState);
|
||||
if (pState->pIn == pState->pInEnd) {
|
||||
gif_AddCodeToBuffer(pState, UpNode, CodeBits);
|
||||
return 0;
|
||||
}
|
||||
*pPixelValueCur = pState->map[*pState->pIn++];
|
||||
/* Follow the string table and the data stream to the end of the longest string that has a code */
|
||||
while (0 != (DownNode = FindPixelOutlet(pState, UpNode, *pPixelValueCur))) {
|
||||
while (0 != (DownNode = gif_FindPixelOutlet(pState, UpNode, *pPixelValueCur))) {
|
||||
UpNode = DownNode;
|
||||
if ((pState->InLen) == 0)
|
||||
return AddCodeToBuffer(pState, UpNode, CodeBits);
|
||||
|
||||
*pPixelValueCur = NextPaletteIndex(pState);
|
||||
if (pState->pIn == pState->pInEnd) {
|
||||
gif_AddCodeToBuffer(pState, UpNode, CodeBits);
|
||||
return 0;
|
||||
}
|
||||
*pPixelValueCur = pState->map[*pState->pIn++];
|
||||
}
|
||||
/* Submit 'UpNode' which is the code of the longest string */
|
||||
if (AddCodeToBuffer(pState, UpNode, CodeBits))
|
||||
return -1;
|
||||
gif_AddCodeToBuffer(pState, UpNode, CodeBits);
|
||||
/* ... and extend the string by appending 'PixelValueCur' */
|
||||
/* Create a successor node for 'PixelValueCur' whose code is 'freecode' */
|
||||
(pState->NodePix)[pState->FreeCode] = *pPixelValueCur;
|
||||
@ -190,15 +163,15 @@ static int NextCode(statestruct *pState, unsigned char *pPixelValueCur, unsigned
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gif_lzw(statestruct *pState, int paletteBitSize) {
|
||||
static int gif_lzw(struct gif_state *pState, int paletteBitSize) {
|
||||
unsigned char PixelValueCur;
|
||||
unsigned char CodeBits;
|
||||
unsigned short Pos;
|
||||
|
||||
/* > Get first data byte */
|
||||
if (pState->InLen == 0)
|
||||
if (pState->pIn == pState->pInEnd)
|
||||
return 0;
|
||||
PixelValueCur = NextPaletteIndex(pState);
|
||||
PixelValueCur = pState->map[*pState->pIn++];
|
||||
/* Number of bits per data item (=pixel)
|
||||
* We need at least a value of 2, otherwise the cc and eoi code consumes
|
||||
* the whole string table
|
||||
@ -211,45 +184,32 @@ static int gif_lzw(statestruct *pState, int paletteBitSize) {
|
||||
pState->ClearCode = (1 << paletteBitSize);
|
||||
pState->FreeCode = pState->ClearCode + 2;
|
||||
pState->OutBitsFree = 8;
|
||||
pState->OutPosCur = -1;
|
||||
pState->OutPosCur = 0;
|
||||
pState->fByteCountByteSet = 0;
|
||||
|
||||
if (BufferNextByte(pState))
|
||||
return 0;
|
||||
|
||||
for (Pos = 0; Pos < pState->ClearCode; Pos++)
|
||||
(pState->NodePix)[Pos] = (unsigned char) Pos;
|
||||
|
||||
FlushStringTable(pState);
|
||||
gif_FlushStringTable(pState);
|
||||
|
||||
/* Write what the GIF specification calls the "code size". */
|
||||
(pState->pOut)[pState->OutPosCur] = paletteBitSize;
|
||||
/* Reserve first bytecount byte */
|
||||
if (BufferNextByte(pState))
|
||||
return 0;
|
||||
gif_BufferNextByte(pState);
|
||||
pState->OutByteCountPos = pState->OutPosCur;
|
||||
if (BufferNextByte(pState))
|
||||
return 0;
|
||||
gif_BufferNextByte(pState);
|
||||
pState->fByteCountByteSet = 1;
|
||||
/* Submit one 'ClearCode' as the first code */
|
||||
if (AddCodeToBuffer(pState, pState->ClearCode, CodeBits))
|
||||
return 0;
|
||||
gif_AddCodeToBuffer(pState, pState->ClearCode, CodeBits);
|
||||
|
||||
for (;;) {
|
||||
int Res;
|
||||
/* generate and save the next code, which may consist of multiple input pixels. */
|
||||
Res = NextCode(pState, &PixelValueCur, CodeBits);
|
||||
if (Res < 0)
|
||||
return 0;
|
||||
/* Check for end of data stream */
|
||||
if (!Res) {
|
||||
if (!gif_NextCode(pState, &PixelValueCur, CodeBits)) { /* Check for end of data stream */
|
||||
/* submit 'eoi' as the last item of the code stream */
|
||||
if (AddCodeToBuffer(pState, (unsigned short) (pState->ClearCode + 1), CodeBits))
|
||||
return 0;
|
||||
gif_AddCodeToBuffer(pState, (unsigned short) (pState->ClearCode + 1), CodeBits);
|
||||
pState->fByteCountByteSet = 0;
|
||||
if (pState->OutBitsFree < 8) {
|
||||
if (BufferNextByte(pState))
|
||||
return 0;
|
||||
gif_BufferNextByte(pState);
|
||||
}
|
||||
/* > Update last bytecount byte; */
|
||||
if (pState->OutByteCountPos < pState->OutPosCur) {
|
||||
@ -257,17 +217,16 @@ static int gif_lzw(statestruct *pState, int paletteBitSize) {
|
||||
= (unsigned char) (pState->OutPosCur - pState->OutByteCountPos - 1);
|
||||
}
|
||||
pState->OutPosCur++;
|
||||
return pState->OutPosCur;
|
||||
return 1;
|
||||
}
|
||||
/* Check for currently last code */
|
||||
if (pState->FreeCode == (1U << CodeBits))
|
||||
CodeBits++;
|
||||
pState->FreeCode++;
|
||||
/* Check for full stringtable */
|
||||
/* Check for full stringtable - for widest compatibility with gif decoders, empty when 0xfff, not 0x1000 */
|
||||
if (pState->FreeCode == 0xfff) {
|
||||
FlushStringTable(pState);
|
||||
if (AddCodeToBuffer(pState, pState->ClearCode, CodeBits))
|
||||
return 0;
|
||||
gif_FlushStringTable(pState);
|
||||
gif_AddCodeToBuffer(pState, pState->ClearCode, CodeBits);
|
||||
|
||||
CodeBits = (unsigned char) (1 + paletteBitSize);
|
||||
pState->FreeCode = (unsigned short) (pState->ClearCode + 2);
|
||||
@ -279,45 +238,50 @@ 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];
|
||||
FILE *gif_file;
|
||||
unsigned short usTemp;
|
||||
int byte_out;
|
||||
int colourCount;
|
||||
unsigned char paletteRGB[10][3];
|
||||
int paletteCount, paletteCountCur, paletteIndex;
|
||||
unsigned int pixelIndex;
|
||||
int paletteCount, i;
|
||||
int paletteBitSize;
|
||||
int paletteSize;
|
||||
statestruct State;
|
||||
struct gif_state State;
|
||||
int transparent_index;
|
||||
int bgindex = -1, fgindex = -1;
|
||||
const int output_to_stdout = symbol->output_options & BARCODE_STDOUT;
|
||||
|
||||
unsigned char backgroundColourIndex;
|
||||
unsigned char RGBCur[3];
|
||||
unsigned char RGBUnused[3] = {0,0,0};
|
||||
static const unsigned char RGBUnused[3] = {0,0,0};
|
||||
unsigned char RGBfg[3];
|
||||
unsigned char RGBbg[3];
|
||||
unsigned char fgalpha;
|
||||
unsigned char bgalpha;
|
||||
|
||||
int colourIndex;
|
||||
|
||||
int fFound;
|
||||
|
||||
unsigned char pixelColour;
|
||||
unsigned int bitmapSize = symbol->bitmap_height * symbol->bitmap_width;
|
||||
|
||||
/* Allow for overhead of 4 == code size + byte count + overflow byte + zero terminator */
|
||||
unsigned int lzoutbufSize = bitmapSize + 4;
|
||||
if (lzoutbufSize > GIF_LZW_PAGE_SIZE) {
|
||||
lzoutbufSize = GIF_LZW_PAGE_SIZE;
|
||||
}
|
||||
const size_t bitmapSize = (size_t) symbol->bitmap_height * symbol->bitmap_width;
|
||||
|
||||
(void) out_colour_get_rgb(symbol->fgcolour, &RGBfg[0], &RGBfg[1], &RGBfg[2], &fgalpha);
|
||||
(void) out_colour_get_rgb(symbol->bgcolour, &RGBbg[0], &RGBbg[1], &RGBbg[2], &bgalpha);
|
||||
|
||||
/* prepare state array */
|
||||
State.pIn = pixelbuf;
|
||||
State.pInEnd = pixelbuf + bitmapSize;
|
||||
/* Allow for overhead of 4 == code size + byte count + overflow byte + zero terminator */
|
||||
State.OutLength = bitmapSize + 4;
|
||||
State.fOutPaged = State.OutLength > GIF_LZW_PAGE_SIZE;
|
||||
if (State.fOutPaged) {
|
||||
State.OutLength = GIF_LZW_PAGE_SIZE;
|
||||
}
|
||||
if (!(State.pOut = (unsigned char *) malloc(State.OutLength))) {
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 614, "Insufficient memory for GIF LZW buffer");
|
||||
}
|
||||
|
||||
State.fmp = &fm;
|
||||
|
||||
/* Open output file in binary mode */
|
||||
if (!fm_open(State.fmp, symbol, "wb")) {
|
||||
errtxtf(0, symbol, 611, "Could not open GIF output file (%1$d: %2$s)", State.fmp->err,
|
||||
strerror(State.fmp->err));
|
||||
free(State.pOut);
|
||||
return ZINT_ERROR_FILE_ACCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a table of the used palette items.
|
||||
* Currently, there are the following 10 colour codes:
|
||||
@ -332,154 +296,82 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
|
||||
* 'G': green
|
||||
* 'K': black
|
||||
* '0' and '1' may be identical to one of the other values
|
||||
*
|
||||
* A data structure is set up as follows:
|
||||
* state.colourCode: list of colour codes
|
||||
* paletteIndex: palette index of the corresponding colour code
|
||||
* There are colourCount entries in the upper lists.
|
||||
* paletteRGB: RGB value at the palette position
|
||||
* There are paletteCount entries.
|
||||
* This value is smaller to colourCount, if multiple colour codes have the
|
||||
* same RGB value and point to the same palette value.
|
||||
* Example:
|
||||
* 0 1 W K are present. 0 is equal to white, while 1 is blue
|
||||
* The resulting tables are:
|
||||
* paletteItem: ['0']=0 (white), ['1']=1 (blue), ['W']=0 (white),
|
||||
* ['K']=2 (black)
|
||||
* Thus, there are 4 colour codes and 3 palette entries.
|
||||
|
||||
*/
|
||||
colourCount = 0;
|
||||
paletteCount = 0;
|
||||
/* loop over all pixels */
|
||||
for (pixelIndex = 0; pixelIndex < bitmapSize; pixelIndex++) {
|
||||
fFound = 0;
|
||||
/* get pixel colour code */
|
||||
pixelColour = pixelbuf[pixelIndex];
|
||||
/* look, if colour code is already in colour list */
|
||||
for (colourIndex = 0; colourIndex < colourCount; colourIndex++) {
|
||||
if ((State.colourCode)[colourIndex] == pixelColour) {
|
||||
fFound = 1;
|
||||
break;
|
||||
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' };
|
||||
for (i = 0; i < 8; i++) {
|
||||
State.map[ultra_chars[i]] = i;
|
||||
out_colour_char_to_rgb(ultra_chars[i], &paletteRGB[i][0], &paletteRGB[i][1], &paletteRGB[i][2]);
|
||||
}
|
||||
paletteCount = 8;
|
||||
paletteBitSize = 3;
|
||||
|
||||
/* For Ultracode, have foreground only if have bind/box */
|
||||
if (symbol->border_width > 0 && (symbol->output_options & (BARCODE_BIND | BARCODE_BOX | BARCODE_BIND_TOP))) {
|
||||
/* Check whether can re-use black */
|
||||
if (RGBfg[0] == 0 && RGBfg[1] == 0 && RGBfg[2] == 0) {
|
||||
State.map['1'] = fgindex = 7; /* Re-use black */
|
||||
} else {
|
||||
State.map['1'] = fgindex = paletteCount;
|
||||
memcpy(paletteRGB[paletteCount++], RGBfg, 3);
|
||||
paletteBitSize = 4;
|
||||
}
|
||||
}
|
||||
/* If colour is already present, go to next colour code */
|
||||
if (fFound)
|
||||
continue;
|
||||
|
||||
/* Colour code not present - add colour code */
|
||||
/* Get RGB value */
|
||||
switch (pixelColour) {
|
||||
case '0': /* standard background */
|
||||
RGBCur[0] = RGBbg[0]; RGBCur[1] = RGBbg[1]; RGBCur[2] = RGBbg[2];
|
||||
break;
|
||||
case '1': /* standard foreground */
|
||||
RGBCur[0] = RGBfg[0]; RGBCur[1] = RGBfg[1]; RGBCur[2] = RGBfg[2];
|
||||
break;
|
||||
default: /* Colour or error case */
|
||||
if (!out_colour_char_to_rgb(pixelColour, &RGBCur[0], &RGBCur[1], &RGBCur[2])) {
|
||||
strcpy(symbol->errtxt, "612: unknown pixel colour");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Search, if RGB value is already present */
|
||||
fFound = 0;
|
||||
for (paletteIndex = 0; paletteIndex < paletteCount; paletteIndex++) {
|
||||
if (RGBCur[0] == paletteRGB[paletteIndex][0]
|
||||
&& RGBCur[1] == paletteRGB[paletteIndex][1]
|
||||
&& RGBCur[2] == paletteRGB[paletteIndex][2])
|
||||
{
|
||||
fFound = 1;
|
||||
break;
|
||||
/* For Ultracode, have background only if have whitespace/quiet zones */
|
||||
if (symbol->whitespace_width > 0 || symbol->whitespace_height > 0
|
||||
|| ((symbol->output_options & BARCODE_QUIET_ZONES)
|
||||
&& !(symbol->output_options & BARCODE_NO_QUIET_ZONES))) {
|
||||
/* Check whether can re-use white */
|
||||
if (RGBbg[0] == 0xff && RGBbg[1] == 0xff && RGBbg[2] == 0xff && bgalpha == fgalpha) {
|
||||
State.map['0'] = bgindex = 0; /* Re-use white */
|
||||
} else {
|
||||
State.map['0'] = bgindex = paletteCount;
|
||||
memcpy(paletteRGB[paletteCount++], RGBbg, 3);
|
||||
paletteBitSize = 4;
|
||||
}
|
||||
}
|
||||
/* RGB not present, add it */
|
||||
if (!fFound) {
|
||||
paletteIndex = paletteCount;
|
||||
paletteRGB[paletteIndex][0] = RGBCur[0];
|
||||
paletteRGB[paletteIndex][1] = RGBCur[1];
|
||||
|
||||
paletteRGB[paletteIndex][2] = RGBCur[2];
|
||||
|
||||
paletteCount++;
|
||||
|
||||
if (pixelColour == '0') bgindex = paletteIndex;
|
||||
if (pixelColour == '1') fgindex = paletteIndex;
|
||||
}
|
||||
/* Add palette index to current colour code */
|
||||
(State.colourCode)[colourCount] = pixelColour;
|
||||
(State.colourPaletteIndex)[colourCount] = paletteIndex;
|
||||
colourCount++;
|
||||
} else {
|
||||
State.map['0'] = bgindex = 0;
|
||||
memcpy(paletteRGB[bgindex], RGBbg, 3);
|
||||
State.map['1'] = fgindex = 1;
|
||||
memcpy(paletteRGB[fgindex], RGBfg, 3);
|
||||
paletteCount = 2;
|
||||
paletteBitSize = 1;
|
||||
}
|
||||
State.colourCount = colourCount;
|
||||
|
||||
/* Set transparency */
|
||||
/* Note: does not allow both transparent foreground and background -
|
||||
* background takes priority */
|
||||
transparent_index = -1;
|
||||
if (bgalpha == 0) {
|
||||
if (bgalpha == 0 && bgindex != -1) {
|
||||
/* Transparent background */
|
||||
transparent_index = bgindex;
|
||||
} else if (fgalpha == 0) {
|
||||
} else if (fgalpha == 0 && fgindex != -1) {
|
||||
/* Transparent foreground */
|
||||
transparent_index = fgindex;
|
||||
}
|
||||
|
||||
/* find palette bit size from palette size*/
|
||||
|
||||
/* 1,2 -> 1, 3,4 ->2, 5,6,7,8->3 */
|
||||
paletteBitSize = 0;
|
||||
paletteCountCur = paletteCount - 1;
|
||||
while (paletteCountCur != 0) {
|
||||
paletteBitSize++;
|
||||
paletteCountCur >>= 1;
|
||||
}
|
||||
/* Minimum is 1 */
|
||||
if (paletteBitSize == 0)
|
||||
paletteBitSize = 1;
|
||||
|
||||
/* palette size 2 ^ bit size */
|
||||
paletteSize = 1 << paletteBitSize;
|
||||
|
||||
/* 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));
|
||||
return ZINT_ERROR_FILE_ACCESS;
|
||||
}
|
||||
#endif
|
||||
gif_file = stdout;
|
||||
} else {
|
||||
if (!(gif_file = out_fopen(symbol->outfile, "wb"))) {
|
||||
sprintf(symbol->errtxt, "611: Could not open output file (%d: %.30s)", errno, strerror(errno));
|
||||
return ZINT_ERROR_FILE_ACCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* GIF signature (6) */
|
||||
memcpy(outbuf, "GIF87a", 6);
|
||||
if (transparent_index != -1)
|
||||
outbuf[4] = '9';
|
||||
|
||||
fwrite(outbuf, 6, 1, gif_file);
|
||||
fm_write(transparent_index == -1 ? "GIF87a" : "GIF89a", 1, 6, State.fmp);
|
||||
/* Screen Descriptor (7) */
|
||||
/* Screen Width */
|
||||
usTemp = (unsigned short) symbol->bitmap_width;
|
||||
outbuf[0] = (unsigned char) (0xff & usTemp);
|
||||
outbuf[1] = (unsigned char) ((0xff00 & usTemp) / 0x100);
|
||||
outbuf[0] = (unsigned char) (0xff & symbol->bitmap_width);
|
||||
outbuf[1] = (unsigned char) (0xff & (symbol->bitmap_width >> 8));
|
||||
/* Screen Height */
|
||||
usTemp = (unsigned short) symbol->bitmap_height;
|
||||
outbuf[2] = (unsigned char) (0xff & usTemp);
|
||||
outbuf[3] = (unsigned char) ((0xff00 & usTemp) / 0x100);
|
||||
outbuf[2] = (unsigned char) (0xff & symbol->bitmap_height);
|
||||
outbuf[3] = (unsigned char) (0xff & (symbol->bitmap_height >> 8));
|
||||
/* write ImageBits-1 to the three least significant bits of byte 5 of
|
||||
* the Screen Descriptor
|
||||
* Bits 76543210
|
||||
* 1 : Global colour map
|
||||
* 111 : 8 bit colour depth of the palette
|
||||
* 0 : Not ordered in decreasing importance
|
||||
* xxx : palette bit zize - 1
|
||||
* xxx : palette bit size - 1
|
||||
*/
|
||||
outbuf[4] = (unsigned char) (0xf0 | (0x7 & (paletteBitSize - 1)));
|
||||
|
||||
@ -487,23 +379,15 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
|
||||
* Background colour index
|
||||
* Default to 0. If colour code 0 or K is present, it is used as index
|
||||
*/
|
||||
|
||||
backgroundColourIndex = 0;
|
||||
for (colourIndex = 0; colourIndex < colourCount; colourIndex++) {
|
||||
if ((State.colourCode)[colourIndex] == '0' || (State.colourCode)[colourIndex] == 'W') {
|
||||
backgroundColourIndex = (State.colourPaletteIndex)[colourIndex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
outbuf[5] = backgroundColourIndex;
|
||||
outbuf[5] = bgindex == -1 ? 0 : bgindex;
|
||||
/* Byte 7 must be 0x00 */
|
||||
outbuf[6] = 0x00;
|
||||
fwrite(outbuf, 7, 1, gif_file);
|
||||
fm_write(outbuf, 1, 7, State.fmp);
|
||||
/* Global Color Table (paletteSize*3) */
|
||||
fwrite(paletteRGB, 3*paletteCount, 1, gif_file);
|
||||
fm_write(paletteRGB, 1, 3*paletteCount, State.fmp);
|
||||
/* add unused palette items to fill palette size */
|
||||
for (paletteIndex = paletteCount; paletteIndex < paletteSize; paletteIndex++) {
|
||||
fwrite(RGBUnused, 3, 1, gif_file);
|
||||
for (i = paletteCount; i < paletteSize; i++) {
|
||||
fm_write(RGBUnused, 1, 3, State.fmp);
|
||||
}
|
||||
|
||||
/* Graphic control extension (8) */
|
||||
@ -512,9 +396,9 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
|
||||
*/
|
||||
if (transparent_index != -1) {
|
||||
/* Extension Introducer = '!' */
|
||||
outbuf[0] = '\x21';
|
||||
outbuf[0] = '!';
|
||||
/* Graphic Control Label */
|
||||
outbuf[1] = '\xf9';
|
||||
outbuf[1] = 0xf9;
|
||||
/* Block Size */
|
||||
outbuf[2] = 4;
|
||||
/* Packet fields:
|
||||
@ -531,11 +415,11 @@ 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, 8, 1, gif_file);
|
||||
fm_write(outbuf, 1, 8, State.fmp);
|
||||
}
|
||||
/* Image Descriptor */
|
||||
/* Image separator character = ',' */
|
||||
outbuf[0] = 0x2c;
|
||||
outbuf[0] = ',';
|
||||
/* "Image Left" */
|
||||
outbuf[1] = 0x00;
|
||||
outbuf[2] = 0x00;
|
||||
@ -544,64 +428,40 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
|
||||
outbuf[4] = 0x00;
|
||||
/* Image Width (low byte first) */
|
||||
outbuf[5] = (unsigned char) (0xff & symbol->bitmap_width);
|
||||
outbuf[6] = (unsigned char) ((0xff00 & symbol->bitmap_width) / 0x100);
|
||||
outbuf[6] = (unsigned char) (0xff & (symbol->bitmap_width >> 8));
|
||||
/* Image Height */
|
||||
outbuf[7] = (unsigned char) (0xff & symbol->bitmap_height);
|
||||
outbuf[8] = (unsigned char) ((0xff00 & symbol->bitmap_height) / 0x100);
|
||||
outbuf[8] = (unsigned char) (0xff & (symbol->bitmap_height >> 8));
|
||||
|
||||
/* Byte 10 contains the interlaced flag and
|
||||
* information on the local color table.
|
||||
* There is no local color table if its most significant bit is reset.
|
||||
*/
|
||||
outbuf[9] = 0x00;
|
||||
fwrite(outbuf, 10, 1, gif_file);
|
||||
|
||||
/* prepare state array */
|
||||
State.pIn = pixelbuf;
|
||||
State.InLen = bitmapSize;
|
||||
if (!(State.pOut = (unsigned char *) malloc(lzoutbufSize))) {
|
||||
if (!output_to_stdout) {
|
||||
(void) fclose(gif_file);
|
||||
}
|
||||
strcpy(symbol->errtxt, "614: Insufficient memory for LZW buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
}
|
||||
State.OutLength = lzoutbufSize;
|
||||
fm_write(outbuf, 1, 10, State.fmp);
|
||||
|
||||
/* call lzw encoding */
|
||||
byte_out = gif_lzw(&State, paletteBitSize);
|
||||
if (byte_out <= 0) {
|
||||
if (!gif_lzw(&State, paletteBitSize)) {
|
||||
free(State.pOut);
|
||||
if (!output_to_stdout) {
|
||||
(void) fclose(gif_file);
|
||||
}
|
||||
strcpy(symbol->errtxt, "613: Insufficient memory for LZW buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
(void) fm_close(State.fmp, symbol);
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 613, "Insufficient memory for GIF LZW buffer");
|
||||
}
|
||||
fwrite((const char *) State.pOut, byte_out, 1, gif_file);
|
||||
fm_write(State.pOut, 1, State.OutPosCur, State.fmp);
|
||||
free(State.pOut);
|
||||
|
||||
/* GIF terminator */
|
||||
fputc('\x3b', gif_file);
|
||||
fm_putc(';', State.fmp);
|
||||
|
||||
if (ferror(gif_file)) {
|
||||
sprintf(symbol->errtxt, "615: Incomplete write to output (%d: %.30s)", errno, strerror(errno));
|
||||
if (!output_to_stdout) {
|
||||
(void) fclose(gif_file);
|
||||
}
|
||||
if (fm_error(State.fmp)) {
|
||||
errtxtf(0, symbol, 615, "Incomplete write of GIF output (%1$d: %2$s)", State.fmp->err,
|
||||
strerror(State.fmp->err));
|
||||
(void) fm_close(State.fmp, symbol);
|
||||
return ZINT_ERROR_FILE_WRITE;
|
||||
}
|
||||
|
||||
if (output_to_stdout) {
|
||||
if (fflush(gif_file) != 0) {
|
||||
sprintf(symbol->errtxt, "616: Incomplete flush to output (%d: %.30s)", errno, strerror(errno));
|
||||
return ZINT_ERROR_FILE_WRITE;
|
||||
}
|
||||
} else {
|
||||
if (fclose(gif_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)) {
|
||||
return errtxtf(ZINT_ERROR_FILE_WRITE, symbol, 617, "Failure on closing GIF output file (%1$d: %2$s)",
|
||||
State.fmp->err, strerror(State.fmp->err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* gridmtx.c - Grid Matrix */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -137,7 +137,7 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
};
|
||||
|
||||
/* Cost of switching modes from k to j - see AIMD014 Rev. 1.63 Table 9 – Type conversion codes */
|
||||
static const unsigned int switch_costs[GM_NUM_MODES][GM_NUM_MODES] = {
|
||||
static const unsigned char switch_costs[GM_NUM_MODES][GM_NUM_MODES] = {
|
||||
/* H N L U M B */
|
||||
/*H*/ { 0, (13 + 2) * GM_MULT, 13 * GM_MULT, 13 * GM_MULT, 13 * GM_MULT, (13 + 9) * GM_MULT },
|
||||
/*N*/ { 10 * GM_MULT, 0, 10 * GM_MULT, 10 * GM_MULT, 10 * GM_MULT, (10 + 9) * GM_MULT },
|
||||
@ -148,7 +148,7 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
};
|
||||
|
||||
/* Final end-of-data cost - see AIMD014 Rev. 1.63 Table 9 – Type conversion codes */
|
||||
static const unsigned int eod_costs[GM_NUM_MODES] = {
|
||||
static const unsigned char eod_costs[GM_NUM_MODES] = {
|
||||
/* H N L U M B */
|
||||
13 * GM_MULT, 10 * GM_MULT, 5 * GM_MULT, 5 * GM_MULT, 10 * GM_MULT, 4 * GM_MULT
|
||||
};
|
||||
@ -156,15 +156,15 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
unsigned int numeral_end = 0, numeral_cost = 0, byte_count = 0; /* State */
|
||||
int double_byte, space, numeric, lower, upper, control, double_digit, eol;
|
||||
|
||||
int i, j, k, cm_i;
|
||||
int i, j, k;
|
||||
unsigned int min_cost;
|
||||
char cur_mode;
|
||||
unsigned int prev_costs[GM_NUM_MODES];
|
||||
unsigned int cur_costs[GM_NUM_MODES];
|
||||
char *char_modes = (char *) z_alloca(length * GM_NUM_MODES);
|
||||
char (*char_modes)[GM_NUM_MODES] = (char (*)[GM_NUM_MODES]) z_alloca(GM_NUM_MODES * length);
|
||||
|
||||
/* char_modes[i * GM_NUM_MODES + j] represents the mode to encode the code point at index i such that the final
|
||||
* segment ends in mode_types[j] and the total number of bits is minimized over all possible choices */
|
||||
/* char_modes[i][j] represents the mode to encode the code point at index i such that the final segment
|
||||
ends in mode_types[j] and the total number of bits is minimized over all possible choices */
|
||||
memset(char_modes, 0, length * GM_NUM_MODES);
|
||||
|
||||
/* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/XX_MULT)
|
||||
@ -172,7 +172,7 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
memcpy(prev_costs, head_costs, GM_NUM_MODES * sizeof(unsigned int));
|
||||
|
||||
/* Calculate costs using dynamic programming */
|
||||
for (i = 0, cm_i = 0; i < length; i++, cm_i += GM_NUM_MODES) {
|
||||
for (i = 0; i < length; i++) {
|
||||
memset(cur_costs, 0, GM_NUM_MODES * sizeof(unsigned int));
|
||||
|
||||
space = numeric = lower = upper = control = double_digit = eol = 0;
|
||||
@ -201,7 +201,7 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
|
||||
/* Hanzi mode can encode anything */
|
||||
cur_costs[GM_H] = prev_costs[GM_H] + (double_digit || eol ? 39 : 78); /* (6.5 : 13) * GM_MULT */
|
||||
char_modes[cm_i + GM_H] = GM_CHINESE;
|
||||
char_modes[i][GM_H] = GM_CHINESE;
|
||||
|
||||
/* Byte mode can encode anything */
|
||||
if (byte_count == 512 || (double_byte && byte_count == 511)) {
|
||||
@ -213,39 +213,39 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
byte_count = 0;
|
||||
}
|
||||
cur_costs[GM_B] += prev_costs[GM_B] + (double_byte ? 96 : 48); /* (16 : 8) * GM_MULT */
|
||||
char_modes[cm_i + GM_B] = GM_BYTE;
|
||||
char_modes[i][GM_B] = GM_BYTE;
|
||||
byte_count += double_byte ? 2 : 1;
|
||||
|
||||
if (gm_in_numeral(ddata, length, i, &numeral_end, &numeral_cost)) {
|
||||
cur_costs[GM_N] = prev_costs[GM_N] + numeral_cost;
|
||||
char_modes[cm_i + GM_N] = GM_NUMBER;
|
||||
char_modes[i][GM_N] = GM_NUMBER;
|
||||
}
|
||||
|
||||
if (control) {
|
||||
cur_costs[GM_L] = prev_costs[GM_L] + 78; /* (7 + 6) * GM_MULT */
|
||||
char_modes[cm_i + GM_L] = GM_LOWER;
|
||||
char_modes[i][GM_L] = GM_LOWER;
|
||||
cur_costs[GM_U] = prev_costs[GM_U] + 78; /* (7 + 6) * GM_MULT */
|
||||
char_modes[cm_i + GM_U] = GM_UPPER;
|
||||
char_modes[i][GM_U] = GM_UPPER;
|
||||
cur_costs[GM_M] = prev_costs[GM_M] + 96; /* (10 + 6) * GM_MULT */
|
||||
char_modes[cm_i + GM_M] = GM_MIXED;
|
||||
char_modes[i][GM_M] = GM_MIXED;
|
||||
} else {
|
||||
if (lower || space) {
|
||||
cur_costs[GM_L] = prev_costs[GM_L] + 30; /* 5 * GM_MULT */
|
||||
char_modes[cm_i + GM_L] = GM_LOWER;
|
||||
char_modes[i][GM_L] = GM_LOWER;
|
||||
}
|
||||
if (upper || space) {
|
||||
cur_costs[GM_U] = prev_costs[GM_U] + 30; /* 5 * GM_MULT */
|
||||
char_modes[cm_i + GM_U] = GM_UPPER;
|
||||
char_modes[i][GM_U] = GM_UPPER;
|
||||
}
|
||||
if (numeric || lower || upper || space) {
|
||||
cur_costs[GM_M] = prev_costs[GM_M] + 36; /* 6 * GM_MULT */
|
||||
char_modes[cm_i + GM_M] = GM_MIXED;
|
||||
char_modes[i][GM_M] = GM_MIXED;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == length - 1) { /* Add end of data costs if last character */
|
||||
for (j = 0; j < GM_NUM_MODES; j++) {
|
||||
if (char_modes[cm_i + j]) {
|
||||
if (char_modes[i][j]) {
|
||||
cur_costs[j] += eod_costs[j];
|
||||
}
|
||||
}
|
||||
@ -254,11 +254,11 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
/* Start new segment at the end to switch modes */
|
||||
for (j = 0; j < GM_NUM_MODES; j++) { /* To mode */
|
||||
for (k = 0; k < GM_NUM_MODES; k++) { /* From mode */
|
||||
if (j != k && char_modes[cm_i + k]) {
|
||||
if (j != k && char_modes[i][k]) {
|
||||
const unsigned int new_cost = cur_costs[k] + switch_costs[k][j];
|
||||
if (!char_modes[cm_i + j] || new_cost < cur_costs[j]) {
|
||||
if (!char_modes[i][j] || new_cost < cur_costs[j]) {
|
||||
cur_costs[j] = new_cost;
|
||||
char_modes[cm_i + j] = mode_types[k];
|
||||
char_modes[i][j] = mode_types[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -278,9 +278,9 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
}
|
||||
|
||||
/* Get optimal mode for each code point by tracing backwards */
|
||||
for (i = length - 1, cm_i = i * GM_NUM_MODES; i >= 0; i--, cm_i -= GM_NUM_MODES) {
|
||||
for (i = length - 1; i >= 0; i--) {
|
||||
j = posn(mode_types, cur_mode);
|
||||
cur_mode = char_modes[cm_i + j];
|
||||
cur_mode = char_modes[i][j];
|
||||
mode[i] = cur_mode;
|
||||
}
|
||||
|
||||
@ -1050,8 +1050,8 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], cons
|
||||
if (error_number == 0) {
|
||||
done = 1;
|
||||
} else {
|
||||
sprintf(symbol->errtxt, "535: Invalid character in input data for ECI %d", local_segs[i].eci);
|
||||
return error_number;
|
||||
return errtxtf(error_number, symbol, 535, "Invalid character in input for ECI '%d'",
|
||||
local_segs[i].eci);
|
||||
}
|
||||
}
|
||||
if (!done) {
|
||||
@ -1069,12 +1069,13 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], cons
|
||||
|
||||
if (symbol->structapp.count) {
|
||||
if (symbol->structapp.count < 2 || symbol->structapp.count > 16) {
|
||||
strcpy(symbol->errtxt, "536: Structured Append count out of range (2-16)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 536,
|
||||
"Structured Append count '%d' out of range (2 to 16)", symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
|
||||
sprintf(symbol->errtxt, "537: Structured Append index out of range (1-%d)", symbol->structapp.count);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 537,
|
||||
"Structured Append index '%1$d' out of range (1 to count %2$d)",
|
||||
symbol->structapp.index, symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.id[0]) {
|
||||
int id, id_len;
|
||||
@ -1082,32 +1083,30 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], cons
|
||||
for (id_len = 1; id_len < 4 && symbol->structapp.id[id_len]; id_len++);
|
||||
|
||||
if (id_len > 3) { /* 255 (8 bits) */
|
||||
strcpy(symbol->errtxt, "538: Structured Append ID too long (3 digit maximum)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 538,
|
||||
"Structured Append ID length %d too long (3 digit maximum)", id_len);
|
||||
}
|
||||
|
||||
id = to_int((const unsigned char *) symbol->structapp.id, id_len);
|
||||
if (id == -1) {
|
||||
strcpy(symbol->errtxt, "539: Invalid Structured Append ID (digits only)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 539, "Invalid Structured Append ID (digits only)");
|
||||
}
|
||||
if (id > 255) {
|
||||
sprintf(symbol->errtxt, "530: Structured Append ID '%d' out of range (0-255)", id);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 530,
|
||||
"Structured Append ID value '%d' out of range (0 to 255)", id);
|
||||
}
|
||||
}
|
||||
p_structapp = &symbol->structapp;
|
||||
}
|
||||
|
||||
if (symbol->eci > 811799) {
|
||||
strcpy(symbol->errtxt, "533: Invalid ECI");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 533, "ECI code '%d' out of range (0 to 811799)",
|
||||
symbol->eci);
|
||||
}
|
||||
|
||||
error_number = gm_encode_segs(ddata, local_segs, seg_count, binary, reader, p_structapp, &bin_len, debug_print);
|
||||
if (error_number != 0) {
|
||||
strcpy(symbol->errtxt, "531: Input data too long");
|
||||
return error_number;
|
||||
return errtxt(error_number, symbol, 531, "Input too long, requires too many codewords (maximum 1313)");
|
||||
}
|
||||
|
||||
/* Determine the size of the symbol */
|
||||
@ -1132,8 +1131,9 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], cons
|
||||
if (symbol->option_2 >= min_layers) {
|
||||
layers = symbol->option_2;
|
||||
} else {
|
||||
strcpy(symbol->errtxt, "534: Input data too long for selected symbol size");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 534,
|
||||
"Input too long for Version %1$d, requires %2$d codewords (maximum %3$d)",
|
||||
symbol->option_2, data_cw, gm_max_cw[symbol->option_2 - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1189,8 +1189,12 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], cons
|
||||
}
|
||||
|
||||
if (data_cw > data_max) {
|
||||
strcpy(symbol->errtxt, "532: Input data too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 532,
|
||||
"Input too long for ECC level %1$d, requires %2$d codewords (maximum %3$d)",
|
||||
ecc_level, data_cw, data_max);
|
||||
}
|
||||
if (debug_print) {
|
||||
printf("Layers: %d, ECC level: %d, Data Codewords: %d\n", layers, ecc_level, data_cw);
|
||||
}
|
||||
|
||||
gm_add_ecc(binary, data_cw, layers, ecc_level, word);
|
||||
|
630
backend/gs1.c
@ -4,7 +4,7 @@
|
||||
*/
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2021-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2021-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -37,8 +37,8 @@
|
||||
#define Z_GS1_LINT_H
|
||||
|
||||
/* N18,csum,key (Used by SSCC, GSRN - PROVIDER, GSRN - RECIPIENT) */
|
||||
static int n18_csum_key(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n18_csum_key(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 18
|
||||
&& csum(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& key(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -47,9 +47,9 @@ static int n18_csum_key(const unsigned char *data, const int data_len,
|
||||
&& key(data, data_len, 0, 18, 18, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N14,csum,key (Used by GTIN, CONTENT) */
|
||||
static int n14_csum_key(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* N14,csum,key (Used by GTIN, CONTENT, MTO GTIN) */
|
||||
static int n14_csum_key(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 14
|
||||
&& csum(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& key(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -58,16 +58,16 @@ static int n14_csum_key(const unsigned char *data, const int data_len,
|
||||
&& key(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X..20 (Used by BATCH/LOT, SERIAL, CPV, PCN...) */
|
||||
static int x__20(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* X..20 (Used by BATCH/LOT, SERIAL, CPV, PCN, GLN EXTENSION COMPONENT, SHIP TO POST, RTN TO POST, REFURB LOT, ...) */
|
||||
static int x__20(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 20
|
||||
&& cset82(data, data_len, 0, 1, 20, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N6,yymmd0 (Used by PROD DATE, DUE DATE, PACK DATE, BEST BEFORE or BEST BY...) */
|
||||
static int n6_yymmd0(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* N6,yymmd0 (Used by PROD DATE, DUE DATE, PACK DATE, BEST BEFORE or BEST BY, SELL BY, USE BY or EXPIRY) */
|
||||
static int n6_yymmd0(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 6
|
||||
&& yymmd0(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
|
||||
@ -75,36 +75,36 @@ static int n6_yymmd0(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N2 (Used by VARIANT) */
|
||||
static int n2(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n2(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 2
|
||||
&& numeric(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* X..28 (Used by TPX) */
|
||||
static int x__28(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__28(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 28
|
||||
&& cset82(data, data_len, 0, 1, 28, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* X..30 (Used by ADDITIONAL ID, CUST. PART No., SECONDARY SERIAL, REF. TO SOURCE...) */
|
||||
static int x__30(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* X..30 (Used by ADDITIONAL ID, CUST. PART No., SECONDARY SERIAL, REF. TO SOURCE, ORDER NUMBER, ROUTE, SHIP TO...) */
|
||||
static int x__30(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 30
|
||||
&& cset82(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N..6 (Used by MTO VARIANT) */
|
||||
static int n__6(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n__6(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 6
|
||||
&& numeric(data, data_len, 0, 1, 6, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N13,csum,key [X..17] (Used by GDTI) */
|
||||
static int n13_csum_key__x__17_(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n13_csum_key__x__17_(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 13 && data_len <= 30
|
||||
&& csum(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& key(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -115,8 +115,8 @@ static int n13_csum_key__x__17_(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N13,csum,key [N..12] (Used by GCN) */
|
||||
static int n13_csum_key__n__12_(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n13_csum_key__n__12_(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 13 && data_len <= 25
|
||||
&& csum(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& key(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -127,29 +127,29 @@ static int n13_csum_key__n__12_(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N..8 (Used by VAR. COUNT, COUNT) */
|
||||
static int n__8(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n__8(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 8
|
||||
&& numeric(data, data_len, 0, 1, 8, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N6 (Used by NET WEIGHT (kg), LENGTH (m), WIDTH (m), HEIGHT (m)...) */
|
||||
static int n6(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* N6 (Used by NET WEIGHT (kg), LENGTH (m), WIDTH (m), HEIGHT (m), AREA (m²), NET VOLUME (l), NET VOLUME (m³)...) */
|
||||
static int n6(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 6
|
||||
&& numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N..15 (Used by AMOUNT, PRICE) */
|
||||
static int n__15(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n__15(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 15
|
||||
&& numeric(data, data_len, 0, 1, 15, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N3,iso4217 N..15 (Used by AMOUNT, PRICE) */
|
||||
static int n3_iso4217_n__15(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n3_iso4217_n__15(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 4 && data_len <= 18
|
||||
&& iso4217(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
|
||||
@ -158,15 +158,15 @@ static int n3_iso4217_n__15(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N4 (Used by PRCNT OFF, POINTS) */
|
||||
static int n4(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n4(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 4
|
||||
&& numeric(data, data_len, 0, 4, 4, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* X..30,key (Used by GINC, GIAI - ASSEMBLY, GIAI) */
|
||||
static int x__30_key(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__30_key(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 30
|
||||
&& key(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg)
|
||||
@ -174,8 +174,8 @@ static int x__30_key(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N17,csum,key (Used by GSIN) */
|
||||
static int n17_csum_key(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n17_csum_key(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 17
|
||||
&& csum(data, data_len, 0, 17, 17, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& key(data, data_len, 0, 17, 17, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -184,9 +184,9 @@ static int n17_csum_key(const unsigned char *data, const int data_len,
|
||||
&& key(data, data_len, 0, 17, 17, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N13,csum,key (Used by SHIP TO LOC, BILL TO, PURCHASE FROM, SHIP FOR LOC...) */
|
||||
static int n13_csum_key(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* N13,csum,key (Used by SHIP TO LOC, BILL TO, PURCHASE FROM, SHIP FOR LOC, LOC No., PAY TO, PROD/SERV LOC, PARTY) */
|
||||
static int n13_csum_key(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 13
|
||||
&& csum(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& key(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -196,8 +196,8 @@ static int n13_csum_key(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N3,iso3166 X..9 (Used by SHIP TO POST) */
|
||||
static int n3_iso3166_x__9(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n3_iso3166_x__9(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 4 && data_len <= 12
|
||||
&& iso3166(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
|
||||
@ -206,42 +206,54 @@ static int n3_iso3166_x__9(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N3,iso3166 (Used by ORIGIN, COUNTRY - PROCESS, COUNTRY - FULL PROCESS) */
|
||||
static int n3_iso3166(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n3_iso3166(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 3
|
||||
&& iso3166(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
|
||||
&& iso3166(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N..15,iso3166list (Used by COUNTRY - INITIAL PROCESS, COUNTRY - DISASSEMBLY) */
|
||||
static int n__15_iso3166list(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 15
|
||||
&& iso3166list(data, data_len, 0, 1, 15, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 1, 15, p_err_no, p_err_posn, err_msg)
|
||||
&& iso3166list(data, data_len, 0, 1, 15, p_err_no, p_err_posn, err_msg, 0);
|
||||
/* N3,iso3166 [N3],iso3166 [N3],iso3166 [N3],iso3166 [N3],iso3166 (Used by COUNTRY - INITIAL PROCESS, COUNTRY -...) */
|
||||
static int n3_iso3166__n3__iso3166__n3__iso3166__n3__iso3166__n3__iso3166(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 3 && data_len <= 15
|
||||
&& iso3166(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& iso3166(data, data_len, 3, 0, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& iso3166(data, data_len, 6, 0, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& iso3166(data, data_len, 9, 0, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& iso3166(data, data_len, 12, 0, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
|
||||
&& iso3166(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 3, 0, 3, p_err_no, p_err_posn, err_msg)
|
||||
&& iso3166(data, data_len, 3, 0, 3, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 6, 0, 3, p_err_no, p_err_posn, err_msg)
|
||||
&& iso3166(data, data_len, 6, 0, 3, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 9, 0, 3, p_err_no, p_err_posn, err_msg)
|
||||
&& iso3166(data, data_len, 9, 0, 3, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 12, 0, 3, p_err_no, p_err_posn, err_msg)
|
||||
&& iso3166(data, data_len, 12, 0, 3, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X..3 (Used by ORIGIN SUBDIVISION, AQUATIC SPECIES) */
|
||||
static int x__3(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__3(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 3
|
||||
&& cset82(data, data_len, 0, 1, 3, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* X..35,pcenc (Used by SHIP TO COMP, SHIP TO NAME, RTN TO COMP, RTN TO NAME...) */
|
||||
static int x__35_pcenc(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* X..35,pcenc (Used by SHIP TO COMP, SHIP TO NAME, RTN TO COMP, RTN TO NAME, SRV DESCRIPTION) */
|
||||
static int x__35_pcenc(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 35
|
||||
&& pcenc(data, data_len, 0, 1, 35, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 35, p_err_no, p_err_posn, err_msg)
|
||||
&& pcenc(data, data_len, 0, 1, 35, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X..70,pcenc (Used by SHIP TO ADD1, SHIP TO ADD2, SHIP TO SUB, SHIP TO LOC...) */
|
||||
static int x__70_pcenc(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* X..70,pcenc (Used by SHIP TO ADD1, SHIP TO ADD2, SHIP TO SUB, SHIP TO LOC, SHIP TO REG, RTN TO ADD1, RTN TO ...) */
|
||||
static int x__70_pcenc(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 70
|
||||
&& pcenc(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg)
|
||||
@ -249,8 +261,8 @@ static int x__70_pcenc(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* X2,iso3166alpha2 (Used by SHIP TO COUNTRY, RTN TO COUNTRY) */
|
||||
static int x2_iso3166alpha2(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x2_iso3166alpha2(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 2
|
||||
&& iso3166alpha2(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg)
|
||||
@ -258,8 +270,8 @@ static int x2_iso3166alpha2(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N10,latitude N10,longitude (Used by SHIP TO GEO) */
|
||||
static int n10_latitude_n10_longitude(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n10_latitude_n10_longitude(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 20
|
||||
&& latitude(data, data_len, 0, 10, 10, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& longitude(data, data_len, 10, 10, 10, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -270,29 +282,29 @@ static int n10_latitude_n10_longitude(const unsigned char *data, const int data_
|
||||
}
|
||||
|
||||
/* N1,yesno (Used by DANGEROUS GOODS, AUTH TO LEAVE, SIG REQUIRED) */
|
||||
static int n1_yesno(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n1_yesno(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 1
|
||||
&& yesno(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg)
|
||||
&& yesno(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N6,yymmd0 N4,hhmm (Used by NOT BEF DEL DT, NOT AFT DEL DT) */
|
||||
static int n6_yymmd0_n4_hhmm(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* N6,yymmd0 N4,hhmi (Used by NOT BEF DEL DT, NOT AFT DEL DT) */
|
||||
static int n6_yymmd0_n4_hhmi(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 10
|
||||
&& yymmd0(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& hhmm(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& hhmi(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
|
||||
&& yymmd0(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg)
|
||||
&& hhmm(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 0);
|
||||
&& hhmi(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N6,yymmdd (Used by REL DATE, FIRST FREEZE DATE) */
|
||||
static int n6_yymmdd(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n6_yymmdd(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 6
|
||||
&& yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
|
||||
@ -300,8 +312,8 @@ static int n6_yymmdd(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N6 [X1],hyphen (Used by MAX TEMP F., MAX TEMP C., MIN TEMP F., MIN TEMP C.) */
|
||||
static int n6__x1__hyphen(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n6__x1__hyphen(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 6 && data_len <= 7
|
||||
&& hyphen(data, data_len, 6, 0, 1, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
|
||||
@ -310,41 +322,41 @@ static int n6__x1__hyphen(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N13 (Used by NSN) */
|
||||
static int n13(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n13(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 13
|
||||
&& numeric(data, data_len, 0, 13, 13, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N6,yymmdd N4,hhmm (Used by EXPIRY TIME) */
|
||||
static int n6_yymmdd_n4_hhmm(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* N6,yymmdd N4,hhmi (Used by EXPIRY TIME) */
|
||||
static int n6_yymmdd_n4_hhmi(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 10
|
||||
&& yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& hhmm(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& hhmi(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
|
||||
&& yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg)
|
||||
&& hhmm(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 0);
|
||||
&& hhmi(data, data_len, 6, 4, 4, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N..4 (Used by ACTIVE POTENCY) */
|
||||
static int n__4(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n__4(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 4
|
||||
&& numeric(data, data_len, 0, 1, 4, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* X..12 (Used by CATCH AREA) */
|
||||
static int x__12(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__12(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 12
|
||||
&& cset82(data, data_len, 0, 1, 12, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N6,yymmdd [N6],yymmdd (Used by HARVEST DATE) */
|
||||
static int n6_yymmdd__n6__yymmdd(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n6_yymmdd__n6__yymmdd(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 6 && data_len <= 12
|
||||
&& yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& yymmdd(data, data_len, 6, 0, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -354,35 +366,35 @@ static int n6_yymmdd__n6__yymmdd(const unsigned char *data, const int data_len,
|
||||
&& yymmdd(data, data_len, 6, 0, 6, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X..10 (Used by FISHING GEAR TYPE) */
|
||||
static int x__10(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* X..10 (Used by FISHING GEAR TYPE, SUFFIX) */
|
||||
static int x__10(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 10
|
||||
&& cset82(data, data_len, 0, 1, 10, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* X..2 (Used by PROD METHOD) */
|
||||
static int x__2(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__2(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 2
|
||||
&& cset82(data, data_len, 0, 1, 2, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N6,yymmdd [N4],hhmm (Used by TEST BY DATE) */
|
||||
static int n6_yymmdd__n4__hhmm(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* N6,yymmdd [N4],hhmi (Used by TEST BY DATE) */
|
||||
static int n6_yymmdd__n4__hhmi(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 6 && data_len <= 10
|
||||
&& yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& hhmm(data, data_len, 6, 0, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& hhmi(data, data_len, 6, 0, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
|
||||
&& yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 6, 0, 4, p_err_no, p_err_posn, err_msg)
|
||||
&& hhmm(data, data_len, 6, 0, 4, p_err_no, p_err_posn, err_msg, 0);
|
||||
&& hhmi(data, data_len, 6, 0, 4, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N3,iso3166999 X..27 (Used by PROCESSOR # 0, PROCESSOR # 1, PROCESSOR # 2, PROCESSOR # 3...) */
|
||||
static int n3_iso3166999_x__27(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* N3,iso3166999 X..27 (Used by PROCESSOR # 0, PROCESSOR # 1, PROCESSOR # 2, PROCESSOR # 3, PROCESSOR # 4, PROC...) */
|
||||
static int n3_iso3166999_x__27(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 4 && data_len <= 30
|
||||
&& iso3166999(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
|
||||
@ -391,8 +403,8 @@ static int n3_iso3166999_x__27(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N1 X1 X1 X1,importeridx (Used by UIC+EXT) */
|
||||
static int n1_x1_x1_x1_importeridx(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n1_x1_x1_x1_importeridx(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 4
|
||||
&& importeridx(data, data_len, 3, 1, 1, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg)
|
||||
@ -402,17 +414,26 @@ static int n1_x1_x1_x1_importeridx(const unsigned char *data, const int data_len
|
||||
&& importeridx(data, data_len, 3, 1, 1, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X2 X..28 (Used by CERT # 1, CERT # 2, CERT # 3, CERT # 4...) */
|
||||
static int x2_x__28(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* X..4,packagetype (Used by UFRGT UNIT TYPE) */
|
||||
static int x__4_packagetype(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 4
|
||||
&& packagetype(data, data_len, 0, 1, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 4, p_err_no, p_err_posn, err_msg)
|
||||
&& packagetype(data, data_len, 0, 1, 4, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X2 X..28 (Used by CERT # 1, CERT # 2, CERT # 3, CERT # 4, CERT # 5, CERT # 6, CERT # 7, CERT # 8, CERT # 9, ...) */
|
||||
static int x2_x__28(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 3 && data_len <= 30
|
||||
&& cset82(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg)
|
||||
&& cset82(data, data_len, 2, 1, 28, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N2,mediatype (Used by AIDC MEDIA TYPE) */
|
||||
static int n2_mediatype(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n2_mediatype(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 2
|
||||
&& mediatype(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 2, 2, p_err_no, p_err_posn, err_msg)
|
||||
@ -420,15 +441,72 @@ static int n2_mediatype(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* X..25 (Used by VCN, REF No.) */
|
||||
static int x__25(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__25(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 25
|
||||
&& cset82(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* N8,yyyymmdd (Used by DOB) */
|
||||
static int n8_yyyymmdd(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 8
|
||||
&& yyyymmdd(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg)
|
||||
&& yyyymmdd(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N8,yyyymmdd N4,hhmi (Used by DOB TIME) */
|
||||
static int n8_yyyymmdd_n4_hhmi(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 12
|
||||
&& yyyymmdd(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& hhmi(data, data_len, 8, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg)
|
||||
&& yyyymmdd(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 8, 4, 4, p_err_no, p_err_posn, err_msg)
|
||||
&& hhmi(data, data_len, 8, 4, 4, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N1,iso5218 (Used by BIO SEX) */
|
||||
static int n1_iso5218(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 1
|
||||
&& iso5218(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg)
|
||||
&& iso5218(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X..40,pcenc (Used by FAMILY NAME, GIVEN NAME, BABY) */
|
||||
static int x__40_pcenc(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 40
|
||||
&& pcenc(data, data_len, 0, 1, 40, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 40, p_err_no, p_err_posn, err_msg)
|
||||
&& pcenc(data, data_len, 0, 1, 40, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X..90,pcenc (Used by FULL NAME) */
|
||||
static int x__90_pcenc(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 90
|
||||
&& pcenc(data, data_len, 0, 1, 90, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 90, p_err_no, p_err_posn, err_msg)
|
||||
&& pcenc(data, data_len, 0, 1, 90, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X3,posinseqslash (Used by BIRTH SEQUENCE) */
|
||||
static int x3_posinseqslash(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 3
|
||||
&& posinseqslash(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg)
|
||||
&& posinseqslash(data, data_len, 0, 3, 3, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N4,nonzero N5,nonzero N3,nonzero N1,winding N1 (Used by DIMENSIONS) */
|
||||
static int n4_nonzero_n5_nonzero_n3_nonzero_n1_winding_n1(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n4_nonzero_n5_nonzero_n3_nonzero_n1_winding_n1(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 14
|
||||
&& nonzero(data, data_len, 0, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& nonzero(data, data_len, 4, 5, 5, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -446,8 +524,8 @@ static int n4_nonzero_n5_nonzero_n3_nonzero_n1_winding_n1(const unsigned char *d
|
||||
}
|
||||
|
||||
/* N1,zero N13,csum,key [X..16] (Used by GRAI) */
|
||||
static int n1_zero_n13_csum_key__x__16_(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n1_zero_n13_csum_key__x__16_(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 14 && data_len <= 30
|
||||
&& zero(data, data_len, 0, 1, 1, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& csum(data, data_len, 1, 13, 13, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -461,8 +539,8 @@ static int n1_zero_n13_csum_key__x__16_(const unsigned char *data, const int dat
|
||||
}
|
||||
|
||||
/* N14,csum N4,pieceoftotal (Used by ITIP, ITIP CONTENT) */
|
||||
static int n14_csum_n4_pieceoftotal(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n14_csum_n4_pieceoftotal(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len == 18
|
||||
&& csum(data, data_len, 0, 14, 14, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& pieceoftotal(data, data_len, 14, 4, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -473,36 +551,42 @@ static int n14_csum_n4_pieceoftotal(const unsigned char *data, const int data_le
|
||||
}
|
||||
|
||||
/* X..34,iban (Used by IBAN) */
|
||||
static int x__34_iban(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__34_iban(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 34
|
||||
&& iban(data, data_len, 0, 1, 34, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 34, p_err_no, p_err_posn, err_msg)
|
||||
&& iban(data, data_len, 0, 1, 34, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N8,yymmddhh [N..4],mmoptss (Used by PROD TIME) */
|
||||
static int n8_yymmddhh__n__4__mmoptss(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
/* N6,yymmdd N2,hh [N2],mi [N2],ss (Used by PROD TIME) */
|
||||
static int n6_yymmdd_n2_hh__n2__mi__n2__ss(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 8 && data_len <= 12
|
||||
&& yymmddhh(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& mmoptss(data, data_len, 8, 0, 4, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg)
|
||||
&& yymmddhh(data, data_len, 0, 8, 8, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 8, 0, 4, p_err_no, p_err_posn, err_msg)
|
||||
&& mmoptss(data, data_len, 8, 0, 4, p_err_no, p_err_posn, err_msg, 0);
|
||||
&& yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& hh(data, data_len, 6, 2, 2, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& mi(data, data_len, 8, 0, 2, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& ss(data, data_len, 10, 0, 2, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg)
|
||||
&& yymmdd(data, data_len, 0, 6, 6, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 6, 2, 2, p_err_no, p_err_posn, err_msg)
|
||||
&& hh(data, data_len, 6, 2, 2, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 8, 0, 2, p_err_no, p_err_posn, err_msg)
|
||||
&& mi(data, data_len, 8, 0, 2, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& numeric(data, data_len, 10, 0, 2, p_err_no, p_err_posn, err_msg)
|
||||
&& ss(data, data_len, 10, 0, 2, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X..50 (Used by OPTSEN) */
|
||||
static int x__50(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__50(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 50
|
||||
&& cset82(data, data_len, 0, 1, 50, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* Y..30,key (Used by CPID) */
|
||||
static int y__30_key(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int y__30_key(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 30
|
||||
&& key(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset39(data, data_len, 0, 1, 30, p_err_no, p_err_posn, err_msg)
|
||||
@ -510,8 +594,8 @@ static int y__30_key(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* N..12,nozeroprefix (Used by CPID SERIAL) */
|
||||
static int n__12_nozeroprefix(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n__12_nozeroprefix(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 12
|
||||
&& nozeroprefix(data, data_len, 0, 1, 12, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& numeric(data, data_len, 0, 1, 12, p_err_no, p_err_posn, err_msg)
|
||||
@ -519,8 +603,8 @@ static int n__12_nozeroprefix(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* X..25,csumalpha,key (Used by GMN) */
|
||||
static int x__25_csumalpha_key(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__25_csumalpha_key(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 25
|
||||
&& csumalpha(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& key(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
@ -529,23 +613,36 @@ static int x__25_csumalpha_key(const unsigned char *data, const int data_len,
|
||||
&& key(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* X..25,csumalpha,key,hasnondigit (Used by MUDI) */
|
||||
static int x__25_csumalpha_key_hasnondigit(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 25
|
||||
&& csumalpha(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& key(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& hasnondigit(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg)
|
||||
&& csumalpha(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& key(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 0)
|
||||
&& hasnondigit(data, data_len, 0, 1, 25, p_err_no, p_err_posn, err_msg, 0);
|
||||
}
|
||||
|
||||
/* N..10 (Used by SRIN) */
|
||||
static int n__10(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int n__10(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 10
|
||||
&& numeric(data, data_len, 0, 1, 10, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* Z..90 (Used by DIGSIG) */
|
||||
static int z__90(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int z__90(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 90
|
||||
&& cset64(data, data_len, 0, 1, 90, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* X..70,couponcode */
|
||||
static int x__70_couponcode(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__70_couponcode(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 70
|
||||
&& couponcode(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg)
|
||||
@ -553,8 +650,8 @@ static int x__70_couponcode(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* X..70,couponposoffer */
|
||||
static int x__70_couponposoffer(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__70_couponposoffer(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 70
|
||||
&& couponposoffer(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg, 1 /*length_only*/)
|
||||
&& cset82(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg)
|
||||
@ -562,15 +659,15 @@ static int x__70_couponposoffer(const unsigned char *data, const int data_len,
|
||||
}
|
||||
|
||||
/* X..70 (Used by PRODUCT URL) */
|
||||
static int x__70(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__70(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 70
|
||||
&& cset82(data, data_len, 0, 1, 70, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
/* X..90 (Used by INTERNAL) */
|
||||
static int x__90(const unsigned char *data, const int data_len,
|
||||
int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
static int x__90(const unsigned char *data,
|
||||
const int data_len, int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
return data_len >= 1 && data_len <= 90
|
||||
&& cset82(data, data_len, 0, 1, 90, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
@ -587,7 +684,7 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
if (ai == 0) {
|
||||
return n18_csum_key(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 1 || ai == 2) {
|
||||
if (ai >= 1 && ai <= 3) {
|
||||
return n14_csum_key(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 10 || ai == 21 || ai == 22) {
|
||||
@ -654,7 +751,7 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
return n3_iso3166(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 423 || ai == 425) {
|
||||
return n__15_iso3166list(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
return n3_iso3166__n3__iso3166__n3__iso3166__n3__iso3166__n3__iso3166(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 427) {
|
||||
return x__3(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
@ -662,7 +759,7 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
|
||||
} else if (ai < 800) {
|
||||
|
||||
if (ai >= 710 && ai <= 715) {
|
||||
if (ai >= 710 && ai <= 716) {
|
||||
return x__20(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
@ -753,7 +850,7 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
return n1_yesno(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 4324 || ai == 4325) {
|
||||
return n6_yymmd0_n4_hhmm(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
return n6_yymmd0_n4_hhmi(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 4326) {
|
||||
return n6_yymmdd(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
@ -771,7 +868,7 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
return x__30(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7003) {
|
||||
return n6_yymmdd_n4_hhmm(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
return n6_yymmdd_n4_hhmi(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7004) {
|
||||
return n__4(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
@ -795,7 +892,7 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
return x__2(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7011) {
|
||||
return n6_yymmdd__n4__hhmm(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
return n6_yymmdd__n4__hhmi(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai >= 7020 && ai <= 7022) {
|
||||
return x__20(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
@ -809,6 +906,9 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
if (ai == 7040) {
|
||||
return n1_x1_x1_x1_importeridx(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7041) {
|
||||
return x__4_packagetype(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
} else if (ai < 7300) {
|
||||
|
||||
@ -824,6 +924,30 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
if (ai == 7242) {
|
||||
return x__25(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7250) {
|
||||
return n8_yyyymmdd(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7251) {
|
||||
return n8_yyyymmdd_n4_hhmi(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7252) {
|
||||
return n1_iso5218(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7253 || ai == 7254 || ai == 7259) {
|
||||
return x__40_pcenc(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7255) {
|
||||
return x__10(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7256) {
|
||||
return x__90_pcenc(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7257) {
|
||||
return x__70_pcenc(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 7258) {
|
||||
return x3_posinseqslash(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
||||
} else if (ai < 8100) {
|
||||
|
||||
@ -849,7 +973,7 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
return x__34_iban(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 8008) {
|
||||
return n8_yymmddhh__n__4__mmoptss(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
return n6_yymmdd_n2_hh__n2__mi__n2__ss(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 8009) {
|
||||
return x__50(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
@ -863,6 +987,9 @@ static int gs1_lint(const int ai, const unsigned char *data, const int data_len,
|
||||
if (ai == 8013) {
|
||||
return x__25_csumalpha_key(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 8014) {
|
||||
return x__25_csumalpha_key_hasnondigit(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
if (ai == 8017 || ai == 8018) {
|
||||
return n18_csum_key(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
}
|
||||
|
118
backend/hanxin.c
@ -1,7 +1,7 @@
|
||||
/* hanxin.c - Han Xin Code */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -364,7 +364,7 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
};
|
||||
|
||||
/* Cost of switching modes from k to j */
|
||||
static const unsigned int switch_costs[HX_NUM_MODES][HX_NUM_MODES] = {
|
||||
static const unsigned char switch_costs[HX_NUM_MODES][HX_NUM_MODES] = {
|
||||
/* N T B 1 2 D F */
|
||||
/*N*/ { 0, (10 + 4) * HX_MULT, (10 + 4 + 13) * HX_MULT, (10 + 4) * HX_MULT, (10 + 4) * HX_MULT, (10 + 4) * HX_MULT, 10 * HX_MULT },
|
||||
/*T*/ { (6 + 4) * HX_MULT, 0, (6 + 4 + 13) * HX_MULT, (6 + 4) * HX_MULT, (6 + 4) * HX_MULT, (6 + 4) * HX_MULT, 6 * HX_MULT },
|
||||
@ -376,7 +376,7 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
};
|
||||
|
||||
/* Final end-of-data costs */
|
||||
static const unsigned int eod_costs[HX_NUM_MODES] = {
|
||||
static const unsigned char eod_costs[HX_NUM_MODES] = {
|
||||
/* N T B 1 2 D F */
|
||||
10 * HX_MULT, 6 * HX_MULT, 0, 12 * HX_MULT, 12 * HX_MULT, 15 * HX_MULT, 0
|
||||
};
|
||||
@ -384,28 +384,28 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
unsigned int numeric_end = 0, numeric_cost = 0, text_submode = 1, fourbyte_end = 0, fourbyte_cost = 0; /* State */
|
||||
int text1, text2;
|
||||
|
||||
int i, j, k, cm_i;
|
||||
int i, j, k;
|
||||
unsigned int min_cost;
|
||||
char cur_mode;
|
||||
unsigned int prev_costs[HX_NUM_MODES];
|
||||
unsigned int cur_costs[HX_NUM_MODES];
|
||||
char *char_modes = (char *) z_alloca(length * HX_NUM_MODES);
|
||||
char (*char_modes)[HX_NUM_MODES] = (char (*)[HX_NUM_MODES]) z_alloca(HX_NUM_MODES * length);
|
||||
|
||||
/* char_modes[i * HX_NUM_MODES + j] represents the mode to encode the code point at index i such that the final
|
||||
* segment ends in mode_types[j] and the total number of bits is minimized over all possible choices */
|
||||
memset(char_modes, 0, length * HX_NUM_MODES);
|
||||
/* char_modes[i][j] represents the mode to encode the code point at index i such that the final segment
|
||||
ends in mode_types[j] and the total number of bits is minimized over all possible choices */
|
||||
memset(char_modes, 0, HX_NUM_MODES * length);
|
||||
|
||||
/* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/XX_MULT)
|
||||
* bits needed to encode the entire string prefix of length i, and end in mode_types[j] */
|
||||
memcpy(prev_costs, head_costs, HX_NUM_MODES * sizeof(unsigned int));
|
||||
|
||||
/* Calculate costs using dynamic programming */
|
||||
for (i = 0, cm_i = 0; i < length; i++, cm_i += HX_NUM_MODES) {
|
||||
for (i = 0; i < length; i++) {
|
||||
memset(cur_costs, 0, HX_NUM_MODES * sizeof(unsigned int));
|
||||
|
||||
if (hx_in_numeric(ddata, length, i, &numeric_end, &numeric_cost)) {
|
||||
cur_costs[HX_N] = prev_costs[HX_N] + numeric_cost;
|
||||
char_modes[cm_i + HX_N] = 'n';
|
||||
char_modes[i][HX_N] = 'n';
|
||||
text1 = 1;
|
||||
text2 = 0;
|
||||
} else {
|
||||
@ -420,35 +420,35 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
} else {
|
||||
cur_costs[HX_T] = prev_costs[HX_T] + 36; /* 6 * HX_MULT */
|
||||
}
|
||||
char_modes[cm_i + HX_T] = 't';
|
||||
char_modes[i][HX_T] = 't';
|
||||
} else {
|
||||
text_submode = 1;
|
||||
}
|
||||
|
||||
/* Binary mode can encode anything */
|
||||
cur_costs[HX_B] = prev_costs[HX_B] + (ddata[i] > 0xFF ? 96 : 48); /* (16 : 8) * HX_MULT */
|
||||
char_modes[cm_i + HX_B] = 'b';
|
||||
char_modes[i][HX_B] = 'b';
|
||||
|
||||
if (hx_in_fourbyte(ddata, length, i, &fourbyte_end, &fourbyte_cost)) {
|
||||
cur_costs[HX_F] = prev_costs[HX_F] + fourbyte_cost;
|
||||
char_modes[cm_i + HX_F] = 'f';
|
||||
char_modes[i][HX_F] = 'f';
|
||||
} else {
|
||||
if (hx_isDoubleByte(ddata[i])) {
|
||||
cur_costs[HX_D] = prev_costs[HX_D] + 90; /* 15 * HX_MULT */
|
||||
char_modes[cm_i + HX_D] = 'd';
|
||||
char_modes[i][HX_D] = 'd';
|
||||
if (hx_isRegion1(ddata[i])) { /* Subset */
|
||||
cur_costs[HX_1] = prev_costs[HX_1] + 72; /* 12 * HX_MULT */
|
||||
char_modes[cm_i + HX_1] = '1';
|
||||
char_modes[i][HX_1] = '1';
|
||||
} else if (hx_isRegion2(ddata[i])) { /* Subset */
|
||||
cur_costs[HX_2] = prev_costs[HX_2] + 72; /* 12 * HX_MULT */
|
||||
char_modes[cm_i + HX_2] = '2';
|
||||
char_modes[i][HX_2] = '2';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == length - 1) { /* Add end of data costs if last character */
|
||||
for (j = 0; j < HX_NUM_MODES; j++) {
|
||||
if (char_modes[cm_i + j]) {
|
||||
if (char_modes[i][j]) {
|
||||
cur_costs[j] += eod_costs[j];
|
||||
}
|
||||
}
|
||||
@ -457,11 +457,11 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
/* Start new segment at the end to switch modes */
|
||||
for (j = 0; j < HX_NUM_MODES; j++) { /* To mode */
|
||||
for (k = 0; k < HX_NUM_MODES; k++) { /* From mode */
|
||||
if (j != k && char_modes[cm_i + k]) {
|
||||
if (j != k && char_modes[i][k]) {
|
||||
const unsigned int new_cost = cur_costs[k] + switch_costs[k][j];
|
||||
if (!char_modes[cm_i + j] || new_cost < cur_costs[j]) {
|
||||
if (!char_modes[i][j] || new_cost < cur_costs[j]) {
|
||||
cur_costs[j] = new_cost;
|
||||
char_modes[cm_i + j] = mode_types[k];
|
||||
char_modes[i][j] = mode_types[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -481,9 +481,9 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
||||
}
|
||||
|
||||
/* Get optimal mode for each code point by tracing backwards */
|
||||
for (i = length - 1, cm_i = i * HX_NUM_MODES; i >= 0; i--, cm_i -= HX_NUM_MODES) {
|
||||
for (i = length - 1; i >= 0; i--) {
|
||||
j = posn(mode_types, cur_mode);
|
||||
cur_mode = char_modes[cm_i + j];
|
||||
cur_mode = char_modes[i][j];
|
||||
mode[i] = cur_mode;
|
||||
}
|
||||
|
||||
@ -1521,8 +1521,8 @@ INTERNAL int hanxin(struct zint_symbol *symbol, struct zint_seg segs[], const in
|
||||
if (error_number == 0) {
|
||||
done = 1;
|
||||
} else if (local_segs[i].eci || seg_count > 1) {
|
||||
sprintf(symbol->errtxt, "545: Invalid character in input data for ECI %d", local_segs[i].eci);
|
||||
return error_number;
|
||||
return errtxtf(error_number, symbol, 545, "Invalid character in input for ECI '%d'",
|
||||
local_segs[i].eci);
|
||||
}
|
||||
}
|
||||
if (!done) {
|
||||
@ -1532,8 +1532,8 @@ INTERNAL int hanxin(struct zint_symbol *symbol, struct zint_seg segs[], const in
|
||||
return error_number;
|
||||
}
|
||||
if (local_segs[i].eci != 32) {
|
||||
strcpy(symbol->errtxt, "543: Converted to GB 18030 but no ECI specified");
|
||||
warn_number = ZINT_WARN_NONCOMPLIANT;
|
||||
warn_number = errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 543,
|
||||
"Converted to GB 18030 but no ECI specified");
|
||||
}
|
||||
}
|
||||
dd += local_segs[i].length;
|
||||
@ -1543,8 +1543,11 @@ INTERNAL int hanxin(struct zint_symbol *symbol, struct zint_seg segs[], const in
|
||||
hx_define_mode_segs(mode, ddata, local_segs, seg_count, debug_print);
|
||||
|
||||
est_binlen = hx_calc_binlen_segs(mode, ddata, local_segs, seg_count);
|
||||
if (debug_print) {
|
||||
printf("Estimated binary length: %d\n", est_binlen);
|
||||
}
|
||||
|
||||
binary = (char *) z_alloca((est_binlen + 1));
|
||||
binary = (char *) malloc(est_binlen + 1);
|
||||
|
||||
if ((ecc_level <= 0) || (ecc_level >= 5)) {
|
||||
ecc_level = 1;
|
||||
@ -1561,40 +1564,16 @@ INTERNAL int hanxin(struct zint_symbol *symbol, struct zint_seg segs[], const in
|
||||
|
||||
version = 85;
|
||||
for (i = 84; i > 0; i--) {
|
||||
switch (ecc_level) {
|
||||
case 1:
|
||||
if (hx_data_codewords_L1[i - 1] >= codewords) {
|
||||
version = i;
|
||||
data_codewords = hx_data_codewords_L1[i - 1];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (hx_data_codewords_L2[i - 1] >= codewords) {
|
||||
version = i;
|
||||
data_codewords = hx_data_codewords_L2[i - 1];
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (hx_data_codewords_L3[i - 1] >= codewords) {
|
||||
version = i;
|
||||
data_codewords = hx_data_codewords_L3[i - 1];
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (hx_data_codewords_L4[i - 1] >= codewords) {
|
||||
version = i;
|
||||
data_codewords = hx_data_codewords_L4[i - 1];
|
||||
}
|
||||
break;
|
||||
default: /* Not reached */
|
||||
assert(0);
|
||||
break;
|
||||
if (hx_data_codewords[ecc_level - 1][i - 1] >= codewords) {
|
||||
version = i;
|
||||
data_codewords = hx_data_codewords[ecc_level - 1][i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (version == 85) {
|
||||
strcpy(symbol->errtxt, "541: Input too long for selected error correction level");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
free(binary);
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 541, "Input too long, requires %d codewords (maximum 3264)",
|
||||
codewords);
|
||||
}
|
||||
|
||||
if ((symbol->option_2 < 0) || (symbol->option_2 > 84)) {
|
||||
@ -1606,27 +1585,35 @@ INTERNAL int hanxin(struct zint_symbol *symbol, struct zint_seg segs[], const in
|
||||
}
|
||||
|
||||
if ((symbol->option_2 != 0) && (symbol->option_2 < version)) {
|
||||
strcpy(symbol->errtxt, "542: Input too long for selected symbol size");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
free(binary);
|
||||
if (ecc_level == 1) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 542,
|
||||
"Input too long for Version %1$d, requires %2$d codewords (maximum %3$d)",
|
||||
symbol->option_2, codewords, hx_data_codewords[ecc_level - 1][symbol->option_2 - 1]);
|
||||
}
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 542,
|
||||
"Input too long for Version %1$d, ECC %2$d, requires %3$d codewords (maximum %4$d)",
|
||||
symbol->option_2, ecc_level, codewords,
|
||||
hx_data_codewords[ecc_level - 1][symbol->option_2 - 1]);
|
||||
}
|
||||
|
||||
/* If there is spare capacity, increase the level of ECC */
|
||||
|
||||
/* Unless explicitly specified (within min/max bounds) by user */
|
||||
if (symbol->option_1 == -1 || symbol->option_1 != ecc_level) {
|
||||
if ((ecc_level == 1) && (codewords <= hx_data_codewords_L2[version - 1])) {
|
||||
if (ecc_level == 1 && codewords <= hx_data_codewords[1][version - 1]) {
|
||||
ecc_level = 2;
|
||||
data_codewords = hx_data_codewords_L2[version - 1];
|
||||
data_codewords = hx_data_codewords[1][version - 1];
|
||||
}
|
||||
|
||||
if ((ecc_level == 2) && (codewords <= hx_data_codewords_L3[version - 1])) {
|
||||
if (ecc_level == 2 && codewords <= hx_data_codewords[2][version - 1]) {
|
||||
ecc_level = 3;
|
||||
data_codewords = hx_data_codewords_L3[version - 1];
|
||||
data_codewords = hx_data_codewords[2][version - 1];
|
||||
}
|
||||
|
||||
if ((ecc_level == 3) && (codewords <= hx_data_codewords_L4[version - 1])) {
|
||||
if (ecc_level == 3 && codewords <= hx_data_codewords[3][version - 1]) {
|
||||
ecc_level = 4;
|
||||
data_codewords = hx_data_codewords_L4[version - 1];
|
||||
data_codewords = hx_data_codewords[3][version - 1];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1645,6 +1632,7 @@ INTERNAL int hanxin(struct zint_symbol *symbol, struct zint_seg segs[], const in
|
||||
datastream[i >> 3] |= 0x80 >> (i & 0x07);
|
||||
}
|
||||
}
|
||||
free(binary);
|
||||
|
||||
if (debug_print) {
|
||||
printf("Datastream (%d):", data_codewords);
|
||||
|
799
backend/hanxin.h
@ -1,7 +1,7 @@
|
||||
/* hanxin.h - definitions for Han Xin code */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2016 Zoe Stuart
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -35,57 +35,64 @@
|
||||
#define Z_HANXIN_H
|
||||
|
||||
/* Data from table B1: Data capacity of Han Xin Code */
|
||||
static const unsigned short hx_total_codewords[] = {
|
||||
25, 37, 50, 54, 69, 84, 100, 117, 136, 155, 161, 181, 203, 225, 249,
|
||||
273, 299, 325, 353, 381, 411, 422, 453, 485, 518, 552, 587, 623, 660,
|
||||
698, 737, 754, 794, 836, 878, 922, 966, 1011, 1058, 1105, 1126, 1175,
|
||||
1224, 1275, 1327, 1380, 1434, 1489, 1513, 1569, 1628, 1686, 1745, 1805,
|
||||
1867, 1929, 1992, 2021, 2086, 2151, 2218, 2286, 2355, 2425, 2496, 2528,
|
||||
2600, 2673, 2749, 2824, 2900, 2977, 3056, 3135, 3171, 3252, 3334, 3416,
|
||||
3500, 3585, 3671, 3758, 3798, 3886
|
||||
static const unsigned short hx_total_codewords[84] = {
|
||||
25, 37, 50, 54, 69, 84, 100, 117, 136, 155,
|
||||
161, 181, 203, 225, 249, 273, 299, 325, 353, 381,
|
||||
411, 422, 453, 485, 518, 552, 587, 623, 660, 698,
|
||||
737, 754, 794, 836, 878, 922, 966, 1011, 1058, 1105,
|
||||
1126, 1175, 1224, 1275, 1327, 1380, 1434, 1489, 1513, 1569,
|
||||
1628, 1686, 1745, 1805, 1867, 1929, 1992, 2021, 2086, 2151,
|
||||
2218, 2286, 2355, 2425, 2496, 2528, 2600, 2673, 2749, 2824,
|
||||
2900, 2977, 3056, 3135, 3171, 3252, 3334, 3416, 3500, 3585,
|
||||
3671, 3758, 3798, 3886
|
||||
};
|
||||
|
||||
static const unsigned short hx_data_codewords_L1[] = {
|
||||
21, 31, 42, 46, 57, 70, 84, 99, 114, 131, 135, 153, 171, 189, 209, 229,
|
||||
251, 273, 297, 321, 345, 354, 381, 407, 436, 464, 493, 523, 554, 586, 619,
|
||||
634, 666, 702, 738, 774, 812, 849, 888, 929, 946, 987, 1028, 1071, 1115,
|
||||
1160, 1204, 1251, 1271, 1317, 1368, 1416, 1465, 1517, 1569, 1621, 1674,
|
||||
1697, 1752, 1807, 1864, 1920, 1979, 2037, 2096, 2124, 2184, 2245, 2309,
|
||||
2372, 2436, 2501, 2568, 2633, 2663, 2732, 2800, 2870, 2940, 3011,
|
||||
3083, 3156, 3190, 3264
|
||||
};
|
||||
|
||||
static const unsigned short hx_data_codewords_L2[] = {
|
||||
17, 25, 34, 38, 49, 58, 70, 81, 96, 109, 113, 127, 143, 157, 175, 191, 209,
|
||||
227, 247, 267, 287, 296, 317, 339, 362, 386, 411, 437, 462, 488, 515, 528,
|
||||
556, 586, 614, 646, 676, 707, 740, 773, 788, 823, 856, 893, 929, 966, 1004,
|
||||
1043, 1059, 1099, 1140, 1180, 1221, 1263, 1307, 1351, 1394, 1415, 1460,
|
||||
1505, 1552, 1600, 1649, 1697, 1748, 1770, 1820, 1871, 1925, 1976, 2030,
|
||||
2083, 2140, 2195, 2219, 2276, 2334, 2392, 2450, 2509, 2569, 2630, 2658,
|
||||
2720
|
||||
};
|
||||
|
||||
static const unsigned short hx_data_codewords_L3[] = {
|
||||
13, 19, 26, 30, 37, 46, 54, 63, 74, 83, 87, 97, 109, 121, 135, 147, 161,
|
||||
175, 191, 205, 221, 228, 245, 261, 280, 298, 317, 337, 358, 376, 397, 408,
|
||||
428, 452, 474, 498, 522, 545, 572, 597, 608, 635, 660, 689, 717, 746, 774,
|
||||
805, 817, 847, 880, 910, 943, 975, 1009, 1041, 1076, 1091, 1126, 1161, 1198,
|
||||
1234, 1271, 1309, 1348, 1366, 1404, 1443, 1485, 1524, 1566, 1607, 1650, 1693,
|
||||
1713, 1756, 1800, 1844, 1890, 1935, 1983, 2030, 2050, 2098
|
||||
};
|
||||
|
||||
static const unsigned short hx_data_codewords_L4[] = {
|
||||
9, 15, 20, 22, 27, 34, 40, 47, 54, 61, 65, 73, 81, 89, 99, 109, 119, 129,
|
||||
141, 153, 165, 168, 181, 195, 208, 220, 235, 251, 264, 280, 295, 302, 318,
|
||||
334, 352, 368, 386, 405, 424, 441, 450, 469, 490, 509, 531, 552, 574, 595, 605,
|
||||
627, 652, 674, 697, 721, 747, 771, 796, 809, 834, 861, 892, 914, 941, 969, 998,
|
||||
1012, 1040, 1069, 1099, 1130, 1160, 1191, 1222, 1253, 1269, 1300, 1334,
|
||||
1366, 1400, 1433, 1469, 1504, 1520, 1554
|
||||
static const unsigned short hx_data_codewords[4][84] = { {
|
||||
21, 31, 42, 46, 57, 70, 84, 99, 114, 131,
|
||||
135, 153, 171, 189, 209, 229, 251, 273, 297, 321,
|
||||
345, 354, 381, 407, 436, 464, 493, 523, 554, 586,
|
||||
619, 634, 666, 702, 738, 774, 812, 849, 888, 929,
|
||||
946, 987, 1028, 1071, 1115, 1160, 1204, 1251, 1271, 1317,
|
||||
1368, 1416, 1465, 1517, 1569, 1621, 1674, 1697, 1752, 1807,
|
||||
1864, 1920, 1979, 2037, 2096, 2124, 2184, 2245, 2309, 2372,
|
||||
2436, 2501, 2568, 2633, 2663, 2732, 2800, 2870, 2940, 3011,
|
||||
3083, 3156, 3190, 3264
|
||||
}, {
|
||||
17, 25, 34, 38, 49, 58, 70, 81, 96, 109,
|
||||
113, 127, 143, 157, 175, 191, 209, 227, 247, 267,
|
||||
287, 296, 317, 339, 362, 386, 411, 437, 462, 488,
|
||||
515, 528, 556, 586, 614, 646, 676, 707, 740, 773,
|
||||
788, 823, 856, 893, 929, 966, 1004, 1043, 1059, 1099,
|
||||
1140, 1180, 1221, 1263, 1307, 1351, 1394, 1415, 1460, 1505,
|
||||
1552, 1600, 1649, 1697, 1748, 1770, 1820, 1871, 1925, 1976,
|
||||
2030, 2083, 2140, 2195, 2219, 2276, 2334, 2392, 2450, 2509,
|
||||
2569, 2630, 2658, 2720
|
||||
}, {
|
||||
13, 19, 26, 30, 37, 46, 54, 63, 74, 83,
|
||||
87, 97, 109, 121, 135, 147, 161, 175, 191, 205,
|
||||
221, 228, 245, 261, 280, 298, 317, 337, 358, 376,
|
||||
397, 408, 428, 452, 474, 498, 522, 545, 572, 597,
|
||||
608, 635, 660, 689, 717, 746, 774, 805, 817, 847,
|
||||
880, 910, 943, 975, 1009, 1041, 1076, 1091, 1126, 1161,
|
||||
1198, 1234, 1271, 1309, 1348, 1366, 1404, 1443, 1485, 1524,
|
||||
1566, 1607, 1650, 1693, 1713, 1756, 1800, 1844, 1890, 1935,
|
||||
1983, 2030, 2050, 2098
|
||||
}, {
|
||||
9, 15, 20, 22, 27, 34, 40, 47, 54, 61,
|
||||
65, 73, 81, 89, 99, 109, 119, 129, 141, 153,
|
||||
165, 168, 181, 195, 208, 220, 235, 251, 264, 280,
|
||||
295, 302, 318, 334, 352, 368, 386, 405, 424, 441,
|
||||
450, 469, 490, 509, 531, 552, 574, 595, 605, 627,
|
||||
652, 674, 697, 721, 747, 771, 796, 809, 834, 861,
|
||||
892, 914, 941, 969, 998, 1012, 1040, 1069, 1099, 1130,
|
||||
1160, 1191, 1222, 1253, 1269, 1300, 1334, 1366, 1400, 1433,
|
||||
1469, 1504, 1520, 1554
|
||||
}
|
||||
};
|
||||
|
||||
/* Value 'k' from Annex A */
|
||||
static const char hx_module_k[] = {
|
||||
0, 0, 0, 14, 16, 16, 17, 18, 19, 20,
|
||||
static const char hx_module_k[84] = {
|
||||
0, 0, 0, 14, 16, 16, 17, 18, 19, 20,
|
||||
14, 15, 16, 16, 17, 17, 18, 19, 20, 20,
|
||||
21, 16, 17, 17, 18, 18, 19, 19, 20, 20,
|
||||
21, 17, 17, 18, 18, 19, 19, 19, 20, 20,
|
||||
@ -97,8 +104,8 @@ static const char hx_module_k[] = {
|
||||
};
|
||||
|
||||
/* Value 'r' from Annex A */
|
||||
static const char hx_module_r[] = {
|
||||
0, 0, 0, 15, 15, 17, 18, 19, 20, 21,
|
||||
static const char hx_module_r[84] = {
|
||||
0, 0, 0, 15, 15, 17, 18, 19, 20, 21,
|
||||
15, 15, 15, 17, 17, 19, 19, 19, 19, 21,
|
||||
21, 17, 16, 18, 17, 19, 18, 20, 19, 21,
|
||||
20, 17, 19, 17, 19, 17, 19, 21, 19, 21,
|
||||
@ -110,357 +117,357 @@ static const char hx_module_r[] = {
|
||||
};
|
||||
|
||||
/* Value of 'm' from Annex A */
|
||||
static const char hx_module_m[] = {
|
||||
0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 10, 10
|
||||
static const char hx_module_m[84] = {
|
||||
0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 10, 10
|
||||
};
|
||||
|
||||
/* Error correction block sizes from Table D1 */
|
||||
static const unsigned char hx_table_d1[] = {
|
||||
/* #blocks, k, 2t, #blocks, k, 2t, #blocks, k, 2t */
|
||||
1, 21, 4, 0, 0, 0, 0, 0, 0, /* version 1 */
|
||||
1, 17, 8, 0, 0, 0, 0, 0, 0,
|
||||
1, 13, 12, 0, 0, 0, 0, 0, 0,
|
||||
1, 9, 16, 0, 0, 0, 0, 0, 0,
|
||||
1, 31, 6, 0, 0, 0, 0, 0, 0, /* version 2 */
|
||||
1, 25, 12, 0, 0, 0, 0, 0, 0,
|
||||
1, 19, 18, 0, 0, 0, 0, 0, 0,
|
||||
1, 15, 22, 0, 0, 0, 0, 0, 0,
|
||||
1, 42, 8, 0, 0, 0, 0, 0, 0, /* version 3 */
|
||||
1, 34, 16, 0, 0, 0, 0, 0, 0,
|
||||
1, 26, 24, 0, 0, 0, 0, 0, 0,
|
||||
1, 20, 30, 0, 0, 0, 0, 0, 0,
|
||||
1, 46, 8, 0, 0, 0, 0, 0, 0, /* version 4 */
|
||||
1, 38, 16, 0, 0, 0, 0, 0, 0,
|
||||
1, 30, 24, 0, 0, 0, 0, 0, 0,
|
||||
1, 22, 32, 0, 0, 0, 0, 0, 0,
|
||||
1, 57, 12, 0, 0, 0, 0, 0, 0, /* version 5 */
|
||||
1, 49, 20, 0, 0, 0, 0, 0, 0,
|
||||
1, 37, 32, 0, 0, 0, 0, 0, 0,
|
||||
1, 14, 20, 1, 13, 22, 0, 0, 0,
|
||||
1, 70, 14, 0, 0, 0, 0, 0, 0, /* version 6 */
|
||||
1, 58, 26, 0, 0, 0, 0, 0, 0,
|
||||
1, 24, 20, 1, 22, 18, 0, 0, 0,
|
||||
1, 16, 24, 1, 18, 26, 0, 0, 0,
|
||||
1, 84, 16, 0, 0, 0, 0, 0, 0, /* version 7 */
|
||||
1, 70, 30, 0, 0, 0, 0, 0, 0,
|
||||
1, 26, 22, 1, 28, 24, 0, 0, 0,
|
||||
2, 14, 20, 1, 12, 20, 0, 0, 0,
|
||||
1, 99, 18, 0, 0, 0, 0, 0, 0, /* version 8 */
|
||||
1, 40, 18, 1, 41, 18, 0, 0, 0,
|
||||
1, 31, 26, 1, 32, 28, 0, 0, 0,
|
||||
2, 16, 24, 1, 15, 22, 0, 0, 0,
|
||||
1, 114, 22, 0, 0, 0, 0, 0, 0, /* version 9 */
|
||||
2, 48, 20, 0, 0, 0, 0, 0, 0,
|
||||
2, 24, 20, 1, 26, 22, 0, 0, 0,
|
||||
2, 18, 28, 1, 18, 26, 0, 0, 0,
|
||||
1, 131, 24, 0, 0, 0, 0, 0, 0, /* version 10 */
|
||||
1, 52, 22, 1, 57, 24, 0, 0, 0,
|
||||
2, 27, 24, 1, 29, 24, 0, 0, 0,
|
||||
2, 21, 32, 1, 19, 30, 0, 0, 0,
|
||||
1, 135, 26, 0, 0, 0, 0, 0, 0, /* version 11 */
|
||||
1, 56, 24, 1, 57, 24, 0, 0, 0,
|
||||
2, 28, 24, 1, 31, 26, 0, 0, 0,
|
||||
2, 22, 32, 1, 21, 32, 0, 0, 0,
|
||||
1, 153, 28, 0, 0, 0, 0, 0, 0, /* version 12 */
|
||||
1, 62, 26, 1, 65, 28, 0, 0, 0,
|
||||
2, 32, 28, 1, 33, 28, 0, 0, 0,
|
||||
3, 17, 26, 1, 22, 30, 0, 0, 0,
|
||||
1, 86, 16, 1, 85, 16, 0, 0, 0, /* version 13 */
|
||||
1, 71, 30, 1, 72, 30, 0, 0, 0,
|
||||
2, 37, 32, 1, 35, 30, 0, 0, 0,
|
||||
3, 20, 30, 1, 21, 32, 0, 0, 0,
|
||||
1, 94, 18, 1, 95, 18, 0, 0, 0, /* version 14 */
|
||||
2, 51, 22, 1, 55, 24, 0, 0, 0,
|
||||
3, 30, 26, 1, 31, 26, 0, 0, 0,
|
||||
4, 18, 28, 1, 17, 24, 0, 0, 0,
|
||||
1, 104, 20, 1, 105, 20, 0, 0, 0, /* version 15 */
|
||||
2, 57, 24, 1, 61, 26, 0, 0, 0,
|
||||
3, 33, 28, 1, 36, 30, 0, 0, 0,
|
||||
4, 20, 30, 1, 19, 30, 0, 0, 0,
|
||||
1, 115, 22, 1, 114, 22, 0, 0, 0, /* version 16 */
|
||||
2, 65, 28, 1, 61, 26, 0, 0, 0,
|
||||
3, 38, 32, 1, 33, 30, 0, 0, 0,
|
||||
5, 19, 28, 1, 14, 24, 0, 0, 0,
|
||||
1, 126, 24, 1, 125, 24, 0, 0, 0, /* version 17 */
|
||||
2, 70, 30, 1, 69, 30, 0, 0, 0,
|
||||
4, 33, 28, 1, 29, 26, 0, 0, 0,
|
||||
5, 20, 30, 1, 19, 30, 0, 0, 0,
|
||||
1, 136, 26, 1, 137, 26, 0, 0, 0, /* version 18 */
|
||||
3, 56, 24, 1, 59, 26, 0, 0, 0,
|
||||
5, 35, 30, 0, 0, 0, 0, 0, 0,
|
||||
6, 18, 28, 1, 21, 28, 0, 0, 0,
|
||||
1, 148, 28, 1, 149, 28, 0, 0, 0, /* version 19 */
|
||||
3, 61, 26, 1, 64, 28, 0, 0, 0,
|
||||
7, 24, 20, 1, 23, 22, 0, 0, 0,
|
||||
6, 20, 30, 1, 21, 32, 0, 0, 0,
|
||||
3, 107, 20, 0, 0, 0, 0, 0, 0, /* version 20 */
|
||||
3, 65, 28, 1, 72, 30, 0, 0, 0,
|
||||
7, 26, 22, 1, 23, 22, 0, 0, 0,
|
||||
7, 19, 28, 1, 20, 32, 0, 0, 0,
|
||||
3, 115, 22, 0, 0, 0, 0, 0, 0, /* version 21 */
|
||||
4, 56, 24, 1, 63, 28, 0, 0, 0,
|
||||
7, 28, 24, 1, 25, 22, 0, 0, 0,
|
||||
8, 18, 28, 1, 21, 22, 0, 0, 0,
|
||||
2, 116, 22, 1, 122, 24, 0, 0, 0, /* version 22 */
|
||||
4, 56, 24, 1, 72, 30, 0, 0, 0,
|
||||
7, 28, 24, 1, 32, 26, 0, 0, 0,
|
||||
8, 18, 28, 1, 24, 30, 0, 0, 0,
|
||||
3, 127, 24, 0, 0, 0, 0, 0, 0, /* version 23 */
|
||||
5, 51, 22, 1, 62, 26, 0, 0, 0,
|
||||
7, 30, 26, 1, 35, 26, 0, 0, 0,
|
||||
8, 20, 30, 1, 21, 32, 0, 0, 0,
|
||||
2, 135, 26, 1, 137, 26, 0, 0, 0, /* version 24 */
|
||||
5, 56, 24, 1, 59, 26, 0, 0, 0,
|
||||
7, 33, 28, 1, 30, 28, 0, 0, 0,
|
||||
11, 16, 24, 1, 19, 26, 0, 0, 0,
|
||||
3, 105, 20, 1, 121, 22, 0, 0, 0, /* version 25 */
|
||||
5, 61, 26, 1, 57, 26, 0, 0, 0,
|
||||
9, 28, 24, 1, 28, 22, 0, 0, 0,
|
||||
10, 19, 28, 1, 18, 30, 0, 0, 0,
|
||||
2, 157, 30, 1, 150, 28, 0, 0, 0, /* version 26 */
|
||||
5, 65, 28, 1, 61, 26, 0, 0, 0,
|
||||
8, 33, 28, 1, 34, 30, 0, 0, 0,
|
||||
10, 19, 28, 2, 15, 26, 0, 0, 0,
|
||||
3, 126, 24, 1, 115, 22, 0, 0, 0, /* version 27 */
|
||||
7, 51, 22, 1, 54, 22, 0, 0, 0,
|
||||
8, 35, 30, 1, 37, 30, 0, 0, 0,
|
||||
15, 15, 22, 1, 10, 22, 0, 0, 0,
|
||||
4, 105, 20, 1, 103, 20, 0, 0, 0, /* version 28 */
|
||||
7, 56, 24, 1, 45, 18, 0, 0, 0,
|
||||
10, 31, 26, 1, 27, 26, 0, 0, 0,
|
||||
10, 17, 26, 3, 20, 28, 1, 21, 28,
|
||||
3, 139, 26, 1, 137, 28, 0, 0, 0, /* version 29 */
|
||||
6, 66, 28, 1, 66, 30, 0, 0, 0,
|
||||
9, 36, 30, 1, 34, 32, 0, 0, 0,
|
||||
13, 19, 28, 1, 17, 32, 0, 0, 0,
|
||||
6, 84, 16, 1, 82, 16, 0, 0, 0, /* version 30 */
|
||||
6, 70, 30, 1, 68, 30, 0, 0, 0,
|
||||
7, 35, 30, 3, 33, 28, 1, 32, 28,
|
||||
13, 20, 30, 1, 20, 28, 0, 0, 0,
|
||||
5, 105, 20, 1, 94, 18, 0, 0, 0, /* version 31 */
|
||||
6, 74, 32, 1, 71, 30, 0, 0, 0,
|
||||
11, 33, 28, 1, 34, 32, 0, 0, 0,
|
||||
13, 19, 28, 3, 16, 26, 0, 0, 0,
|
||||
4, 127, 24, 1, 126, 24, 0, 0, 0, /* version 32 */
|
||||
7, 66, 28, 1, 66, 30, 0, 0, 0,
|
||||
12, 30, 24, 1, 24, 28, 1, 24, 30,
|
||||
15, 19, 28, 1, 17, 32, 0, 0, 0,
|
||||
7, 84, 16, 1, 78, 16, 0, 0, 0, /* version 33 */
|
||||
7, 70, 30, 1, 66, 28, 0, 0, 0,
|
||||
12, 33, 28, 1, 32, 30, 0, 0, 0,
|
||||
14, 21, 32, 1, 24, 28, 0, 0, 0,
|
||||
5, 117, 22, 1, 117, 24, 0, 0, 0, /* version 34 */
|
||||
8, 66, 28, 1, 58, 26, 0, 0, 0,
|
||||
11, 38, 32, 1, 34, 32, 0, 0, 0,
|
||||
15, 20, 30, 2, 17, 26, 0, 0, 0,
|
||||
4, 148, 28, 1, 146, 28, 0, 0, 0, /* version 35 */
|
||||
8, 68, 30, 1, 70, 24, 0, 0, 0,
|
||||
10, 36, 32, 3, 38, 28, 0, 0, 0,
|
||||
16, 19, 28, 3, 16, 26, 0, 0, 0,
|
||||
4, 126, 24, 2, 135, 26, 0, 0, 0, /* version 36 */
|
||||
8, 70, 28, 2, 43, 26, 0, 0, 0,
|
||||
13, 32, 28, 2, 41, 30, 0, 0, 0,
|
||||
17, 19, 28, 3, 15, 26, 0, 0, 0,
|
||||
5, 136, 26, 1, 132, 24, 0, 0, 0, /* version 37 */
|
||||
5, 67, 30, 4, 68, 28, 1, 69, 28,
|
||||
14, 35, 30, 1, 32, 24, 0, 0, 0,
|
||||
18, 18, 26, 3, 16, 28, 1, 14, 28,
|
||||
3, 142, 26, 3, 141, 28, 0, 0, 0, /* version 38 */
|
||||
8, 70, 30, 1, 73, 32, 1, 74, 32,
|
||||
12, 34, 30, 3, 34, 26, 1, 35, 28,
|
||||
18, 21, 32, 1, 27, 30, 0, 0, 0,
|
||||
5, 116, 22, 2, 103, 20, 1, 102, 20, /* version 39 */
|
||||
9, 74, 32, 1, 74, 30, 0, 0, 0,
|
||||
14, 34, 28, 2, 32, 32, 1, 32, 30,
|
||||
19, 21, 32, 1, 25, 26, 0, 0, 0,
|
||||
7, 116, 22, 1, 117, 22, 0, 0, 0, /* version 40 */
|
||||
11, 65, 28, 1, 58, 24, 0, 0, 0,
|
||||
15, 38, 32, 1, 27, 28, 0, 0, 0,
|
||||
20, 20, 30, 1, 20, 32, 1, 21, 32,
|
||||
6, 136, 26, 1, 130, 24, 0, 0, 0, /* version 41 */
|
||||
11, 66, 28, 1, 62, 30, 0, 0, 0,
|
||||
14, 34, 28, 3, 34, 32, 1, 30, 30,
|
||||
18, 20, 30, 3, 20, 28, 2, 15, 26,
|
||||
5, 105, 20, 2, 115, 22, 2, 116, 22, /* version 42 */
|
||||
10, 75, 32, 1, 73, 32, 0, 0, 0,
|
||||
16, 38, 32, 1, 27, 28, 0, 0, 0,
|
||||
22, 19, 28, 2, 16, 30, 1, 19, 30,
|
||||
6, 147, 28, 1, 146, 28, 0, 0, 0, /* version 43 */
|
||||
11, 66, 28, 2, 65, 30, 0, 0, 0,
|
||||
18, 33, 28, 2, 33, 30, 0, 0, 0,
|
||||
22, 21, 32, 1, 28, 30, 0, 0, 0,
|
||||
6, 116, 22, 3, 125, 24, 0, 0, 0, /* version 44 */
|
||||
11, 75, 32, 1, 68, 30, 0, 0, 0,
|
||||
13, 35, 28, 6, 34, 32, 1, 30, 30,
|
||||
23, 21, 32, 1, 26, 30, 0, 0, 0,
|
||||
7, 105, 20, 4, 95, 18, 0, 0, 0, /* version 45 */
|
||||
12, 67, 28, 1, 63, 30, 1, 62, 32,
|
||||
21, 31, 26, 2, 33, 32, 0, 0, 0,
|
||||
23, 21, 32, 2, 24, 30, 0, 0, 0,
|
||||
10, 116, 22, 0, 0, 0, 0, 0, 0, /* version 46 */
|
||||
12, 74, 32, 1, 78, 30, 0, 0, 0,
|
||||
18, 37, 32, 1, 39, 30, 1, 41, 28,
|
||||
25, 21, 32, 1, 27, 28, 0, 0, 0,
|
||||
5, 126, 24, 4, 115, 22, 1, 114, 22, /* version 47 */
|
||||
12, 67, 28, 2, 66, 32, 1, 68, 30,
|
||||
21, 35, 30, 1, 39, 30, 0, 0, 0,
|
||||
26, 21, 32, 1, 28, 28, 0, 0, 0,
|
||||
9, 126, 24, 1, 117, 22, 0, 0, 0, /* version 48 */
|
||||
13, 75, 32, 1, 68, 30, 0, 0, 0,
|
||||
20, 35, 30, 3, 35, 28, 0, 0, 0,
|
||||
27, 21, 32, 1, 28, 30, 0, 0, 0,
|
||||
9, 126, 24, 1, 137, 26, 0, 0, 0, /* version 49 */
|
||||
13, 71, 30, 2, 68, 32, 0, 0, 0,
|
||||
20, 37, 32, 1, 39, 28, 1, 38, 28,
|
||||
24, 20, 32, 5, 25, 28, 0, 0, 0,
|
||||
8, 147, 28, 1, 141, 28, 0, 0, 0, /* version 50 */
|
||||
10, 73, 32, 4, 74, 30, 1, 73, 30,
|
||||
16, 36, 32, 6, 39, 30, 1, 37, 30,
|
||||
27, 21, 32, 3, 20, 26, 0, 0, 0,
|
||||
9, 137, 26, 1, 135, 26, 0, 0, 0, /* version 51 */
|
||||
12, 70, 30, 4, 75, 32, 0, 0, 0,
|
||||
24, 35, 30, 1, 40, 28, 0, 0, 0,
|
||||
23, 20, 32, 8, 24, 30, 0, 0, 0,
|
||||
14, 95, 18, 1, 86, 18, 0, 0, 0, /* version 52 */
|
||||
13, 73, 32, 3, 77, 30, 0, 0, 0,
|
||||
24, 35, 30, 2, 35, 28, 0, 0, 0,
|
||||
26, 21, 32, 5, 21, 30, 1, 23, 30,
|
||||
9, 147, 28, 1, 142, 28, 0, 0, 0, /* version 53 */
|
||||
10, 73, 30, 6, 70, 32, 1, 71, 32,
|
||||
25, 35, 30, 2, 34, 26, 0, 0, 0,
|
||||
29, 21, 32, 4, 22, 30, 0, 0, 0,
|
||||
11, 126, 24, 1, 131, 24, 0, 0, 0, /* version 54 */
|
||||
16, 74, 32, 1, 79, 30, 0, 0, 0,
|
||||
25, 38, 32, 1, 25, 30, 0, 0, 0,
|
||||
33, 21, 32, 1, 28, 28, 0, 0, 0,
|
||||
14, 105, 20, 1, 99, 18, 0, 0, 0, /* version 55 */
|
||||
19, 65, 28, 1, 72, 28, 0, 0, 0,
|
||||
24, 37, 32, 2, 40, 30, 1, 41, 30,
|
||||
31, 21, 32, 4, 24, 32, 0, 0, 0,
|
||||
10, 147, 28, 1, 151, 28, 0, 0, 0, /* version 56 */
|
||||
15, 71, 30, 3, 71, 32, 1, 73, 32,
|
||||
24, 37, 32, 3, 38, 30, 1, 39, 30,
|
||||
36, 19, 30, 3, 29, 26, 0, 0, 0,
|
||||
15, 105, 20, 1, 99, 18, 0, 0, 0, /* version 57 */
|
||||
19, 70, 30, 1, 64, 28, 0, 0, 0,
|
||||
27, 38, 32, 2, 25, 26, 0, 0, 0,
|
||||
38, 20, 30, 2, 18, 28, 0, 0, 0,
|
||||
14, 105, 20, 1, 113, 22, 1, 114, 22, /* version 58 */
|
||||
17, 67, 30, 3, 92, 32, 0, 0, 0,
|
||||
30, 35, 30, 1, 41, 30, 0, 0, 0,
|
||||
36, 21, 32, 1, 26, 30, 1, 27, 30,
|
||||
11, 146, 28, 1, 146, 26, 0, 0, 0, /* version 59 */
|
||||
20, 70, 30, 1, 60, 26, 0, 0, 0,
|
||||
29, 38, 32, 1, 24, 32, 0, 0, 0,
|
||||
40, 20, 30, 2, 17, 26, 0, 0, 0,
|
||||
3, 137, 26, 1, 136, 26, 10, 126, 24, /* version 60 */
|
||||
22, 65, 28, 1, 75, 30, 0, 0, 0,
|
||||
30, 37, 32, 1, 51, 30, 0, 0, 0,
|
||||
42, 20, 30, 1, 21, 30, 0, 0, 0,
|
||||
12, 126, 24, 2, 118, 22, 1, 116, 22, /* version 61 */
|
||||
19, 74, 32, 1, 74, 30, 1, 72, 28,
|
||||
30, 38, 32, 2, 29, 30, 0, 0, 0,
|
||||
39, 20, 32, 2, 37, 26, 1, 38, 26,
|
||||
12, 126, 24, 3, 136, 26, 0, 0, 0, /* version 62 */
|
||||
21, 70, 30, 2, 65, 28, 0, 0, 0,
|
||||
34, 35, 30, 1, 44, 32, 0, 0, 0,
|
||||
42, 20, 30, 2, 19, 28, 2, 18, 28,
|
||||
12, 126, 24, 3, 117, 22, 1, 116, 22, /* version 63 */
|
||||
25, 61, 26, 2, 62, 28, 0, 0, 0,
|
||||
34, 35, 30, 1, 40, 32, 1, 41, 32,
|
||||
45, 20, 30, 1, 20, 32, 1, 21, 32,
|
||||
15, 105, 20, 2, 115, 22, 2, 116, 22, /* version 64 */
|
||||
25, 65, 28, 1, 72, 28, 0, 0, 0,
|
||||
18, 35, 30, 17, 37, 32, 1, 50, 32,
|
||||
42, 20, 30, 6, 19, 28, 1, 15, 28,
|
||||
19, 105, 20, 1, 101, 20, 0, 0, 0, /* version 65 */
|
||||
33, 51, 22, 1, 65, 22, 0, 0, 0,
|
||||
40, 33, 28, 1, 28, 28, 0, 0, 0,
|
||||
49, 20, 30, 1, 18, 28, 0, 0, 0,
|
||||
18, 105, 20, 2, 117, 22, 0, 0, 0, /* version 66 */
|
||||
26, 65, 28, 1, 80, 30, 0, 0, 0,
|
||||
35, 35, 30, 3, 35, 28, 1, 36, 28,
|
||||
52, 18, 28, 2, 38, 30, 0, 0, 0,
|
||||
26, 84, 16, 0, 0, 0, 0, 0, 0, /* version 67 */
|
||||
26, 70, 30, 0, 0, 0, 0, 0, 0,
|
||||
45, 31, 26, 1, 9, 26, 0, 0, 0,
|
||||
52, 20, 30, 0, 0, 0, 0, 0, 0,
|
||||
16, 126, 24, 1, 114, 22, 1, 115, 22, /* version 68 */
|
||||
23, 70, 30, 3, 65, 28, 1, 66, 28,
|
||||
40, 35, 30, 1, 43, 30, 0, 0, 0,
|
||||
46, 20, 30, 7, 19, 28, 1, 16, 28,
|
||||
19, 116, 22, 1, 105, 22, 0, 0, 0, /* version 69 */
|
||||
20, 70, 30, 7, 66, 28, 1, 63, 28,
|
||||
40, 35, 30, 1, 42, 32, 1, 43, 32,
|
||||
54, 20, 30, 1, 19, 30, 0, 0, 0,
|
||||
17, 126, 24, 2, 115, 22, 0, 0, 0, /* version 70 */
|
||||
24, 70, 30, 4, 74, 32, 0, 0, 0,
|
||||
48, 31, 26, 2, 18, 26, 0, 0, 0,
|
||||
54, 19, 28, 6, 15, 26, 1, 14, 26,
|
||||
29, 84, 16, 0, 0, 0, 0, 0, 0, /* version 71 */
|
||||
29, 70, 30, 0, 0, 0, 0, 0, 0,
|
||||
6, 34, 30, 3, 36, 30, 38, 33, 28,
|
||||
58, 20, 30, 0, 0, 0, 0, 0, 0,
|
||||
16, 147, 28, 1, 149, 28, 0, 0, 0, /* version 72 */
|
||||
31, 66, 28, 1, 37, 26, 0, 0, 0,
|
||||
48, 33, 28, 1, 23, 26, 0, 0, 0,
|
||||
53, 20, 30, 6, 19, 28, 1, 17, 28,
|
||||
20, 115, 22, 2, 134, 24, 0, 0, 0, /* verdion 73 */
|
||||
29, 66, 28, 2, 56, 26, 2, 57, 26,
|
||||
45, 36, 30, 2, 15, 28, 0, 0, 0,
|
||||
59, 20, 30, 2, 21, 32, 0, 0, 0,
|
||||
17, 147, 28, 1, 134, 26, 0, 0, 0, /* version 74 */
|
||||
26, 70, 30, 5, 75, 32, 0, 0, 0,
|
||||
47, 35, 30, 1, 48, 32, 0, 0, 0,
|
||||
64, 18, 28, 2, 33, 30, 1, 35, 30,
|
||||
22, 115, 22, 1, 133, 24, 0, 0, 0, /* version 75 */
|
||||
33, 65, 28, 1, 74, 28, 0, 0, 0,
|
||||
43, 36, 30, 5, 27, 28, 1, 30, 28,
|
||||
57, 20, 30, 5, 21, 32, 1, 24, 32,
|
||||
18, 136, 26, 2, 142, 26, 0, 0, 0, /* version 76 */
|
||||
33, 66, 28, 2, 49, 26, 0, 0, 0,
|
||||
48, 35, 30, 2, 38, 28, 0, 0, 0,
|
||||
64, 20, 30, 1, 20, 32, 0, 0, 0,
|
||||
19, 126, 24, 2, 135, 26, 1, 136, 26, /* version 77 */
|
||||
32, 66, 28, 2, 55, 26, 2, 56, 26,
|
||||
49, 36, 30, 2, 18, 32, 0, 0, 0,
|
||||
65, 18, 28, 5, 27, 30, 1, 29, 30,
|
||||
20, 137, 26, 1, 130, 26, 0, 0, 0, /* version 78 */
|
||||
30, 75, 32, 2, 71, 32, 0, 0, 0,
|
||||
46, 35, 30, 6, 39, 32, 0, 0, 0,
|
||||
3, 12, 30, 70, 19, 28, 0, 0, 0,
|
||||
20, 147, 28, 0, 0, 0, 0, 0, 0, /* version 79 */
|
||||
35, 70, 30, 0, 0, 0, 0, 0, 0,
|
||||
49, 35, 30, 5, 35, 28, 0, 0, 0,
|
||||
70, 20, 30, 0, 0, 0, 0, 0, 0,
|
||||
21, 136, 26, 1, 155, 28, 0, 0, 0, /* version 80 */
|
||||
34, 70, 30, 1, 64, 28, 1, 65, 28,
|
||||
54, 35, 30, 1, 45, 30, 0, 0, 0,
|
||||
68, 20, 30, 3, 18, 28, 1, 19, 28,
|
||||
19, 126, 24, 5, 115, 22, 1, 114, 22, /* version 81 */
|
||||
33, 70, 30, 3, 65, 28, 1, 64, 28,
|
||||
52, 35, 30, 3, 41, 32, 1, 40, 32,
|
||||
67, 20, 30, 5, 21, 32, 1, 24, 32,
|
||||
2, 150, 28, 21, 136, 26, 0, 0, 0, /* version 82 */
|
||||
32, 70, 30, 6, 65, 28, 0, 0, 0,
|
||||
52, 38, 32, 2, 27, 32, 0, 0, 0,
|
||||
73, 20, 30, 2, 22, 32, 0, 0, 0,
|
||||
21, 126, 24, 4, 136, 26, 0, 0, 0, /* version 83 */
|
||||
30, 74, 32, 6, 73, 30, 0, 0, 0,
|
||||
54, 35, 30, 4, 40, 32, 0, 0, 0,
|
||||
75, 20, 30, 1, 20, 28, 0, 0, 0,
|
||||
30, 105, 20, 1, 114, 22, 0, 0, 0, /* version 84 */
|
||||
3, 45, 22, 55, 47, 20, 0, 0, 0,
|
||||
2, 26, 26, 62, 33, 28, 0, 0, 0,
|
||||
79, 18, 28, 4, 33, 30, 0, 0, 0
|
||||
/* #blocks, k, 2t, #blocks, k, 2t, #blocks, k, 2t */
|
||||
1, 21, 4, 0, 0, 0, 0, 0, 0, /* version 1 */
|
||||
1, 17, 8, 0, 0, 0, 0, 0, 0,
|
||||
1, 13, 12, 0, 0, 0, 0, 0, 0,
|
||||
1, 9, 16, 0, 0, 0, 0, 0, 0,
|
||||
1, 31, 6, 0, 0, 0, 0, 0, 0, /* version 2 */
|
||||
1, 25, 12, 0, 0, 0, 0, 0, 0,
|
||||
1, 19, 18, 0, 0, 0, 0, 0, 0,
|
||||
1, 15, 22, 0, 0, 0, 0, 0, 0,
|
||||
1, 42, 8, 0, 0, 0, 0, 0, 0, /* version 3 */
|
||||
1, 34, 16, 0, 0, 0, 0, 0, 0,
|
||||
1, 26, 24, 0, 0, 0, 0, 0, 0,
|
||||
1, 20, 30, 0, 0, 0, 0, 0, 0,
|
||||
1, 46, 8, 0, 0, 0, 0, 0, 0, /* version 4 */
|
||||
1, 38, 16, 0, 0, 0, 0, 0, 0,
|
||||
1, 30, 24, 0, 0, 0, 0, 0, 0,
|
||||
1, 22, 32, 0, 0, 0, 0, 0, 0,
|
||||
1, 57, 12, 0, 0, 0, 0, 0, 0, /* version 5 */
|
||||
1, 49, 20, 0, 0, 0, 0, 0, 0,
|
||||
1, 37, 32, 0, 0, 0, 0, 0, 0,
|
||||
1, 14, 20, 1, 13, 22, 0, 0, 0,
|
||||
1, 70, 14, 0, 0, 0, 0, 0, 0, /* version 6 */
|
||||
1, 58, 26, 0, 0, 0, 0, 0, 0,
|
||||
1, 24, 20, 1, 22, 18, 0, 0, 0,
|
||||
1, 16, 24, 1, 18, 26, 0, 0, 0,
|
||||
1, 84, 16, 0, 0, 0, 0, 0, 0, /* version 7 */
|
||||
1, 70, 30, 0, 0, 0, 0, 0, 0,
|
||||
1, 26, 22, 1, 28, 24, 0, 0, 0,
|
||||
2, 14, 20, 1, 12, 20, 0, 0, 0,
|
||||
1, 99, 18, 0, 0, 0, 0, 0, 0, /* version 8 */
|
||||
1, 40, 18, 1, 41, 18, 0, 0, 0,
|
||||
1, 31, 26, 1, 32, 28, 0, 0, 0,
|
||||
2, 16, 24, 1, 15, 22, 0, 0, 0,
|
||||
1, 114, 22, 0, 0, 0, 0, 0, 0, /* version 9 */
|
||||
2, 48, 20, 0, 0, 0, 0, 0, 0,
|
||||
2, 24, 20, 1, 26, 22, 0, 0, 0,
|
||||
2, 18, 28, 1, 18, 26, 0, 0, 0,
|
||||
1, 131, 24, 0, 0, 0, 0, 0, 0, /* version 10 */
|
||||
1, 52, 22, 1, 57, 24, 0, 0, 0,
|
||||
2, 27, 24, 1, 29, 24, 0, 0, 0,
|
||||
2, 21, 32, 1, 19, 30, 0, 0, 0,
|
||||
1, 135, 26, 0, 0, 0, 0, 0, 0, /* version 11 */
|
||||
1, 56, 24, 1, 57, 24, 0, 0, 0,
|
||||
2, 28, 24, 1, 31, 26, 0, 0, 0,
|
||||
2, 22, 32, 1, 21, 32, 0, 0, 0,
|
||||
1, 153, 28, 0, 0, 0, 0, 0, 0, /* version 12 */
|
||||
1, 62, 26, 1, 65, 28, 0, 0, 0,
|
||||
2, 32, 28, 1, 33, 28, 0, 0, 0,
|
||||
3, 17, 26, 1, 22, 30, 0, 0, 0,
|
||||
1, 86, 16, 1, 85, 16, 0, 0, 0, /* version 13 */
|
||||
1, 71, 30, 1, 72, 30, 0, 0, 0,
|
||||
2, 37, 32, 1, 35, 30, 0, 0, 0,
|
||||
3, 20, 30, 1, 21, 32, 0, 0, 0,
|
||||
1, 94, 18, 1, 95, 18, 0, 0, 0, /* version 14 */
|
||||
2, 51, 22, 1, 55, 24, 0, 0, 0,
|
||||
3, 30, 26, 1, 31, 26, 0, 0, 0,
|
||||
4, 18, 28, 1, 17, 24, 0, 0, 0,
|
||||
1, 104, 20, 1, 105, 20, 0, 0, 0, /* version 15 */
|
||||
2, 57, 24, 1, 61, 26, 0, 0, 0,
|
||||
3, 33, 28, 1, 36, 30, 0, 0, 0,
|
||||
4, 20, 30, 1, 19, 30, 0, 0, 0,
|
||||
1, 115, 22, 1, 114, 22, 0, 0, 0, /* version 16 */
|
||||
2, 65, 28, 1, 61, 26, 0, 0, 0,
|
||||
3, 38, 32, 1, 33, 30, 0, 0, 0,
|
||||
5, 19, 28, 1, 14, 24, 0, 0, 0,
|
||||
1, 126, 24, 1, 125, 24, 0, 0, 0, /* version 17 */
|
||||
2, 70, 30, 1, 69, 30, 0, 0, 0,
|
||||
4, 33, 28, 1, 29, 26, 0, 0, 0,
|
||||
5, 20, 30, 1, 19, 30, 0, 0, 0,
|
||||
1, 136, 26, 1, 137, 26, 0, 0, 0, /* version 18 */
|
||||
3, 56, 24, 1, 59, 26, 0, 0, 0,
|
||||
5, 35, 30, 0, 0, 0, 0, 0, 0,
|
||||
6, 18, 28, 1, 21, 28, 0, 0, 0,
|
||||
1, 148, 28, 1, 149, 28, 0, 0, 0, /* version 19 */
|
||||
3, 61, 26, 1, 64, 28, 0, 0, 0,
|
||||
7, 24, 20, 1, 23, 22, 0, 0, 0,
|
||||
6, 20, 30, 1, 21, 32, 0, 0, 0,
|
||||
3, 107, 20, 0, 0, 0, 0, 0, 0, /* version 20 */
|
||||
3, 65, 28, 1, 72, 30, 0, 0, 0,
|
||||
7, 26, 22, 1, 23, 22, 0, 0, 0,
|
||||
7, 19, 28, 1, 20, 32, 0, 0, 0,
|
||||
3, 115, 22, 0, 0, 0, 0, 0, 0, /* version 21 */
|
||||
4, 56, 24, 1, 63, 28, 0, 0, 0,
|
||||
7, 28, 24, 1, 25, 22, 0, 0, 0,
|
||||
8, 18, 28, 1, 21, 22, 0, 0, 0,
|
||||
2, 116, 22, 1, 122, 24, 0, 0, 0, /* version 22 */
|
||||
4, 56, 24, 1, 72, 30, 0, 0, 0,
|
||||
7, 28, 24, 1, 32, 26, 0, 0, 0,
|
||||
8, 18, 28, 1, 24, 30, 0, 0, 0,
|
||||
3, 127, 24, 0, 0, 0, 0, 0, 0, /* version 23 */
|
||||
5, 51, 22, 1, 62, 26, 0, 0, 0,
|
||||
7, 30, 26, 1, 35, 26, 0, 0, 0,
|
||||
8, 20, 30, 1, 21, 32, 0, 0, 0,
|
||||
2, 135, 26, 1, 137, 26, 0, 0, 0, /* version 24 */
|
||||
5, 56, 24, 1, 59, 26, 0, 0, 0,
|
||||
7, 33, 28, 1, 30, 28, 0, 0, 0,
|
||||
11, 16, 24, 1, 19, 26, 0, 0, 0,
|
||||
3, 105, 20, 1, 121, 22, 0, 0, 0, /* version 25 */
|
||||
5, 61, 26, 1, 57, 26, 0, 0, 0,
|
||||
9, 28, 24, 1, 28, 22, 0, 0, 0,
|
||||
10, 19, 28, 1, 18, 30, 0, 0, 0,
|
||||
2, 157, 30, 1, 150, 28, 0, 0, 0, /* version 26 */
|
||||
5, 65, 28, 1, 61, 26, 0, 0, 0,
|
||||
8, 33, 28, 1, 34, 30, 0, 0, 0,
|
||||
10, 19, 28, 2, 15, 26, 0, 0, 0,
|
||||
3, 126, 24, 1, 115, 22, 0, 0, 0, /* version 27 */
|
||||
7, 51, 22, 1, 54, 22, 0, 0, 0,
|
||||
8, 35, 30, 1, 37, 30, 0, 0, 0,
|
||||
15, 15, 22, 1, 10, 22, 0, 0, 0,
|
||||
4, 105, 20, 1, 103, 20, 0, 0, 0, /* version 28 */
|
||||
7, 56, 24, 1, 45, 18, 0, 0, 0,
|
||||
10, 31, 26, 1, 27, 26, 0, 0, 0,
|
||||
10, 17, 26, 3, 20, 28, 1, 21, 28,
|
||||
3, 139, 26, 1, 137, 28, 0, 0, 0, /* version 29 */
|
||||
6, 66, 28, 1, 66, 30, 0, 0, 0,
|
||||
9, 36, 30, 1, 34, 32, 0, 0, 0,
|
||||
13, 19, 28, 1, 17, 32, 0, 0, 0,
|
||||
6, 84, 16, 1, 82, 16, 0, 0, 0, /* version 30 */
|
||||
6, 70, 30, 1, 68, 30, 0, 0, 0,
|
||||
7, 35, 30, 3, 33, 28, 1, 32, 28,
|
||||
13, 20, 30, 1, 20, 28, 0, 0, 0,
|
||||
5, 105, 20, 1, 94, 18, 0, 0, 0, /* version 31 */
|
||||
6, 74, 32, 1, 71, 30, 0, 0, 0,
|
||||
11, 33, 28, 1, 34, 32, 0, 0, 0,
|
||||
13, 19, 28, 3, 16, 26, 0, 0, 0,
|
||||
4, 127, 24, 1, 126, 24, 0, 0, 0, /* version 32 */
|
||||
7, 66, 28, 1, 66, 30, 0, 0, 0,
|
||||
12, 30, 24, 1, 24, 28, 1, 24, 30,
|
||||
15, 19, 28, 1, 17, 32, 0, 0, 0,
|
||||
7, 84, 16, 1, 78, 16, 0, 0, 0, /* version 33 */
|
||||
7, 70, 30, 1, 66, 28, 0, 0, 0,
|
||||
12, 33, 28, 1, 32, 30, 0, 0, 0,
|
||||
14, 21, 32, 1, 24, 28, 0, 0, 0,
|
||||
5, 117, 22, 1, 117, 24, 0, 0, 0, /* version 34 */
|
||||
8, 66, 28, 1, 58, 26, 0, 0, 0,
|
||||
11, 38, 32, 1, 34, 32, 0, 0, 0,
|
||||
15, 20, 30, 2, 17, 26, 0, 0, 0,
|
||||
4, 148, 28, 1, 146, 28, 0, 0, 0, /* version 35 */
|
||||
8, 68, 30, 1, 70, 24, 0, 0, 0,
|
||||
10, 36, 32, 3, 38, 28, 0, 0, 0,
|
||||
16, 19, 28, 3, 16, 26, 0, 0, 0,
|
||||
4, 126, 24, 2, 135, 26, 0, 0, 0, /* version 36 */
|
||||
8, 70, 28, 2, 43, 26, 0, 0, 0,
|
||||
13, 32, 28, 2, 41, 30, 0, 0, 0,
|
||||
17, 19, 28, 3, 15, 26, 0, 0, 0,
|
||||
5, 136, 26, 1, 132, 24, 0, 0, 0, /* version 37 */
|
||||
5, 67, 30, 4, 68, 28, 1, 69, 28,
|
||||
14, 35, 30, 1, 32, 24, 0, 0, 0,
|
||||
18, 18, 26, 3, 16, 28, 1, 14, 28,
|
||||
3, 142, 26, 3, 141, 28, 0, 0, 0, /* version 38 */
|
||||
8, 70, 30, 1, 73, 32, 1, 74, 32,
|
||||
12, 34, 30, 3, 34, 26, 1, 35, 28,
|
||||
18, 21, 32, 1, 27, 30, 0, 0, 0,
|
||||
5, 116, 22, 2, 103, 20, 1, 102, 20, /* version 39 */
|
||||
9, 74, 32, 1, 74, 30, 0, 0, 0,
|
||||
14, 34, 28, 2, 32, 32, 1, 32, 30,
|
||||
19, 21, 32, 1, 25, 26, 0, 0, 0,
|
||||
7, 116, 22, 1, 117, 22, 0, 0, 0, /* version 40 */
|
||||
11, 65, 28, 1, 58, 24, 0, 0, 0,
|
||||
15, 38, 32, 1, 27, 28, 0, 0, 0,
|
||||
20, 20, 30, 1, 20, 32, 1, 21, 32,
|
||||
6, 136, 26, 1, 130, 24, 0, 0, 0, /* version 41 */
|
||||
11, 66, 28, 1, 62, 30, 0, 0, 0,
|
||||
14, 34, 28, 3, 34, 32, 1, 30, 30,
|
||||
18, 20, 30, 3, 20, 28, 2, 15, 26,
|
||||
5, 105, 20, 2, 115, 22, 2, 116, 22, /* version 42 */
|
||||
10, 75, 32, 1, 73, 32, 0, 0, 0,
|
||||
16, 38, 32, 1, 27, 28, 0, 0, 0,
|
||||
22, 19, 28, 2, 16, 30, 1, 19, 30,
|
||||
6, 147, 28, 1, 146, 28, 0, 0, 0, /* version 43 */
|
||||
11, 66, 28, 2, 65, 30, 0, 0, 0,
|
||||
18, 33, 28, 2, 33, 30, 0, 0, 0,
|
||||
22, 21, 32, 1, 28, 30, 0, 0, 0,
|
||||
6, 116, 22, 3, 125, 24, 0, 0, 0, /* version 44 */
|
||||
11, 75, 32, 1, 68, 30, 0, 0, 0,
|
||||
13, 35, 28, 6, 34, 32, 1, 30, 30,
|
||||
23, 21, 32, 1, 26, 30, 0, 0, 0,
|
||||
7, 105, 20, 4, 95, 18, 0, 0, 0, /* version 45 */
|
||||
12, 67, 28, 1, 63, 30, 1, 62, 32,
|
||||
21, 31, 26, 2, 33, 32, 0, 0, 0,
|
||||
23, 21, 32, 2, 24, 30, 0, 0, 0,
|
||||
10, 116, 22, 0, 0, 0, 0, 0, 0, /* version 46 */
|
||||
12, 74, 32, 1, 78, 30, 0, 0, 0,
|
||||
18, 37, 32, 1, 39, 30, 1, 41, 28,
|
||||
25, 21, 32, 1, 27, 28, 0, 0, 0,
|
||||
5, 126, 24, 4, 115, 22, 1, 114, 22, /* version 47 */
|
||||
12, 67, 28, 2, 66, 32, 1, 68, 30,
|
||||
21, 35, 30, 1, 39, 30, 0, 0, 0,
|
||||
26, 21, 32, 1, 28, 28, 0, 0, 0,
|
||||
9, 126, 24, 1, 117, 22, 0, 0, 0, /* version 48 */
|
||||
13, 75, 32, 1, 68, 30, 0, 0, 0,
|
||||
20, 35, 30, 3, 35, 28, 0, 0, 0,
|
||||
27, 21, 32, 1, 28, 30, 0, 0, 0,
|
||||
9, 126, 24, 1, 137, 26, 0, 0, 0, /* version 49 */
|
||||
13, 71, 30, 2, 68, 32, 0, 0, 0,
|
||||
20, 37, 32, 1, 39, 28, 1, 38, 28,
|
||||
24, 20, 32, 5, 25, 28, 0, 0, 0,
|
||||
8, 147, 28, 1, 141, 28, 0, 0, 0, /* version 50 */
|
||||
10, 73, 32, 4, 74, 30, 1, 73, 30,
|
||||
16, 36, 32, 6, 39, 30, 1, 37, 30,
|
||||
27, 21, 32, 3, 20, 26, 0, 0, 0,
|
||||
9, 137, 26, 1, 135, 26, 0, 0, 0, /* version 51 */
|
||||
12, 70, 30, 4, 75, 32, 0, 0, 0,
|
||||
24, 35, 30, 1, 40, 28, 0, 0, 0,
|
||||
23, 20, 32, 8, 24, 30, 0, 0, 0,
|
||||
14, 95, 18, 1, 86, 18, 0, 0, 0, /* version 52 */
|
||||
13, 73, 32, 3, 77, 30, 0, 0, 0,
|
||||
24, 35, 30, 2, 35, 28, 0, 0, 0,
|
||||
26, 21, 32, 5, 21, 30, 1, 23, 30,
|
||||
9, 147, 28, 1, 142, 28, 0, 0, 0, /* version 53 */
|
||||
10, 73, 30, 6, 70, 32, 1, 71, 32,
|
||||
25, 35, 30, 2, 34, 26, 0, 0, 0,
|
||||
29, 21, 32, 4, 22, 30, 0, 0, 0,
|
||||
11, 126, 24, 1, 131, 24, 0, 0, 0, /* version 54 */
|
||||
16, 74, 32, 1, 79, 30, 0, 0, 0,
|
||||
25, 38, 32, 1, 25, 30, 0, 0, 0,
|
||||
33, 21, 32, 1, 28, 28, 0, 0, 0,
|
||||
14, 105, 20, 1, 99, 18, 0, 0, 0, /* version 55 */
|
||||
19, 65, 28, 1, 72, 28, 0, 0, 0,
|
||||
24, 37, 32, 2, 40, 30, 1, 41, 30,
|
||||
31, 21, 32, 4, 24, 32, 0, 0, 0,
|
||||
10, 147, 28, 1, 151, 28, 0, 0, 0, /* version 56 */
|
||||
15, 71, 30, 3, 71, 32, 1, 73, 32,
|
||||
24, 37, 32, 3, 38, 30, 1, 39, 30,
|
||||
36, 19, 30, 3, 29, 26, 0, 0, 0,
|
||||
15, 105, 20, 1, 99, 18, 0, 0, 0, /* version 57 */
|
||||
19, 70, 30, 1, 64, 28, 0, 0, 0,
|
||||
27, 38, 32, 2, 25, 26, 0, 0, 0,
|
||||
38, 20, 30, 2, 18, 28, 0, 0, 0,
|
||||
14, 105, 20, 1, 113, 22, 1, 114, 22, /* version 58 */
|
||||
17, 67, 30, 3, 92, 32, 0, 0, 0,
|
||||
30, 35, 30, 1, 41, 30, 0, 0, 0,
|
||||
36, 21, 32, 1, 26, 30, 1, 27, 30,
|
||||
11, 146, 28, 1, 146, 26, 0, 0, 0, /* version 59 */
|
||||
20, 70, 30, 1, 60, 26, 0, 0, 0,
|
||||
29, 38, 32, 1, 24, 32, 0, 0, 0,
|
||||
40, 20, 30, 2, 17, 26, 0, 0, 0,
|
||||
3, 137, 26, 1, 136, 26, 10, 126, 24, /* version 60 */
|
||||
22, 65, 28, 1, 75, 30, 0, 0, 0,
|
||||
30, 37, 32, 1, 51, 30, 0, 0, 0,
|
||||
42, 20, 30, 1, 21, 30, 0, 0, 0,
|
||||
12, 126, 24, 2, 118, 22, 1, 116, 22, /* version 61 */
|
||||
19, 74, 32, 1, 74, 30, 1, 72, 28,
|
||||
30, 38, 32, 2, 29, 30, 0, 0, 0,
|
||||
39, 20, 32, 2, 37, 26, 1, 38, 26,
|
||||
12, 126, 24, 3, 136, 26, 0, 0, 0, /* version 62 */
|
||||
21, 70, 30, 2, 65, 28, 0, 0, 0,
|
||||
34, 35, 30, 1, 44, 32, 0, 0, 0,
|
||||
42, 20, 30, 2, 19, 28, 2, 18, 28,
|
||||
12, 126, 24, 3, 117, 22, 1, 116, 22, /* version 63 */
|
||||
25, 61, 26, 2, 62, 28, 0, 0, 0,
|
||||
34, 35, 30, 1, 40, 32, 1, 41, 32,
|
||||
45, 20, 30, 1, 20, 32, 1, 21, 32,
|
||||
15, 105, 20, 2, 115, 22, 2, 116, 22, /* version 64 */
|
||||
25, 65, 28, 1, 72, 28, 0, 0, 0,
|
||||
18, 35, 30, 17, 37, 32, 1, 50, 32,
|
||||
42, 20, 30, 6, 19, 28, 1, 15, 28,
|
||||
19, 105, 20, 1, 101, 20, 0, 0, 0, /* version 65 */
|
||||
33, 51, 22, 1, 65, 22, 0, 0, 0,
|
||||
40, 33, 28, 1, 28, 28, 0, 0, 0,
|
||||
49, 20, 30, 1, 18, 28, 0, 0, 0,
|
||||
18, 105, 20, 2, 117, 22, 0, 0, 0, /* version 66 */
|
||||
26, 65, 28, 1, 80, 30, 0, 0, 0,
|
||||
35, 35, 30, 3, 35, 28, 1, 36, 28,
|
||||
52, 18, 28, 2, 38, 30, 0, 0, 0,
|
||||
26, 84, 16, 0, 0, 0, 0, 0, 0, /* version 67 */
|
||||
26, 70, 30, 0, 0, 0, 0, 0, 0,
|
||||
45, 31, 26, 1, 9, 26, 0, 0, 0,
|
||||
52, 20, 30, 0, 0, 0, 0, 0, 0,
|
||||
16, 126, 24, 1, 114, 22, 1, 115, 22, /* version 68 */
|
||||
23, 70, 30, 3, 65, 28, 1, 66, 28,
|
||||
40, 35, 30, 1, 43, 30, 0, 0, 0,
|
||||
46, 20, 30, 7, 19, 28, 1, 16, 28,
|
||||
19, 116, 22, 1, 105, 22, 0, 0, 0, /* version 69 */
|
||||
20, 70, 30, 7, 66, 28, 1, 63, 28,
|
||||
40, 35, 30, 1, 42, 32, 1, 43, 32,
|
||||
54, 20, 30, 1, 19, 30, 0, 0, 0,
|
||||
17, 126, 24, 2, 115, 22, 0, 0, 0, /* version 70 */
|
||||
24, 70, 30, 4, 74, 32, 0, 0, 0,
|
||||
48, 31, 26, 2, 18, 26, 0, 0, 0,
|
||||
54, 19, 28, 6, 15, 26, 1, 14, 26,
|
||||
29, 84, 16, 0, 0, 0, 0, 0, 0, /* version 71 */
|
||||
29, 70, 30, 0, 0, 0, 0, 0, 0,
|
||||
6, 34, 30, 3, 36, 30, 38, 33, 28,
|
||||
58, 20, 30, 0, 0, 0, 0, 0, 0,
|
||||
16, 147, 28, 1, 149, 28, 0, 0, 0, /* version 72 */
|
||||
31, 66, 28, 1, 37, 26, 0, 0, 0,
|
||||
48, 33, 28, 1, 23, 26, 0, 0, 0,
|
||||
53, 20, 30, 6, 19, 28, 1, 17, 28,
|
||||
20, 115, 22, 2, 134, 24, 0, 0, 0, /* version 73 */
|
||||
29, 66, 28, 2, 56, 26, 2, 57, 26,
|
||||
45, 36, 30, 2, 15, 28, 0, 0, 0,
|
||||
59, 20, 30, 2, 21, 32, 0, 0, 0,
|
||||
17, 147, 28, 1, 134, 26, 0, 0, 0, /* version 74 */
|
||||
26, 70, 30, 5, 75, 32, 0, 0, 0,
|
||||
47, 35, 30, 1, 48, 32, 0, 0, 0,
|
||||
64, 18, 28, 2, 33, 30, 1, 35, 30,
|
||||
22, 115, 22, 1, 133, 24, 0, 0, 0, /* version 75 */
|
||||
33, 65, 28, 1, 74, 28, 0, 0, 0,
|
||||
43, 36, 30, 5, 27, 28, 1, 30, 28,
|
||||
57, 20, 30, 5, 21, 32, 1, 24, 32,
|
||||
18, 136, 26, 2, 142, 26, 0, 0, 0, /* version 76 */
|
||||
33, 66, 28, 2, 49, 26, 0, 0, 0,
|
||||
48, 35, 30, 2, 38, 28, 0, 0, 0,
|
||||
64, 20, 30, 1, 20, 32, 0, 0, 0,
|
||||
19, 126, 24, 2, 135, 26, 1, 136, 26, /* version 77 */
|
||||
32, 66, 28, 2, 55, 26, 2, 56, 26,
|
||||
49, 36, 30, 2, 18, 32, 0, 0, 0,
|
||||
65, 18, 28, 5, 27, 30, 1, 29, 30,
|
||||
20, 137, 26, 1, 130, 26, 0, 0, 0, /* version 78 */
|
||||
30, 75, 32, 2, 71, 32, 0, 0, 0,
|
||||
46, 35, 30, 6, 39, 32, 0, 0, 0,
|
||||
3, 12, 30, 70, 19, 28, 0, 0, 0,
|
||||
20, 147, 28, 0, 0, 0, 0, 0, 0, /* version 79 */
|
||||
35, 70, 30, 0, 0, 0, 0, 0, 0,
|
||||
49, 35, 30, 5, 35, 28, 0, 0, 0,
|
||||
70, 20, 30, 0, 0, 0, 0, 0, 0,
|
||||
21, 136, 26, 1, 155, 28, 0, 0, 0, /* version 80 */
|
||||
34, 70, 30, 1, 64, 28, 1, 65, 28,
|
||||
54, 35, 30, 1, 45, 30, 0, 0, 0,
|
||||
68, 20, 30, 3, 18, 28, 1, 19, 28,
|
||||
19, 126, 24, 5, 115, 22, 1, 114, 22, /* version 81 */
|
||||
33, 70, 30, 3, 65, 28, 1, 64, 28,
|
||||
52, 35, 30, 3, 41, 32, 1, 40, 32,
|
||||
67, 20, 30, 5, 21, 32, 1, 24, 32,
|
||||
2, 150, 28, 21, 136, 26, 0, 0, 0, /* version 82 */
|
||||
32, 70, 30, 6, 65, 28, 0, 0, 0,
|
||||
52, 38, 32, 2, 27, 32, 0, 0, 0,
|
||||
73, 20, 30, 2, 22, 32, 0, 0, 0,
|
||||
21, 126, 24, 4, 136, 26, 0, 0, 0, /* version 83 */
|
||||
30, 74, 32, 6, 73, 30, 0, 0, 0,
|
||||
54, 35, 30, 4, 40, 32, 0, 0, 0,
|
||||
75, 20, 30, 1, 20, 28, 0, 0, 0,
|
||||
30, 105, 20, 1, 114, 22, 0, 0, 0, /* version 84 */
|
||||
3, 45, 22, 55, 47, 20, 0, 0, 0,
|
||||
2, 26, 26, 62, 33, 28, 0, 0, 0,
|
||||
79, 18, 28, 4, 33, 30, 0, 0, 0
|
||||
};
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* imail.c - Handles Intelligent Mail (aka OneCode) for USPS */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -40,8 +40,8 @@
|
||||
|
||||
/* The following lookup tables were generated using the code in Appendix C */
|
||||
|
||||
/* Appendix D Table 1 - 5 of 13 characters */
|
||||
static const unsigned short AppxD_I[1287] = {
|
||||
/* Appendix D Table 1 - 5 of 13 characters */
|
||||
0x001F, 0x1F00, 0x002F, 0x1E80, 0x0037, 0x1D80, 0x003B, 0x1B80, 0x003D, 0x1780,
|
||||
0x003E, 0x0F80, 0x004F, 0x1E40, 0x0057, 0x1D40, 0x005B, 0x1B40, 0x005D, 0x1740,
|
||||
0x005E, 0x0F40, 0x0067, 0x1CC0, 0x006B, 0x1AC0, 0x006D, 0x16C0, 0x006E, 0x0EC0,
|
||||
@ -173,8 +173,8 @@ static const unsigned short AppxD_I[1287] = {
|
||||
0x08E2, 0x064C, 0x0554, 0x04E4, 0x0358, 0x02E8, 0x01F0
|
||||
};
|
||||
|
||||
/* Appendix D Table II - 2 of 13 characters */
|
||||
static const unsigned short AppxD_II[78] = {
|
||||
/* Appendix D Table II - 2 of 13 characters */
|
||||
0x0003, 0x1800, 0x0005, 0x1400, 0x0006, 0x0C00, 0x0009, 0x1200, 0x000A, 0x0A00,
|
||||
0x000C, 0x0600, 0x0011, 0x1100, 0x0012, 0x0900, 0x0014, 0x0500, 0x0018, 0x0300,
|
||||
0x0021, 0x1080, 0x0022, 0x0880, 0x0024, 0x0480, 0x0028, 0x0280, 0x0030, 0x0180,
|
||||
@ -185,14 +185,15 @@ static const unsigned short AppxD_II[78] = {
|
||||
0x0801, 0x1002, 0x1001, 0x0802, 0x0404, 0x0208, 0x0110, 0x00A0
|
||||
};
|
||||
|
||||
static const unsigned short AppxD_IV[130] = {
|
||||
/* Appendix D Table IV - Bar-to-Character Mapping (reverse lookup) */
|
||||
67, 6, 78, 16, 86, 95, 34, 40, 45, 113, 117, 121, 62, 87, 18, 104, 41, 76, 57, 119, 115, 72, 97,
|
||||
2, 127, 26, 105, 35, 122, 52, 114, 7, 24, 82, 68, 63, 94, 44, 77, 112, 70, 100, 39, 30, 107,
|
||||
15, 125, 85, 10, 65, 54, 88, 20, 106, 46, 66, 8, 116, 29, 61, 99, 80, 90, 37, 123, 51, 25, 84,
|
||||
129, 56, 4, 109, 96, 28, 36, 47, 11, 71, 33, 102, 21, 9, 17, 49, 124, 79, 64, 91, 42, 69, 53,
|
||||
60, 14, 1, 27, 103, 126, 75, 89, 50, 120, 19, 32, 110, 92, 111, 130, 59, 31, 12, 81, 43, 55,
|
||||
5, 74, 22, 101, 128, 58, 118, 48, 108, 38, 98, 93, 23, 83, 13, 73, 3
|
||||
/* Appendix D Table IV - Bar-to-Character Mapping (reverse lookup) */
|
||||
static const unsigned char AppxD_IV[130] = {
|
||||
67, 6, 78, 16, 86, 95, 34, 40, 45, 113, 117, 121, 62, 87, 18, 104, 41, 76, 57, 119,
|
||||
115, 72, 97, 2, 127, 26, 105, 35, 122, 52, 114, 7, 24, 82, 68, 63, 94, 44, 77, 112,
|
||||
70, 100, 39, 30, 107, 15, 125, 85, 10, 65, 54, 88, 20, 106, 46, 66, 8, 116, 29, 61,
|
||||
99, 80, 90, 37, 123, 51, 25, 84, 129, 56, 4, 109, 96, 28, 36, 47, 11, 71, 33, 102,
|
||||
21, 9, 17, 49, 124, 79, 64, 91, 42, 69, 53, 60, 14, 1, 27, 103, 126, 75, 89, 50,
|
||||
120, 19, 32, 110, 92, 111, 130, 59, 31, 12, 81, 43, 55, 5, 74, 22, 101, 128, 58, 118,
|
||||
48, 108, 38, 98, 93, 23, 83, 13, 73, 3
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
@ -258,12 +259,11 @@ INTERNAL int usps_imail(struct zint_symbol *symbol, unsigned char source[], int
|
||||
int zip_len, len;
|
||||
|
||||
if (length > 32) {
|
||||
strcpy(symbol->errtxt, "450: Input too long (32 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 450, "Input length %d too long (maximum 32)", length);
|
||||
}
|
||||
if (!is_sane(SODIUM_MNS_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "451: Invalid character in data (digits and \"-\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(SODIUM_MNS_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 451,
|
||||
"Invalid character at position %d in input (digits and \"-\" only)", i);
|
||||
}
|
||||
|
||||
/* separate the tracking code from the routing code */
|
||||
@ -295,18 +295,18 @@ INTERNAL int usps_imail(struct zint_symbol *symbol, unsigned char source[], int
|
||||
}
|
||||
|
||||
if (strlen(tracker) != 20) {
|
||||
strcpy(symbol->errtxt, "452: Invalid length for tracking code (20 characters required)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 452,
|
||||
"Invalid length for tracking code (20 characters required)");
|
||||
}
|
||||
if (tracker[1] > '4') {
|
||||
strcpy(symbol->errtxt, "454: Barcode Identifier (second character) out of range (0 to 4)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 454,
|
||||
"Barcode Identifier (second character) out of range (0 to 4)");
|
||||
}
|
||||
|
||||
zip_len = (int) strlen(zip);
|
||||
if (zip_len != 0 && zip_len != 5 && zip_len != 9 && zip_len != 11) {
|
||||
strcpy(symbol->errtxt, "453: Invalid length for ZIP code (5, 9 or 11 characters required)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 453,
|
||||
"Invalid length for ZIP code (5, 9 or 11 characters required)");
|
||||
}
|
||||
|
||||
/* *** Step 1 - Conversion of Data Fields into Binary Data *** */
|
||||
@ -437,10 +437,12 @@ INTERNAL int usps_imail(struct zint_symbol *symbol, unsigned char source[], int
|
||||
Tracker 0.048" (average of 0.039" - 0.057")
|
||||
Ascender/descender 0.0965" (average of 0.082" - 0.111") less T = 0.0485"
|
||||
*/
|
||||
symbol->row_height[0] = stripf(0.0485f * 43); /* 2.0855 */
|
||||
symbol->row_height[1] = stripf(0.048f * 43); /* 2.064 */
|
||||
const float min_height = 4.875f; /* 0.125 * 39 */
|
||||
const float max_height = 7.75500011f; /* 0.165 * 47 */
|
||||
symbol->row_height[0] = 2.0855f; /* 0.0485 * 43 */
|
||||
symbol->row_height[1] = 2.06399989f; /* 0.048 * 43 */
|
||||
/* Note using max X for minimum and min X for maximum */
|
||||
error_number = daft_set_height(symbol, stripf(0.125f * 39) /*4.875*/, stripf(0.165f * 47) /*7.755*/);
|
||||
error_number = daft_set_height(symbol, min_height, max_height);
|
||||
} else {
|
||||
symbol->row_height[0] = 3.0f;
|
||||
symbol->row_height[1] = 2.0f;
|
||||
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2021-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2021-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -52,7 +52,7 @@ static int iso4217_numeric(int cc) {
|
||||
0x45, 0x00, 0x00, 0x01, 0x00, 0x10, 0x11, 0x11,
|
||||
0x00, 0x11, 0x11, 0x00, 0x81, 0x00, 0x04, 0x04,
|
||||
0x04, 0x01, 0x00, 0x14, 0x00, 0x00, 0x44, 0x00,
|
||||
0x20, 0x00, 0x00, 0xA0, 0x7F, 0xB5, 0xFD, 0xFB,
|
||||
0x20, 0x00, 0x00, 0xB0, 0x7F, 0xB5, 0xFD, 0xFB,
|
||||
0xBF, 0xBF, 0x3F, 0x47, 0xA4,
|
||||
};
|
||||
int b = cc >> 3;
|
||||
|
@ -2,8 +2,8 @@
|
||||
#include <windows.h>
|
||||
#include <winver.h>
|
||||
|
||||
#define VER_FILEVERSION 2,13,0,0
|
||||
#define VER_FILEVERSION_STR "2.13.0.0\0"
|
||||
#define VER_FILEVERSION 2,13,0,9
|
||||
#define VER_FILEVERSION_STR "2.13.0.9\0"
|
||||
|
||||
#ifdef GCC_WINDRES
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
@ -30,7 +30,7 @@ BEGIN
|
||||
VALUE "FileDescription", "libzint barcode library\0"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "zint.dll\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2023 Robin Stuart & BogDan Vatra\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2024 Robin Stuart & BogDan Vatra\0"
|
||||
VALUE "OriginalFilename", "zint.dll\0"
|
||||
VALUE "ProductName", "libzint\0"
|
||||
VALUE "ProductVersion", VER_FILEVERSION_STR
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* mailmark.c - Royal Mail 4-state and 2D Mailmark barcodes */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -72,11 +72,11 @@ static const unsigned char mailmark_data_symbol_even[30] = {
|
||||
0x33, 0x35, 0x36, 0x39, 0x3A, 0x3C
|
||||
};
|
||||
|
||||
static const unsigned short mailmark_extender_group_c[22] = {
|
||||
static const unsigned char mailmark_extender_group_c[22] = {
|
||||
3, 5, 7, 11, 13, 14, 16, 17, 19, 0, 1, 2, 4, 6, 8, 9, 10, 12, 15, 18, 20, 21
|
||||
};
|
||||
|
||||
static const unsigned short mailmark_extender_group_l[26] = {
|
||||
static const unsigned char mailmark_extender_group_l[26] = {
|
||||
2, 5, 7, 8, 13, 14, 15, 16, 21, 22, 23, 0, 1, 3, 4, 6, 9, 10, 11, 12, 17, 18, 19, 20, 24, 25
|
||||
};
|
||||
|
||||
@ -194,16 +194,14 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int
|
||||
int error_number = 0;
|
||||
|
||||
if (length > 26) {
|
||||
strcpy(symbol->errtxt, "580: Input too long (26 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 580, "Input length %d too long (maximum 26)", length);
|
||||
}
|
||||
|
||||
ustrcpy(local_source, source);
|
||||
|
||||
if (length < 22) {
|
||||
if (length < 14) {
|
||||
strcpy(symbol->errtxt, "588: Input too short (14 character minimum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 588, "Input length %d too short (minimum 14)", length);
|
||||
}
|
||||
for (i = length; i <= 22; i++) {
|
||||
strcat(local_source, " ");
|
||||
@ -222,30 +220,27 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int
|
||||
printf("Producing 4-state Mailmark (%d): %s<end>\n", length, local_source);
|
||||
}
|
||||
|
||||
if (!is_sane(RUBIDIUM_F, (unsigned char *) local_source, length)) {
|
||||
strcpy(symbol->errtxt, "581: Invalid character in data (alphanumerics and space only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(RUBIDIUM_F, (unsigned char *) local_source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 581,
|
||||
"Invalid character at position %d in input (alphanumerics and space only)", i);
|
||||
}
|
||||
|
||||
/* Format is in the range 0-4 */
|
||||
format = ctoi(local_source[0]);
|
||||
if ((format < 0) || (format > 4)) {
|
||||
strcpy(symbol->errtxt, "582: Format (1st character) out of range (0 to 4)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 582, "Format (1st character) out of range (0 to 4)");
|
||||
}
|
||||
|
||||
/* Version ID is in the range 1-4 */
|
||||
version_id = ctoi(local_source[1]) - 1;
|
||||
if ((version_id < 0) || (version_id > 3)) {
|
||||
strcpy(symbol->errtxt, "583: Version ID (2nd character) out of range (1 to 4)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 583, "Version ID (2nd character) out of range (1 to 4)");
|
||||
}
|
||||
|
||||
/* Class is in the range 0-9,A-E */
|
||||
mail_class = ctoi(local_source[2]);
|
||||
if ((mail_class < 0) || (mail_class > 14)) {
|
||||
strcpy(symbol->errtxt, "584: Class (3rd character) out of range (0 to 9 and A to E)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 584, "Class (3rd character) out of range (0 to 9 and A to E)");
|
||||
}
|
||||
|
||||
/* Supply Chain ID is 2 digits for barcode C and 6 digits for barcode L */
|
||||
@ -255,8 +250,8 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int
|
||||
supply_chain_id *= 10;
|
||||
supply_chain_id += ctoi(local_source[i]);
|
||||
} else {
|
||||
sprintf(symbol->errtxt, "585: Invalid Supply Chain ID at character %d (digits only)", i);
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 585,
|
||||
"Invalid Supply Chain ID at character %d (digits only)", i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,8 +262,7 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int
|
||||
item_id *= 10;
|
||||
item_id += ctoi(local_source[i]);
|
||||
} else {
|
||||
sprintf(symbol->errtxt, "586: Invalid Item ID at character %d (digits only)", i);
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 586, "Invalid Item ID at character %d (digits only)", i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,8 +272,7 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int
|
||||
}
|
||||
postcode[9] = '\0';
|
||||
if (mailmark_verify_postcode(postcode, &postcode_type) != 0) {
|
||||
sprintf(symbol->errtxt, "587: Invalid postcode \"%s\"", postcode);
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 587, "Invalid postcode \"%s\"", postcode);
|
||||
}
|
||||
|
||||
/* Convert postcode to internal user field */
|
||||
@ -497,10 +490,12 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int
|
||||
Using recommended 1.9mm and 1.3mm heights for Ascender/Descenders and Trackers resp. as defaults
|
||||
Min height 4.22mm * 39 (max pitch) / 25.4mm ~ 6.47, max height 5.84mm * 47 (min pitch) / 25.4mm ~ 10.8
|
||||
*/
|
||||
symbol->row_height[0] = stripf((1.9f * 42.3f) / 25.4f); /* ~3.16 */
|
||||
symbol->row_height[1] = stripf((1.3f * 42.3f) / 25.4f); /* ~2.16 */
|
||||
const float min_height = 6.47952747f; /* (4.22 * 39) / 25.4 */
|
||||
const float max_height = 10.8062992f; /* (5.84 * 47) / 25.4 */
|
||||
symbol->row_height[0] = 3.16417313f; /* (1.9 * 42.3) / 25.4 */
|
||||
symbol->row_height[1] = 2.16496062f; /* (1.3 * 42.3) / 25.4 */
|
||||
/* Note using max X for minimum and min X for maximum */
|
||||
error_number = daft_set_height(symbol, stripf((4.22f * 39) / 25.4f), stripf((5.84f * 47) / 25.4f));
|
||||
error_number = daft_set_height(symbol, min_height, max_height);
|
||||
} else {
|
||||
symbol->row_height[0] = 4.0f;
|
||||
symbol->row_height[1] = 2.0f;
|
||||
@ -524,13 +519,11 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
|
||||
struct zint_seg segs[1];
|
||||
|
||||
if (length > 90) {
|
||||
strcpy(symbol->errtxt, "589: Input too long (90 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 589, "Input length %d too long (maximum 90)", length);
|
||||
}
|
||||
|
||||
if (length < 28) { /* After adding prefix (4), blank Return to Sender Post Code (7), Reserved (6): 28 + 17 = 45 */
|
||||
strcpy(symbol->errtxt, "860: Input too short (28 character minimum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 860, "Input length %d too short (minimum 28)", length);
|
||||
}
|
||||
|
||||
/* Add prefix if missing */
|
||||
@ -538,8 +531,7 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
|
||||
to_upper(local_source, 3);
|
||||
if (memcmp(local_source, "JGB ", 4) != 0) {
|
||||
if (length > 86) {
|
||||
strcpy(symbol->errtxt, "861: Input too long (86 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 861, "Input length %d too long (maximum 86)", length);
|
||||
}
|
||||
ustrcpy(local_source, "JGB ");
|
||||
ustrcpy(local_source + 4, source);
|
||||
@ -549,8 +541,7 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
|
||||
}
|
||||
|
||||
if (length < 32) {
|
||||
strcpy(symbol->errtxt, "862: Input too short (32 character minimum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 862, "Input length %d too short (minimum 32)", length);
|
||||
}
|
||||
if (length < 39) { /* Space-pad Return to Sender Post Code */
|
||||
memset(local_source + length, ' ', 39 - length);
|
||||
@ -568,18 +559,18 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
|
||||
/* 8: 24 x 24, 10: 32 x 32, 30: 16 x 48 */
|
||||
if (symbol->option_2) {
|
||||
if (symbol->option_2 != 8 && symbol->option_2 != 10 && symbol->option_2 != 30) {
|
||||
strcpy(symbol->errtxt, "863: Invalid symbol size selected (8, 10, 30 only)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 863, "Invalid Version '%d' (8, 10 or 30 only)",
|
||||
symbol->option_2);
|
||||
}
|
||||
if (symbol->option_2 == 8) {
|
||||
if (length > 51) {
|
||||
strcpy(symbol->errtxt, "864: Input too long for selected size (51 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 864,
|
||||
"Input length %d too long for Version 8 (maximum 51)", length);
|
||||
}
|
||||
} else if (symbol->option_2 == 30) {
|
||||
if (length > 70) {
|
||||
strcpy(symbol->errtxt, "865: Input too long for selected size (70 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 865,
|
||||
"Input length %d too long for Version 30 (maximum 70)", length);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -596,38 +587,32 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
|
||||
printf("Producing 2D Mailmark %d (%d): %s<end>\n", symbol->option_2, length, local_source);
|
||||
}
|
||||
|
||||
if (!is_sane(RUBIDIUM_F, local_source, 45)) {
|
||||
strcpy(symbol->errtxt,
|
||||
"866: Invalid character in data (alphanumerics and space only in first 45 characters)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(RUBIDIUM_F, local_source, 45))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 866,
|
||||
"Invalid character at position %d in input (alphanumerics and space only in first 45)", i);
|
||||
}
|
||||
|
||||
/* Information Type ID */
|
||||
/* Not checking that matches values listed in Mailmark Definition Document as contradicted by Mailmark Mailing
|
||||
Requirements Section 5.7 which says 'P' for poll card is valid, which isn't listed */
|
||||
if (local_source[4] == ' ') {
|
||||
strcpy(symbol->errtxt, "867: Invalid Information Type ID (cannot be space)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 867, "Invalid Information Type ID (cannot be space)");
|
||||
}
|
||||
/* Version ID */
|
||||
if (local_source[5] != '1') {
|
||||
strcpy(symbol->errtxt, "868: Invalid Version ID (\"1\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 868, "Invalid Version ID (\"1\" only)");
|
||||
}
|
||||
/* Class */
|
||||
if (local_source[6] == ' ') {
|
||||
strcpy(symbol->errtxt, "869: Invalid Class (cannot be space)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 869, "Invalid Class (cannot be space)");
|
||||
}
|
||||
/* Supply Chain ID */
|
||||
if (cnt_digits(local_source, length, 7, 7) != 7) {
|
||||
strcpy(symbol->errtxt, "870: Invalid Supply Chain ID (7 digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 870, "Invalid Supply Chain ID (7 digits only)");
|
||||
}
|
||||
/* Item ID */
|
||||
if (cnt_digits(local_source, length, 14, 8) != 8) {
|
||||
strcpy(symbol->errtxt, "871: Invalid Item ID (8 digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 871, "Invalid Item ID (8 digits only)");
|
||||
}
|
||||
|
||||
/* Destination Post Code plus DPS field */
|
||||
@ -636,14 +621,12 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
|
||||
}
|
||||
postcode[9] = '\0';
|
||||
if (mailmark_verify_postcode(postcode, NULL) != 0) {
|
||||
strcpy(symbol->errtxt, "872: Invalid Destination Post Code plus DPS");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 872, "Invalid Destination Post Code plus DPS");
|
||||
}
|
||||
|
||||
/* Service Type */
|
||||
if (local_source[31] < '0' || local_source[31] > '6') {
|
||||
strcpy(symbol->errtxt, "873: Invalid Service Type (\"0\" to \"6\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 873, "Invalid Service Type (\"0\" to \"6\" only)");
|
||||
}
|
||||
|
||||
/* Return to Sender Post Code */
|
||||
@ -661,15 +644,13 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
|
||||
}
|
||||
postcode[9] = '\0';
|
||||
if (mailmark_verify_postcode(postcode, NULL) != 0) {
|
||||
strcpy(symbol->errtxt, "874: Invalid Return to Sender Post Code");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 874, "Invalid Return to Sender Post Code");
|
||||
}
|
||||
}
|
||||
|
||||
/* Reserved */
|
||||
if (memcmp(local_source + 39, " ", 6) != 0) {
|
||||
strcpy(symbol->errtxt, "875: Invalid Reserved field (must be spaces only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 875, "Invalid Reserved field (must be spaces only)");
|
||||
}
|
||||
|
||||
segs[0].eci = 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* maxicode.c - Handles MaxiCode */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2010-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2010-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -31,6 +31,7 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
/* Includes corrections thanks to Monica Swanson @ Source Technologies */
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "common.h"
|
||||
#include "maxicode.h"
|
||||
@ -140,12 +141,14 @@ static int maxi_bestSurroundingSet(const int index, const int length, const unsi
|
||||
}
|
||||
|
||||
/* Format text according to Appendix A */
|
||||
static int maxi_text_process(unsigned char set[144], unsigned char character[144], const int mode,
|
||||
const unsigned char in_source[], int length, const int eci, const int scm_vv, int *p_sp,
|
||||
const int debug_print) {
|
||||
static int maxi_text_process(unsigned char set[144], unsigned char character[144], const unsigned char in_source[],
|
||||
int length, const int eci, const int scm_vv, int *p_sp, int current_set, const int debug_print) {
|
||||
|
||||
int sp = *p_sp;
|
||||
int i, count, current_set, padding_set;
|
||||
int i, count;
|
||||
#ifndef NDEBUG
|
||||
int ns_count1 = 0, ns_count2 = 0;
|
||||
#endif
|
||||
|
||||
static const unsigned char set15[2] = { 1, 5 };
|
||||
static const unsigned char set12[2] = { 1, 2 };
|
||||
@ -155,28 +158,28 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144
|
||||
unsigned char *source_buf = (unsigned char *) z_alloca(length + 9); /* For prefixing 9-character SCM sequence */
|
||||
|
||||
if (sp + length > 144) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Insert ECI at the beginning of message if needed */
|
||||
/* Encode ECI assignment numbers according to table 3 */
|
||||
if (eci != 0) {
|
||||
if (sp + 1 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
if (sp + 1 + length > 144) return 0;
|
||||
character[sp++] = 27; /* ECI */
|
||||
if (eci <= 31) {
|
||||
if (sp + 1 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
if (sp + 1 + length > 144) return 0;
|
||||
character[sp++] = eci;
|
||||
} else if (eci <= 1023) {
|
||||
if (sp + 2 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
if (sp + 2 + length > 144) return 0;
|
||||
character[sp++] = 0x20 | ((eci >> 6) & 0x0F);
|
||||
character[sp++] = eci & 0x3F;
|
||||
} else if (eci <= 32767) {
|
||||
if (sp + 3 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
if (sp + 3 + length > 144) return 0;
|
||||
character[sp++] = 0x30 | ((eci >> 12) & 0x07);
|
||||
character[sp++] = (eci >> 6) & 0x3F;
|
||||
character[sp++] = eci & 0x3F;
|
||||
} else {
|
||||
if (sp + 4 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
if (sp + 4 + length > 144) return 0;
|
||||
character[sp++] = 0x38 | ((eci >> 18) & 0x03);
|
||||
character[sp++] = (eci >> 12) & 0x3F;
|
||||
character[sp++] = (eci >> 6) & 0x3F;
|
||||
@ -186,7 +189,7 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144
|
||||
|
||||
if (scm_vv != -1) { /* Add SCM prefix */
|
||||
if (sp + length > 135) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return 0;
|
||||
}
|
||||
sprintf((char *) source_buf, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */
|
||||
memcpy(source_buf + 9, in_source, length);
|
||||
@ -285,18 +288,11 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144
|
||||
}
|
||||
}
|
||||
|
||||
padding_set = set[sp + length - 1] == 2 ? 2 : 1;
|
||||
for (i = length; sp + i < 144; i++) {
|
||||
/* Add the padding */
|
||||
set[sp + i] = padding_set;
|
||||
character[sp + i] = 33;
|
||||
}
|
||||
|
||||
/* Find candidates for number compression */
|
||||
/* Note the prohibition on number compression in the primary message in ISO/IEC 16023:2000 B.1 (1)
|
||||
applies to modes 2 & 3 only */
|
||||
count = 0;
|
||||
for (i = 0; sp + i < 144; i++) {
|
||||
for (i = 0; sp + i < 144 && sp + i < length; i++) {
|
||||
if ((set[sp + i] == 1) && ((character[sp + i] >= 48) && (character[sp + i] <= 57))) {
|
||||
/* Character is a number */
|
||||
count++;
|
||||
@ -304,6 +300,9 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144
|
||||
/* Nine digits in a row can be compressed */
|
||||
memset(set + sp + i - 8, 6, 9); /* Set set of nine digits to 6 */
|
||||
count = 0;
|
||||
#ifndef NDEBUG
|
||||
ns_count1++;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
count = 0;
|
||||
@ -311,9 +310,7 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144
|
||||
}
|
||||
|
||||
/* Add shift and latch characters */
|
||||
current_set = 1;
|
||||
i = 0;
|
||||
do {
|
||||
for (i = 0; sp + i < 144 && set[sp + i] != 255; i++) {
|
||||
|
||||
if ((set[sp + i] != current_set) && (set[sp + i] != 6)) {
|
||||
switch (set[sp + i]) {
|
||||
@ -405,14 +402,10 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144
|
||||
}
|
||||
i++; /* Allow for bump */
|
||||
}
|
||||
i++;
|
||||
} while (sp + i < 144);
|
||||
|
||||
if (debug_print) fputc('\n', stdout);
|
||||
}
|
||||
|
||||
/* Number compression has not been forgotten! - It's handled below */
|
||||
i = 0;
|
||||
do {
|
||||
for (i = 0; sp + i < 144 && sp + i <= length - 9; i++) {
|
||||
if (set[sp + i] == 6) {
|
||||
/* Number compression */
|
||||
int value = to_int(character + sp + i, 9);
|
||||
@ -424,30 +417,20 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144
|
||||
character[sp + i + 4] = (value & 0xfc0) >> 6;
|
||||
character[sp + i + 5] = (value & 0x3f);
|
||||
|
||||
i += 6;
|
||||
memmove(set + sp + i, set + sp + i + 3, 141 - (sp + i));
|
||||
memmove(character + sp + i, character + sp + i + 3, 141 - (sp + i));
|
||||
memmove(set + sp + i + 6, set + sp + i + 9, 144 - (sp + i + 9));
|
||||
memmove(character + sp + i + 6, character + sp + i + 9, 144 - (sp + i + 9));
|
||||
i += 5;
|
||||
length -= 3;
|
||||
} else {
|
||||
i++;
|
||||
#ifndef NDEBUG
|
||||
ns_count2++;
|
||||
#endif
|
||||
}
|
||||
} while (sp + i <= 135); /* 144 - 9 */
|
||||
|
||||
if (debug_print) printf("Length: %d\n", length);
|
||||
|
||||
if (((mode == 2) || (mode == 3)) && (sp + length > 84)) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
|
||||
} else if (((mode == 4) || (mode == 6)) && (sp + length > 93)) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
|
||||
} else if ((mode == 5) && (sp + length > 77)) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
assert(ns_count1 == ns_count2);
|
||||
|
||||
*p_sp = sp + length;
|
||||
|
||||
return 0;
|
||||
return current_set;
|
||||
}
|
||||
|
||||
/* Call `maxi_text_process()` for each segment, dealing with Structured Append beforehand and populating
|
||||
@ -456,8 +439,10 @@ static int maxi_text_process_segs(unsigned char maxi_codeword[144], const int mo
|
||||
const int seg_count, const int structapp_cw, int scm_vv, const int debug_print) {
|
||||
unsigned char set[144], character[144] = {0};
|
||||
int i;
|
||||
int error_number;
|
||||
int sp = 0;
|
||||
int current_set = 1; /* Initial Code Set A */
|
||||
int padding_set = 0, padding_char = 0; /* Suppress clang-tidy-20 warnings */
|
||||
const int max_length = mode == 5 ? 77 : mode <= 3 ? 84 : 93;
|
||||
|
||||
memset(set, 255, 144);
|
||||
|
||||
@ -468,14 +453,47 @@ static int maxi_text_process_segs(unsigned char maxi_codeword[144], const int mo
|
||||
}
|
||||
|
||||
for (i = 0; i < seg_count; i++) {
|
||||
error_number = maxi_text_process(set, character, mode, segs[i].source, segs[i].length, segs[i].eci, scm_vv,
|
||||
&sp, debug_print);
|
||||
if (error_number != 0) {
|
||||
return error_number;
|
||||
current_set = maxi_text_process(set, character, segs[i].source, segs[i].length, segs[i].eci, scm_vv, &sp,
|
||||
current_set, debug_print);
|
||||
if (current_set == 0) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
scm_vv = -1;
|
||||
}
|
||||
|
||||
/* If end in Code Set C or D, switch to A for padding */
|
||||
if (sp < max_length && (current_set == 3 || current_set == 4)) {
|
||||
set[sp] = 1;
|
||||
character[sp] = 58; /* Sets C,D Latch A */
|
||||
sp++;
|
||||
current_set = 1;
|
||||
if (debug_print) fputs("LCHA ", stdout);
|
||||
}
|
||||
|
||||
if (debug_print) {
|
||||
if (sp < max_length) {
|
||||
printf("\nPads (%d)\n", max_length - sp);
|
||||
} else {
|
||||
fputs("\nNo Pads\n", stdout);
|
||||
}
|
||||
}
|
||||
|
||||
if (sp < max_length) {
|
||||
padding_set = current_set == 5 ? 5 : current_set == 2 ? 2 : 1;
|
||||
padding_char = current_set == 5 ? 28 : 33;
|
||||
for (; sp < max_length; sp++) {
|
||||
/* Add the padding */
|
||||
set[sp] = padding_set;
|
||||
character[sp] = padding_char;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_print) printf("Length: %d\n", sp);
|
||||
|
||||
if (sp > max_length) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Copy the encoded text into the codeword array */
|
||||
if ((mode == 2) || (mode == 3)) {
|
||||
for (i = 0; i < 84; i++) { /* secondary only */
|
||||
@ -557,8 +575,7 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const
|
||||
lp = (int) strlen(symbol->primary);
|
||||
if (lp == 0) {
|
||||
if (mode == 0) { /* Require primary message to auto-determine between 2 and 3 */
|
||||
strcpy(symbol->errtxt, "554: Primary Message empty");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 554, "Primary Message empty");
|
||||
}
|
||||
mode = 4;
|
||||
} else {
|
||||
@ -573,8 +590,7 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const
|
||||
}
|
||||
|
||||
if ((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */
|
||||
strcpy(symbol->errtxt, "550: Invalid MaxiCode Mode");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 550, "Mode '%d' out of range (2 to 6)", mode);
|
||||
}
|
||||
|
||||
if ((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */
|
||||
@ -586,8 +602,11 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const
|
||||
lp = (int) strlen(symbol->primary);
|
||||
}
|
||||
if (lp < 7 || lp > 15) { /* 1 to 9 character postcode + 3 digit country code + 3 digit service class */
|
||||
strcpy(symbol->errtxt, "551: Invalid length for Primary Message");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if (lp == 0) {
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 548, "Primary Message empty");
|
||||
}
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 551, "Primary Message length %d wrong (7 to 15 only)",
|
||||
lp);
|
||||
}
|
||||
postcode_len = lp - 6;
|
||||
|
||||
@ -595,8 +614,8 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const
|
||||
service = to_int((const unsigned char *) (symbol->primary + postcode_len + 3), 3);
|
||||
|
||||
if (countrycode == -1 || service == -1) { /* check that country code and service are numeric */
|
||||
strcpy(symbol->errtxt, "552: Non-numeric country code or service class in Primary Message");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 552,
|
||||
"Non-numeric country code or service class in Primary Message");
|
||||
}
|
||||
|
||||
memcpy(postcode, symbol->primary, postcode_len);
|
||||
@ -609,10 +628,15 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const
|
||||
postcode_len = i;
|
||||
break;
|
||||
} else if (!z_isdigit(postcode[i])) {
|
||||
strcpy(symbol->errtxt, "555: Non-numeric postcode in Primary Message");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 555, "Non-numeric postcode in Primary Message");
|
||||
}
|
||||
}
|
||||
if (countrycode == 840 && postcode_len == 5) {
|
||||
/* Annex B, section B.1, paragraph 4.a, "In the case of country code 840, if the "+4" is unknown,
|
||||
then fill with zeroes" (adapted from OkaiBarcode, stricter interpretation, props Daniel Gredler) */
|
||||
memcpy(postcode + 5, "0000", 5); /* Include NUL char */
|
||||
postcode_len = 9;
|
||||
}
|
||||
maxi_do_primary_2(maxi_codeword, postcode, postcode_len, countrycode, service);
|
||||
} else {
|
||||
/* Just truncate and space-pad */
|
||||
@ -625,8 +649,8 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const
|
||||
for (i = 0; i < 6; i++) {
|
||||
/* Don't allow Code Set A control characters CR, RS, GS and RS */
|
||||
if (postcode[i] < ' ' || maxiCodeSet[postcode[i]] > 1) {
|
||||
strcpy(symbol->errtxt, "556: Invalid character in postcode in Primary Message");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 556,
|
||||
"Invalid character in postcode in Primary Message");
|
||||
}
|
||||
}
|
||||
maxi_do_primary_3(maxi_codeword, postcode, countrycode, service);
|
||||
@ -634,8 +658,8 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const
|
||||
|
||||
if (symbol->option_2) { /* Check for option_2 = vv + 1, where vv is version of SCM prefix "[)>\R01\Gvv" */
|
||||
if (symbol->option_2 < 0 || symbol->option_2 > 100) {
|
||||
strcpy(symbol->errtxt, "557: Invalid SCM prefix version");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 557,
|
||||
"SCM prefix version '%d' out of range (1 to 100)", symbol->option_2);
|
||||
}
|
||||
scm_vv = symbol->option_2 - 1;
|
||||
}
|
||||
@ -653,24 +677,23 @@ INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const
|
||||
|
||||
if (symbol->structapp.count) {
|
||||
if (symbol->structapp.count < 2 || symbol->structapp.count > 8) {
|
||||
strcpy(symbol->errtxt, "558: Structured Append count out of range (2-8)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 558,
|
||||
"Structured Append count '%d' out of range (2 to 8)", symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
|
||||
sprintf(symbol->errtxt, "559: Structured Append index out of range (1-%d)", symbol->structapp.count);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 559,
|
||||
"Structured Append index '%1$d' out of range (1 to count %2$d)",
|
||||
symbol->structapp.index, symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.id[0]) {
|
||||
strcpy(symbol->errtxt, "549: Structured Append ID not available for MaxiCode");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 549, "Structured Append ID not available for MaxiCode");
|
||||
}
|
||||
structapp_cw = (symbol->structapp.count - 1) | ((symbol->structapp.index - 1) << 3);
|
||||
}
|
||||
|
||||
error_number = maxi_text_process_segs(maxi_codeword, mode, segs, seg_count, structapp_cw, scm_vv, debug_print);
|
||||
if (error_number == ZINT_ERROR_TOO_LONG) {
|
||||
strcpy(symbol->errtxt, "553: Input data too long");
|
||||
return error_number;
|
||||
return errtxt(error_number, symbol, 553, "Input too long, requires too many codewords (maximum 144)");
|
||||
}
|
||||
|
||||
/* All the data is sorted - now do error correction */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* medical.c - Handles 1 track and 2 track pharmacode and Codabar */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -63,6 +63,7 @@ INTERNAL int pharma(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
the specification at http://www.laetus.com/laetus.php?request=file&id=69
|
||||
(http://www.gomaro.ch/ftproot/Laetus_PHARMA-CODE.pdf) */
|
||||
|
||||
int i;
|
||||
int tester;
|
||||
int counter, error_number = 0, h;
|
||||
char inter[18] = {0}; /* 131070 -> 17 bits */
|
||||
@ -71,18 +72,16 @@ INTERNAL int pharma(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
char *d = dest;
|
||||
|
||||
if (length > 6) {
|
||||
strcpy(symbol->errtxt, "350: Input too long (6 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 350, "Input length %d too long (maximum 6)", length);
|
||||
}
|
||||
tester = to_int(source, length);
|
||||
if (tester == -1) {
|
||||
strcpy(symbol->errtxt, "351: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 351,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
tester = to_int(source, length);
|
||||
if ((tester < 3) || (tester > 131070)) {
|
||||
strcpy(symbol->errtxt, "352: Data out of range (3 to 131070)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 352, "Input value '%d' out of range (3 to 131070)", tester);
|
||||
}
|
||||
|
||||
do {
|
||||
@ -152,6 +151,7 @@ static int pharma_two_calc(int tester, char *d) {
|
||||
|
||||
INTERNAL int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
/* Draws the patterns for two track pharmacode */
|
||||
int i;
|
||||
int tester;
|
||||
char height_pattern[200];
|
||||
unsigned int loopey, h;
|
||||
@ -159,17 +159,16 @@ INTERNAL int pharma_two(struct zint_symbol *symbol, unsigned char source[], int
|
||||
int error_number = 0;
|
||||
|
||||
if (length > 8) {
|
||||
strcpy(symbol->errtxt, "354: Input too long (8 character maximum");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 354, "Input length %d too long (maximum 8)", length);
|
||||
}
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 355,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
tester = to_int(source, length);
|
||||
if (tester == -1) {
|
||||
strcpy(symbol->errtxt, "355: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
}
|
||||
if ((tester < 4) || (tester > 64570080)) {
|
||||
strcpy(symbol->errtxt, "353: Data out of range (4 to 64570080)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 353, "Input value '%d' out of range (4 to 64570080)", tester);
|
||||
}
|
||||
h = pharma_two_calc(tester, height_pattern);
|
||||
|
||||
@ -209,36 +208,32 @@ INTERNAL int codabar(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
int d_chars = 0;
|
||||
|
||||
if (length > 103) { /* No stack smashing please (103 + 1) * 11 = 1144 */
|
||||
strcpy(symbol->errtxt, "356: Input too long (103 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 356, "Input length %d too long (maximum 103)", length);
|
||||
}
|
||||
/* BS EN 798:1995 4.2 "'Codabar' symbols shall consist of ... b) start character;
|
||||
c) one or more symbol characters representing data ... d) stop character ..." */
|
||||
if (length < 3) {
|
||||
strcpy(symbol->errtxt, "362: Input too short (3 character minimum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 362, "Input length %d too short (minimum 3)", length);
|
||||
}
|
||||
to_upper(source, length);
|
||||
|
||||
/* Codabar must begin and end with the characters A, B, C or D */
|
||||
if ((source[0] != 'A') && (source[0] != 'B') && (source[0] != 'C')
|
||||
&& (source[0] != 'D')) {
|
||||
strcpy(symbol->errtxt, "358: Does not begin with \"A\", \"B\", \"C\" or \"D\"");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 358, "Does not begin with \"A\", \"B\", \"C\" or \"D\"");
|
||||
}
|
||||
if ((source[length - 1] != 'A') && (source[length - 1] != 'B') &&
|
||||
(source[length - 1] != 'C') && (source[length - 1] != 'D')) {
|
||||
strcpy(symbol->errtxt, "359: Does not end with \"A\", \"B\", \"C\" or \"D\"");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 359, "Does not end with \"A\", \"B\", \"C\" or \"D\"");
|
||||
}
|
||||
if (!is_sane_lookup(CALCIUM, sizeof(CALCIUM) - 1, source, length, posns)) {
|
||||
sprintf(symbol->errtxt, "357: Invalid character in data (\"%s\" only)", CALCIUM);
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane_lookup(CALCIUM, sizeof(CALCIUM) - 1, source, length, posns))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 357,
|
||||
"Invalid character at position %1$d in input (\"%2$s\" only)", i, CALCIUM);
|
||||
}
|
||||
/* And must not use A, B, C or D otherwise (BS EN 798:1995 4.3.2) */
|
||||
if (!is_sane(CALCIUM_INNER_F, source + 1, length - 2)) {
|
||||
strcpy(symbol->errtxt, "363: Cannot contain \"A\", \"B\", \"C\" or \"D\"");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(CALCIUM_INNER_F, source + 1, length - 2))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 363,
|
||||
"Invalid character at position %d in input (cannot contain \"A\", \"B\", \"C\" or \"D\")", i);
|
||||
}
|
||||
|
||||
/* Add check character: 1 don't show to HRT, 2 do show to HRT
|
||||
@ -275,7 +270,7 @@ INTERNAL int codabar(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
narrow/wide ratio as 2 and I = X) width = ((2 * N + 5) * C + (N – 1) * (D + 2)) * X + I * (C – 1) + 2Q
|
||||
= ((4 + 5) * C + (D + 2) + C - 1 + 2 * 10) * X = (10 * C + D + 21) * X
|
||||
Length (C) includes start/stop chars */
|
||||
const float min_height_min = stripf(5.0f / 0.43f);
|
||||
const float min_height_min = 11.6279068f; /* 5.0 / 0.43 */
|
||||
float min_height = stripf((10.0f * ((add_checksum ? length + 1 : length) + 2.0f) + d_chars + 21.0f) * 0.15f);
|
||||
if (min_height < min_height_min) {
|
||||
min_height = min_height_min;
|
||||
@ -301,17 +296,16 @@ INTERNAL int code32(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
static const char TABELLA[] = "0123456789BCDFGHJKLMNPQRSTUVWXYZ";
|
||||
int i, zeroes, error_number = 0, checksum, checkpart, checkdigit;
|
||||
char localstr[10], risultante[7];
|
||||
long int pharmacode, devisor;
|
||||
unsigned int pharmacode, devisor;
|
||||
int codeword[6];
|
||||
|
||||
/* Validate the input */
|
||||
if (length > 8) {
|
||||
strcpy(symbol->errtxt, "360: Input too long (8 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 360, "Input length %d too long (maximum 8)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "361: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 361,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
/* Add leading zeros as required */
|
||||
@ -343,7 +337,7 @@ INTERNAL int code32(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
/* Convert from decimal to base-32 */
|
||||
devisor = 33554432;
|
||||
for (i = 5; i >= 0; i--) {
|
||||
long int remainder;
|
||||
unsigned int remainder;
|
||||
codeword[i] = pharmacode / devisor;
|
||||
remainder = pharmacode % devisor;
|
||||
pharmacode = remainder;
|
||||
|
100
backend/output.c
@ -1,7 +1,7 @@
|
||||
/* output.c - Common routines for raster/vector
|
||||
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2020-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2020-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -52,12 +52,12 @@ static int out_check_colour(struct zint_symbol *symbol, const char *colour, cons
|
||||
if ((comma1 = strchr(colour, ',')) == NULL) {
|
||||
const int len = (int) strlen(colour);
|
||||
if ((len != 6) && (len != 8)) {
|
||||
sprintf(symbol->errtxt, "880: Malformed %s RGB colour (6 or 8 characters only)", name);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 880, "Malformed %s RGB colour (6 or 8 characters only)",
|
||||
name);
|
||||
}
|
||||
if (!is_sane(OUT_SSET_F, (unsigned char *) colour, len)) {
|
||||
sprintf(symbol->errtxt, "881: Malformed %s RGB colour '%s' (hexadecimal only)", name, colour);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
if (not_sane(OUT_SSET_F, (unsigned char *) colour, len)) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 881,
|
||||
"Malformed %1$s RGB colour '%2$s' (hexadecimal only)", name, colour);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -66,29 +66,29 @@ static int out_check_colour(struct zint_symbol *symbol, const char *colour, cons
|
||||
/* CMYK comma-separated percentages */
|
||||
if ((comma2 = strchr(comma1 + 1, ',')) == NULL || (comma3 = strchr(comma2 + 1, ',')) == NULL
|
||||
|| strchr(comma3 + 1, ',') != NULL) {
|
||||
sprintf(symbol->errtxt, "882: Malformed %s CMYK colour (4 decimal numbers, comma-separated)", name);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 882,
|
||||
"Malformed %s CMYK colour (4 decimal numbers, comma-separated)", name);
|
||||
}
|
||||
if (comma1 - colour > 3 || comma2 - (comma1 + 1) > 3 || comma3 - (comma2 + 1) > 3 || strlen(comma3 + 1) > 3) {
|
||||
sprintf(symbol->errtxt, "883: Malformed %s CMYK colour (3 digit maximum per number)", name);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 883,
|
||||
"Malformed %s CMYK colour (3 digit maximum per number)", name);
|
||||
}
|
||||
|
||||
if ((val = to_int((const unsigned char *) colour, (int) (comma1 - colour))) == -1 || val > 100) {
|
||||
sprintf(symbol->errtxt, "884: Malformed %s CMYK colour C (decimal 0-100 only)", name);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 884, "Malformed %s CMYK colour C (decimal 0 to 100 only)",
|
||||
name);
|
||||
}
|
||||
if ((val = to_int((const unsigned char *) (comma1 + 1), (int) (comma2 - (comma1 + 1)))) == -1 || val > 100) {
|
||||
sprintf(symbol->errtxt, "885: Malformed %s CMYK colour M (decimal 0-100 only)", name);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 885, "Malformed %s CMYK colour M (decimal 0 to 100 only)",
|
||||
name);
|
||||
}
|
||||
if ((val = to_int((const unsigned char *) (comma2 + 1), (int) (comma3 - (comma2 + 1)))) == -1 || val > 100) {
|
||||
sprintf(symbol->errtxt, "886: Malformed %s CMYK colour Y (decimal 0-100 only)", name);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 886, "Malformed %s CMYK colour Y (decimal 0 to 100 only)",
|
||||
name);
|
||||
}
|
||||
if ((val = to_int((const unsigned char *) (comma3 + 1), (int) strlen(comma3 + 1))) == -1 || val > 100) {
|
||||
sprintf(symbol->errtxt, "887: Malformed %s CMYK colour K (decimal 0-100 only)", name);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 887, "Malformed %s CMYK colour K (decimal 0 to 100 only)",
|
||||
name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -129,13 +129,13 @@ INTERNAL int out_colour_get_rgb(const char *colour, unsigned char *red, unsigned
|
||||
black = 100 - to_int((const unsigned char *) (comma3 + 1), (int) strlen(comma3 + 1));
|
||||
|
||||
val = 100 - to_int((const unsigned char *) colour, (int) (comma1 - colour)); /* Cyan */
|
||||
*red = (int) roundf((0xFF * val * black) / 10000.0f);
|
||||
*red = (int) round((0xFF * val * black) / 10000.0);
|
||||
|
||||
val = 100 - to_int((const unsigned char *) (comma1 + 1), (int) (comma2 - (comma1 + 1))); /* Magenta */
|
||||
*green = (int) roundf((0xFF * val * black) / 10000.0f);
|
||||
*green = (int) round((0xFF * val * black) / 10000.0);
|
||||
|
||||
val = 100 - to_int((const unsigned char *) (comma2 + 1), (int) (comma3 - (comma2 + 1))); /* Yellow */
|
||||
*blue = (int) roundf((0xFF * val * black) / 10000.0f);
|
||||
*blue = (int) round((0xFF * val * black) / 10000.0);
|
||||
|
||||
if (alpha) {
|
||||
*alpha = 0xFF;
|
||||
@ -176,10 +176,10 @@ INTERNAL int out_colour_get_cmyk(const char *colour, int *cyan, int *magenta, in
|
||||
*cyan = *magenta = *yellow = 0;
|
||||
*black = 100;
|
||||
} else {
|
||||
*cyan = (int) roundf((k - red) * 100.0f / k);
|
||||
*magenta = (int) roundf((k - green) * 100.0f / k);
|
||||
*yellow = (int) roundf((k - blue) * 100.0f / k);
|
||||
*black = (int) roundf(((0xFF - k) * 100.0f) / 0xFF);
|
||||
*cyan = (int) round((k - red) * 100.0 / k);
|
||||
*magenta = (int) round((k - green) * 100.0 / k);
|
||||
*yellow = (int) round((k - blue) * 100.0 / k);
|
||||
*black = (int) round(((0xFF - k) * 100.0) / 0xFF);
|
||||
}
|
||||
|
||||
if (rgb_alpha) {
|
||||
@ -504,8 +504,8 @@ static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text
|
||||
/* USPS DMM 300 2006 (2011) 708.9.3 (top/bottom zero)
|
||||
right 0.125" (min) / 0.03925" (X max) ~ 3.18, left 1.25" - 0.66725" (max width of barcode)
|
||||
- 0.375 (max right) = 0.20775" / 0.03925" (X max) ~ 5.29 */
|
||||
*right = (float) (0.125 / 0.03925);
|
||||
*left = (float) (0.20775 / 0.03925);
|
||||
*right = 3.18471336f; /* 0.125 / 0.03925 */
|
||||
*left = 5.29299355f; /* 0.20775 / 0.03925 */
|
||||
done = 1;
|
||||
break;
|
||||
case BARCODE_PHARMA:
|
||||
@ -561,13 +561,13 @@ static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text
|
||||
/* Customer Barcode Technical Specifications (2012) left/right 6mm / 0.6mm = 10,
|
||||
top/bottom 2mm / 0.6mm ~ 3.33 (X max) */
|
||||
*left = *right = 10.0f;
|
||||
*top = *bottom = (float) (2.0 / 0.6);
|
||||
*top = *bottom = 3.33333325f; /* 2.0 / 0.6 */
|
||||
done = 1;
|
||||
break;
|
||||
case BARCODE_RM4SCC:
|
||||
/* Royal Mail Know How User's Manual Appendix C: using CBC, same as MAILMARK_4S, 2mm all round,
|
||||
use X max (25.4mm / 39) i.e. 20 bars per 25.4mm */
|
||||
*left = *right = *top = *bottom = (float) ((2.0 * 39.0) / 25.4); /* ~ 3.07 */
|
||||
*left = *right = *top = *bottom = 3.07086611f; /* (2.0 * 39.0) / 25.4 */
|
||||
done = 1;
|
||||
break;
|
||||
case BARCODE_DATAMATRIX:
|
||||
@ -578,7 +578,7 @@ static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text
|
||||
break;
|
||||
case BARCODE_JAPANPOST:
|
||||
/* Japan Post Zip/Barcode Manual p.13 2mm all round, X 0.6mm, 2mm / 0.6mm ~ 3.33 */
|
||||
*left = *right = *top = *bottom = (float) (2.0 / 0.6);
|
||||
*left = *right = *top = *bottom = 3.33333325f; /* 2.0 / 0.6 */
|
||||
done = 1;
|
||||
break;
|
||||
|
||||
@ -591,8 +591,8 @@ static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text
|
||||
case BARCODE_USPS_IMAIL:
|
||||
/* USPS-B-3200 (2015) Section 2.3.2 left/right 0.125", top/bottom 0.026", use X max (1 / 39)
|
||||
i.e. 20 bars per inch */
|
||||
*left = *right = 0.125f * 39.0f; /* 4.875 */
|
||||
*top = *bottom = 0.026f * 39.0f; /* 1.014 */
|
||||
*left = *right = 4.875f; /* 0.125 * 39.0 */
|
||||
*top = *bottom = 1.01400006f; /* 0.026 * 39.0 */
|
||||
done = 1;
|
||||
break;
|
||||
|
||||
@ -604,7 +604,7 @@ static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text
|
||||
|
||||
case BARCODE_KIX:
|
||||
/* Handleiding KIX code brochure - same as RM4SCC/MAILMARK_4S */
|
||||
*left = *right = *top = *bottom = (float) ((2.0 * 39.0) / 25.4); /* ~ 3.07 */
|
||||
*left = *right = *top = *bottom = 3.07086611f; /* (2.0 * 39.0) / 25.4 */
|
||||
done = 1;
|
||||
break;
|
||||
case BARCODE_AZTEC:
|
||||
@ -630,7 +630,7 @@ static int out_quiet_zones(const struct zint_symbol *symbol, const int hide_text
|
||||
case BARCODE_MAILMARK_4S:
|
||||
/* Royal Mail Mailmark Barcode Definition Document Section 3.5.2, 2mm all round, use X max (25.4mm / 39)
|
||||
i.e. 20 bars per 25.4mm */
|
||||
*left = *right = *top = *bottom = (float) ((2.0 * 39.0) / 25.4); /* ~ 3.07 */
|
||||
*left = *right = *top = *bottom = 3.07086611f; /* (2.0 * 39.0) / 25.4 */
|
||||
done = 1;
|
||||
break;
|
||||
case BARCODE_UPU_S10:
|
||||
@ -971,7 +971,7 @@ INTERNAL FILE *out_fopen(const char filename[256], const char *mode) {
|
||||
memcpy(dirname, filename, dirend - filename);
|
||||
dirname[dirend - filename] = '/';
|
||||
dirname[dirend - filename + 1] = '\0';
|
||||
#if _WIN32
|
||||
#ifdef _WIN32
|
||||
for (d = dirname; *d; d++) { /* Convert to Unix separators */
|
||||
if (*d == '\\') {
|
||||
*d = '/';
|
||||
@ -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 : */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* output.h - Common routines for raster/vector */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2020-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2020-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -77,8 +77,50 @@ 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);
|
||||
/* Little-endian output */
|
||||
#define out_le_u16(b, n) do { \
|
||||
unsigned char *bp = (unsigned char *) &(b); \
|
||||
uint16_t u16 = (uint16_t) (n); \
|
||||
bp[0] = (unsigned char) (u16 & 0xFF); \
|
||||
bp[1] = (unsigned char) ((u16 >> 8) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
#define out_le_u32(b, n) do { \
|
||||
unsigned char *bp = (unsigned char *) &(b); \
|
||||
uint32_t u32 = (uint32_t) (n); \
|
||||
bp[0] = (unsigned char) (u32 & 0xFF); \
|
||||
bp[1] = (unsigned char) ((u32 >> 8) & 0xFF); \
|
||||
bp[2] = (unsigned char) ((u32 >> 16) & 0xFF); \
|
||||
bp[3] = (unsigned char) ((u32 >> 24) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
#define out_le_i32(b, n) do { \
|
||||
unsigned char *bp = (unsigned char *) &(b); \
|
||||
int32_t i32 = (int32_t) (n); \
|
||||
bp[0] = (unsigned char) (i32 & 0xFF); \
|
||||
bp[1] = (unsigned char) ((i32 >> 8) & 0xFF); \
|
||||
bp[2] = (unsigned char) ((i32 >> 16) & 0xFF); \
|
||||
bp[3] = (unsigned char) ((i32 >> 24) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
#define out_le_float(b, n) do { \
|
||||
unsigned char *bp = (unsigned char *) &(b); \
|
||||
float f = (float) (n); \
|
||||
uint32_t *p_u32 = (uint32_t *) &f; \
|
||||
bp[0] = (unsigned char) (*p_u32 & 0xFF); \
|
||||
bp[1] = (unsigned char) ((*p_u32 >> 8) & 0xFF); \
|
||||
bp[2] = (unsigned char) ((*p_u32 >> 16) & 0xFF); \
|
||||
bp[3] = (unsigned char) ((*p_u32 >> 24) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
/* If `#pragma pack()` not supported, try per-type packed attribute */
|
||||
#ifdef __COMPCERT__
|
||||
/* Can't use `__attribute__` as may be defined to be no-op by libc if not GNU C or Clang (e.g. glibc does this) */
|
||||
# define OUT_PACK __attribute((__packed__)) /* CompCert C workaround extension `__attribute` */
|
||||
#else
|
||||
# define OUT_USE_PRAGMA_PACK
|
||||
# define OUT_PACK
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* pcx.c - Handles output to ZSoft PCX file */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -33,11 +33,8 @@
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "filemem.h"
|
||||
#include "output.h"
|
||||
#include "pcx.h" /* PCX header structure */
|
||||
|
||||
@ -46,11 +43,12 @@ 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;
|
||||
int bytes_per_line = symbol->bitmap_width + (symbol->bitmap_width & 1); /* Must be even */
|
||||
unsigned char previous;
|
||||
const int output_to_stdout = symbol->output_options & BARCODE_STDOUT; /* Suppress gcc -fanalyzer warning */
|
||||
const unsigned char *pb;
|
||||
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);
|
||||
|
||||
rle_row[bytes_per_line - 1] = 0; /* Will remain zero if bitmap_width odd */
|
||||
@ -62,11 +60,11 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
|
||||
header.version = 5; /* Version 3.0 */
|
||||
header.encoding = 1; /* Run length encoding */
|
||||
header.bits_per_pixel = 8; /* TODO: 1-bit monochrome black/white */
|
||||
header.window_xmin = 0;
|
||||
header.window_ymin = 0;
|
||||
header.window_xmax = symbol->bitmap_width - 1;
|
||||
header.window_ymax = symbol->bitmap_height - 1;
|
||||
header.horiz_dpi = symbol->dpmm ? (uint16_t) roundf(stripf(symbol->dpmm * 25.4f)) : 300;
|
||||
out_le_u16(header.window_xmin, 0);
|
||||
out_le_u16(header.window_ymin, 0);
|
||||
out_le_u16(header.window_xmax, symbol->bitmap_width - 1);
|
||||
out_le_u16(header.window_ymax, symbol->bitmap_height - 1);
|
||||
out_le_u16(header.horiz_dpi, symbol->dpmm ? roundf(stripf(symbol->dpmm * 25.4f)) : 300);
|
||||
header.vert_dpi = header.horiz_dpi;
|
||||
|
||||
for (i = 0; i < 48; i++) {
|
||||
@ -76,36 +74,25 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
|
||||
header.reserved = 0;
|
||||
header.number_of_planes = 3 + (fgalpha != 0xFF || bgalpha != 0xFF); /* TODO: 1-bit monochrome black/white */
|
||||
|
||||
header.bytes_per_line = bytes_per_line;
|
||||
out_le_u16(header.bytes_per_line, bytes_per_line);
|
||||
|
||||
header.palette_info = 1; /* Colour */
|
||||
header.horiz_screen_size = 0;
|
||||
header.vert_screen_size = 0;
|
||||
out_le_u16(header.palette_info, 1); /* Colour */
|
||||
out_le_u16(header.horiz_screen_size, 0);
|
||||
out_le_u16(header.vert_screen_size, 0);
|
||||
|
||||
for (i = 0; i < 54; i++) {
|
||||
header.filler[i] = 0x00;
|
||||
}
|
||||
|
||||
/* 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")) {
|
||||
return errtxtf(ZINT_ERROR_FILE_ACCESS, symbol, 621, "Could not open PCX output file (%1$d: %2$s)", fmp->err,
|
||||
strerror(fmp->err));
|
||||
}
|
||||
|
||||
fwrite(&header, sizeof(pcx_header_t), 1, pcx_file);
|
||||
fm_write(&header, sizeof(pcx_header_t), 1, fmp);
|
||||
|
||||
for (row = 0; row < symbol->bitmap_height; row++) {
|
||||
const unsigned char *const pb = pixelbuf + row * symbol->bitmap_width;
|
||||
for (row = 0, pb = pixelbuf; row < symbol->bitmap_height; row++, pb += symbol->bitmap_width) {
|
||||
for (colour = 0; colour < header.number_of_planes; colour++) {
|
||||
for (column = 0; column < symbol->bitmap_width; column++) {
|
||||
const unsigned char ch = pb[column];
|
||||
@ -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)) {
|
||||
errtxtf(0, symbol, 622, "Incomplete write of PCX output (%1$d: %2$s)", 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)) {
|
||||
return errtxtf(ZINT_ERROR_FILE_WRITE, symbol, 624, "Failure on closing PCX output file (%1$d: %2$s)",
|
||||
fmp->err, strerror(fmp->err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* pcx.h - header structure for ZSoft PCX files */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2016-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2016-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -35,9 +35,11 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#pragma pack (1)
|
||||
#ifdef OUT_USE_PRAGMA_PACK
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
typedef struct pcx_header {
|
||||
uint8_t manufacturer;
|
||||
@ -58,13 +60,15 @@ extern "C" {
|
||||
uint16_t horiz_screen_size;
|
||||
uint16_t vert_screen_size;
|
||||
uint8_t filler[54];
|
||||
} pcx_header_t;
|
||||
} OUT_PACK pcx_header_t;
|
||||
|
||||
#pragma pack ()
|
||||
#ifdef OUT_USE_PRAGMA_PACK
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
#endif /* Z_PCX_H */
|
||||
|
168
backend/pdf417.c
@ -1,7 +1,7 @@
|
||||
/* pdf417.c - Handles PDF417 stacked symbology */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
Portions Copyright (C) 2004 Grandzebu
|
||||
Bug Fixes thanks to KL Chin <klchin@users.sourceforge.net>
|
||||
|
||||
@ -68,7 +68,7 @@ static const char pdf_smodes[] = { '?', 'A', 'L', 'M', 'P', 'B', 'N' };
|
||||
|
||||
/* Return (real) mode text */
|
||||
static const char *pdf_mode_str(const int mode) {
|
||||
static const char *modes[3] = { "Text", "Byte", "Number" };
|
||||
static const char modes[3][7] = { "Text", "Byte", "Number" };
|
||||
return mode >= PDF_TEX && mode <= PDF_NUM ? modes[mode - PDF_TEX] : "ERROR";
|
||||
}
|
||||
|
||||
@ -146,10 +146,12 @@ static const char pdf_MicroAutosize[56] = {
|
||||
/* ISO/IEC 15438:2015 5.1.1 c) 3) Max possible number of characters at error correction level 0
|
||||
(Numeric Compaction mode) */
|
||||
#define PDF_MAX_LEN 2710
|
||||
#define PDF_MAX_LEN_S "2710" /* String version of above */
|
||||
#define PDF_MAX_STREAM_LEN (PDF_MAX_LEN * 3) /* Allow for tripling up due to shifts/latches (ticket #300 (#7)) */
|
||||
|
||||
/* ISO/IEC 24728:2006 5.1.1 c) 3) Max possible number of characters (Numeric Compaction mode) */
|
||||
#define MICRO_PDF_MAX_LEN 366
|
||||
#define MICRO_PDF_MAX_LEN_S "366" /* String version of above */
|
||||
|
||||
/* 866 */
|
||||
/* Initial non-compressed categorization of input */
|
||||
@ -166,7 +168,8 @@ static int pdf_quelmode(const unsigned char codeascii) {
|
||||
}
|
||||
|
||||
/* Helper to switch TEX mode sub-mode */
|
||||
static int pdf_textprocess_switch(const int curtable, const int newtable, unsigned char chainet[PDF_MAX_STREAM_LEN], int wnet) {
|
||||
static int pdf_textprocess_switch(const int curtable, const int newtable, unsigned char chainet[PDF_MAX_STREAM_LEN],
|
||||
int wnet) {
|
||||
switch (curtable) {
|
||||
case T_ALPHA:
|
||||
switch (newtable) {
|
||||
@ -320,15 +323,11 @@ static int pdf_num_stay(const unsigned char *chaine, const int indexliste, short
|
||||
}
|
||||
|
||||
/* Pack segments using the method described in Appendix D of the AIM specification (ISO/IEC 15438:2015 Annex N) */
|
||||
static void pdf_appendix_d_encode(const unsigned char *chaine, short liste[3][PDF_MAX_LEN], int *p_indexliste,
|
||||
const int debug_print) {
|
||||
static void pdf_appendix_d_encode(const unsigned char *chaine, short liste[3][PDF_MAX_LEN], int *p_indexliste) {
|
||||
const int indexliste = *p_indexliste;
|
||||
int i = 0, next, last = 0, stayintext = 0;
|
||||
|
||||
while (i < indexliste) {
|
||||
if (debug_print) {
|
||||
printf("Encoding block %d = %d (%d)\n", i, liste[1][i], liste[0][i]);
|
||||
}
|
||||
|
||||
if ((liste[1][i] == PDF_NUM) && pdf_num_stay(chaine, indexliste, liste, i)) {
|
||||
/* leave as numeric */
|
||||
@ -510,7 +509,7 @@ static void pdf_textprocess_minimal(short *chainemc, int *p_mclength, const unsi
|
||||
}
|
||||
|
||||
for (i = *p_i; i < indexliste && PDF_REAL_MODE(liste[1][i]) == PDF_TEX; i++) {
|
||||
static const int newtables[5] = { 0, T_ALPHA, T_LOWER, T_MIXED, T_PUNCT };
|
||||
static const unsigned char newtables[5] = { 0, T_ALPHA, T_LOWER, T_MIXED, T_PUNCT };
|
||||
const int newtable = newtables[liste[1][i]];
|
||||
const int from = liste[2][i];
|
||||
for (j = 0; j < liste[0][i]; j++) {
|
||||
@ -554,30 +553,23 @@ static void pdf_textprocess_minimal(short *chainemc, int *p_mclength, const unsi
|
||||
/* 671 */
|
||||
/* Byte compaction */
|
||||
INTERNAL void pdf_byteprocess(short *chainemc, int *p_mclength, const unsigned char chaine[], int start,
|
||||
const int length, const int lastmode, const int debug_print) {
|
||||
const int length, const int lastmode) {
|
||||
const int real_lastmode = PDF_REAL_MODE(lastmode);
|
||||
|
||||
if (debug_print) printf("\nEntering byte mode at position %d\n", start);
|
||||
|
||||
if (length == 1) {
|
||||
/* shift or latch depending on previous mode */
|
||||
chainemc[(*p_mclength)++] = real_lastmode == PDF_TEX ? 913 : 901;
|
||||
chainemc[(*p_mclength)++] = chaine[start];
|
||||
if (debug_print) {
|
||||
printf("%s %d\n", real_lastmode == PDF_TEX ? "913" : "901", chaine[start]);
|
||||
}
|
||||
} else {
|
||||
int len;
|
||||
/* select the switch for multiple of 6 bytes */
|
||||
if (length % 6 == 0) {
|
||||
chainemc[(*p_mclength)++] = 924;
|
||||
if (debug_print) fputs("924 ", stdout);
|
||||
} else {
|
||||
/* Default mode for MICROPDF417 is Byte Compaction (ISO/IEC 24728:2006 5.4.3), but not emitting it
|
||||
* depends on whether an ECI has been emitted previously (or not) it appears, so simpler and safer
|
||||
* to always emit it. */
|
||||
chainemc[(*p_mclength)++] = 901;
|
||||
if (debug_print) fputs("901 ", stdout);
|
||||
}
|
||||
|
||||
len = 0;
|
||||
@ -1025,24 +1017,26 @@ static int pdf_initial(struct zint_symbol *symbol, const unsigned char chaine[],
|
||||
if (debug_print) {
|
||||
fputs("\nInitial block pattern:\n", stdout);
|
||||
for (i = 0; i < indexliste; i++) {
|
||||
printf("Start: %d Len: %d Type: %s\n", liste[2][i], liste[0][i], pdf_mode_str(liste[1][i]));
|
||||
int j;
|
||||
for (j = 0; j < liste[0][i]; j++) fputc(pdf_mode_str(liste[1][i])[0], stdout);
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
pdf_appendix_d_encode(chaine, liste, &indexliste, debug_print);
|
||||
pdf_appendix_d_encode(chaine, liste, &indexliste);
|
||||
} else {
|
||||
if (!pdf_define_mode(liste, &indexliste, chaine, length, *p_lastmode, debug_print)) {
|
||||
strcpy(symbol->errtxt, "749: Insufficient memory for mode buffers");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 749, "Insufficient memory for mode buffers");
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_print) {
|
||||
fputs("\nCompacted block pattern:\n", stdout);
|
||||
for (i = 0; i < indexliste; i++) {
|
||||
printf("Start: %d Len: %d Type: %s\n", liste[2][i], liste[0][i],
|
||||
pdf_mode_str(PDF_REAL_MODE(liste[1][i])));
|
||||
int j;
|
||||
for (j = 0; j < liste[0][i]; j++) fputc(pdf_mode_str(PDF_REAL_MODE(liste[1][i]))[0], stdout);
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
/* 541 - now compress the data */
|
||||
@ -1058,8 +1052,8 @@ static int pdf_initial(struct zint_symbol *symbol, const unsigned char chaine[],
|
||||
|
||||
if (eci != 0) {
|
||||
if (eci > 811799) {
|
||||
strcpy(symbol->errtxt, "472: Invalid ECI");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 472, "ECI code '%d' out of range (0 to 811799)",
|
||||
symbol->eci);
|
||||
}
|
||||
/* Encoding ECI assignment number, according to Table 8 */
|
||||
if (eci <= 899) {
|
||||
@ -1092,7 +1086,7 @@ static int pdf_initial(struct zint_symbol *symbol, const unsigned char chaine[],
|
||||
}
|
||||
break;
|
||||
case PDF_BYT: /* 670 - octet stream mode */
|
||||
pdf_byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], *p_lastmode, debug_print);
|
||||
pdf_byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], *p_lastmode);
|
||||
/* don't switch mode on single byte shift from text mode */
|
||||
if (PDF_REAL_MODE(*p_lastmode) != PDF_TEX || liste[0][i] != 1) {
|
||||
*p_lastmode = PDF_BYT;
|
||||
@ -1132,12 +1126,13 @@ static int pdf_initial_segs(struct zint_symbol *symbol, struct zint_seg segs[],
|
||||
int id_cnt = 0, ids[10];
|
||||
|
||||
if (symbol->structapp.count < 2 || symbol->structapp.count > 99999) {
|
||||
strcpy(symbol->errtxt, "740: Structured Append count out of range (2-99999)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 740,
|
||||
"Structured Append count '%d' out of range (2 to 99999)", symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.index < 1 || symbol->structapp.index > symbol->structapp.count) {
|
||||
sprintf(symbol->errtxt, "741: Structured Append index out of range (1-%d)", symbol->structapp.count);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 741,
|
||||
"Structured Append index '%1$d' out of range (1 to count %2$d)",
|
||||
symbol->structapp.index, symbol->structapp.count);
|
||||
}
|
||||
if (symbol->structapp.id[0]) {
|
||||
int id_len;
|
||||
@ -1145,21 +1140,21 @@ static int pdf_initial_segs(struct zint_symbol *symbol, struct zint_seg segs[],
|
||||
for (id_len = 1; id_len < 31 && symbol->structapp.id[id_len]; id_len++);
|
||||
|
||||
if (id_len > 30) { /* 10 triplets */
|
||||
strcpy(symbol->errtxt, "742: Structured Append ID too long (30 digit maximum)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 742,
|
||||
"Structured Append ID length %d too long (30 digit maximum)", id_len);
|
||||
}
|
||||
|
||||
for (i = 0; i < id_len; i += 3, id_cnt++) {
|
||||
const int triplet_len = i + 3 < id_len ? 3 : id_len - i;
|
||||
ids[id_cnt] = to_int((const unsigned char *) (symbol->structapp.id + i), triplet_len);
|
||||
if (ids[id_cnt] == -1) {
|
||||
strcpy(symbol->errtxt, "743: Invalid Structured Append ID (digits only)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 743,
|
||||
"Invalid Structured Append ID (digits only)");
|
||||
}
|
||||
if (ids[id_cnt] > 899) {
|
||||
sprintf(symbol->errtxt, "744: Structured Append ID triplet %d '%03d' out of range (000-899)",
|
||||
id_cnt + 1, ids[id_cnt]);
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 744,
|
||||
"Structured Append ID triplet %1$d value '%2$03d' out of range (000 to 899)",
|
||||
id_cnt + 1, ids[id_cnt]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1209,11 +1204,10 @@ static int pdf_enc(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
int structapp_cp = 0;
|
||||
int error_number;
|
||||
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
|
||||
static const int ecc_num_cws[] = { 2, 4, 8, 16, 32, 64, 128, 256, 512 };
|
||||
static const short ecc_num_cws[] = { 2, 4, 8, 16, 32, 64, 128, 256, 512 };
|
||||
|
||||
if (segs_length(segs, seg_count) > PDF_MAX_LEN) {
|
||||
strcpy(symbol->errtxt, "463: Input string too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
if ((i = segs_length(segs, seg_count)) > PDF_MAX_LEN) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 463, "Input length %d too long (maximum " PDF_MAX_LEN_S ")", i);
|
||||
}
|
||||
|
||||
error_number = pdf_initial_segs(symbol, segs, seg_count, 0 /*is_micro*/, chainemc, &mclength, structapp_cws,
|
||||
@ -1257,8 +1251,7 @@ static int pdf_enc(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
|
||||
if (longueur > 928) {
|
||||
/* Enforce maximum codeword limit */
|
||||
strcpy(symbol->errtxt, "464: Input string too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 464, "Input too long, requires too many codewords (maximum 928)");
|
||||
}
|
||||
|
||||
cols = symbol->option_2;
|
||||
@ -1275,21 +1268,20 @@ static int pdf_enc(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
/* Increase rows if multiple too big */
|
||||
for (; cols >= 1 && rows < 90 && rows * cols > 928; rows++, cols = (longueur + rows - 1) / rows);
|
||||
if (rows * cols > 928) {
|
||||
strcpy(symbol->errtxt, "465: Data too long for specified number of rows");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 465,
|
||||
"Input too long, requires too many codewords (maximum 928)");
|
||||
}
|
||||
}
|
||||
} else { /* Cols given */
|
||||
/* Increase rows if multiple too big */
|
||||
for (; rows <= 90 && rows * cols < longueur; rows++);
|
||||
if (rows > 90 || rows * cols > 928) {
|
||||
strcpy(symbol->errtxt, "745: Data too long for specified number of columns");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 745, "Input too long for number of columns '%d'", cols);
|
||||
}
|
||||
}
|
||||
if (rows != symbol->option_3) {
|
||||
sprintf(symbol->errtxt, "746: Rows increased from %d to %d", symbol->option_3, rows);
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
error_number = errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 746,
|
||||
"Number of rows increased from %1$d to %2$d", symbol->option_3, rows);
|
||||
}
|
||||
} else { /* Rows automatic, cols automatic or given */
|
||||
if (cols < 1) { /* Cols automatic */
|
||||
@ -1306,12 +1298,12 @@ static int pdf_enc(struct zint_symbol *symbol, struct zint_seg segs[], const int
|
||||
/* Increase cols if multiple too big */
|
||||
for (; rows >= 3 && cols < 30 && rows * cols > 928; cols++, rows = (longueur + cols - 1) / cols);
|
||||
if (rows * cols > 928) {
|
||||
strcpy(symbol->errtxt, "747: Data too long for specified number of columns");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 747,
|
||||
"Input too long, requires too many codewords (maximum 928)");
|
||||
}
|
||||
if (symbol->option_2 && cols != symbol->option_2) { /* Note previously did not warn if cols auto-upped */
|
||||
sprintf(symbol->errtxt, "748: Columns increased from %d to %d", symbol->option_2, cols);
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
error_number = errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 748,
|
||||
"Number of columns increased from %1$d to %2$d", symbol->option_2, cols);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1457,28 +1449,28 @@ INTERNAL int pdf417(struct zint_symbol *symbol, struct zint_seg segs[], const in
|
||||
error_number = 0;
|
||||
|
||||
if ((symbol->option_1 < -1) || (symbol->option_1 > 8)) {
|
||||
strcpy(symbol->errtxt, "460: Security value out of range");
|
||||
errtxtf(0, symbol, 460, "Error correction level '%d' out of range (0 to 8)", symbol->option_1);
|
||||
if (symbol->warn_level == WARN_FAIL_ALL) {
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
}
|
||||
error_number = errtxt_adj(ZINT_WARN_INVALID_OPTION, symbol, "%1$s%2$s", ", ignoring");
|
||||
symbol->option_1 = -1;
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
}
|
||||
if ((symbol->option_2 < 0) || (symbol->option_2 > 30)) {
|
||||
strcpy(symbol->errtxt, "461: Number of columns out of range (1 to 30)");
|
||||
errtxtf(0, symbol, 461, "Number of columns '%d' out of range (1 to 30)", symbol->option_2);
|
||||
if (symbol->warn_level == WARN_FAIL_ALL) {
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
}
|
||||
error_number = errtxt_adj(ZINT_WARN_INVALID_OPTION, symbol, "%1$s%2$s", ", ignoring");
|
||||
symbol->option_2 = 0;
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
}
|
||||
if (symbol->option_3 && (symbol->option_3 < 3 || symbol->option_3 > 90)) {
|
||||
strcpy(symbol->errtxt, "466: Number of rows out of range (3 to 90)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 466, "Number of rows '%d' out of range (3 to 90)",
|
||||
symbol->option_3);
|
||||
}
|
||||
if (symbol->option_2 && symbol->option_3 && symbol->option_2 * symbol->option_3 > 928) {
|
||||
strcpy(symbol->errtxt, "475: Columns x rows out of range (1 to 928)");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 475, "Columns x rows value '%d' out of range (1 to 928)",
|
||||
symbol->option_2 * symbol->option_3);
|
||||
}
|
||||
|
||||
/* 349 */
|
||||
@ -1505,14 +1497,15 @@ INTERNAL int micropdf417(struct zint_symbol *symbol, struct zint_seg segs[], con
|
||||
int variant;
|
||||
int LeftRAP, CentreRAP, RightRAP, Cluster, loop;
|
||||
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
|
||||
/* From ISO/IEC 24728:2006 Table 1 — MicroPDF417 version characteristics */
|
||||
static char col_max_codewords[5] = { 0, 20, 37, 82, 126 };
|
||||
|
||||
if (segs_length(segs, seg_count) > MICRO_PDF_MAX_LEN) {
|
||||
strcpy(symbol->errtxt, "474: Input data too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
if ((i = segs_length(segs, seg_count)) > MICRO_PDF_MAX_LEN) {
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 474, "Input length %d too long (maximum " MICRO_PDF_MAX_LEN_S ")",
|
||||
i);
|
||||
}
|
||||
if (symbol->option_3) {
|
||||
strcpy(symbol->errtxt, "476: Cannot specify rows for MicroPDF417");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 476, "Cannot specify rows for MicroPDF417");
|
||||
}
|
||||
|
||||
/* Encoding starts out the same as PDF417, so use the same code */
|
||||
@ -1526,16 +1519,17 @@ INTERNAL int micropdf417(struct zint_symbol *symbol, struct zint_seg segs[], con
|
||||
/* This is where it all changes! */
|
||||
|
||||
if (mclength + structapp_cp > 126) {
|
||||
strcpy(symbol->errtxt, "467: Input data too long");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 467, "Input too long, requires %d codewords (maximum 126)",
|
||||
mclength + structapp_cp);
|
||||
}
|
||||
if (symbol->option_2 > 4) {
|
||||
strcpy(symbol->errtxt, "468: Specified width out of range");
|
||||
if (symbol->warn_level == WARN_FAIL_ALL) {
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 471, "Number of columns '%d' out of range (1 to 4)",
|
||||
symbol->option_2);
|
||||
}
|
||||
error_number = errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 468,
|
||||
"Number of columns '%d' out of range (1 to 4), ignoring", symbol->option_2);
|
||||
symbol->option_2 = 0;
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
}
|
||||
|
||||
if (debug_print) {
|
||||
@ -1550,34 +1544,16 @@ INTERNAL int micropdf417(struct zint_symbol *symbol, struct zint_seg segs[], con
|
||||
|
||||
variant = 0;
|
||||
|
||||
if ((symbol->option_2 == 1) && (mclength + structapp_cp > 20)) {
|
||||
/* the user specified 1 column but the data doesn't fit - go to automatic */
|
||||
strcpy(symbol->errtxt, "469: Specified symbol size too small for data");
|
||||
if (symbol->option_2 >= 1 && mclength + structapp_cp > col_max_codewords[symbol->option_2]) {
|
||||
/* The user specified the column but the data doesn't fit - go to automatic */
|
||||
if (symbol->warn_level == WARN_FAIL_ALL) {
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxtf(ZINT_ERROR_INVALID_OPTION, symbol, 469,
|
||||
"Input too long for number of columns '%1$d', requires %2$d codewords (maximum %3$d)",
|
||||
symbol->option_2, mclength + structapp_cp, col_max_codewords[symbol->option_2]);
|
||||
}
|
||||
error_number = errtxtf(ZINT_WARN_INVALID_OPTION, symbol, 470,
|
||||
"Input too long for number of columns '%d', ignoring", symbol->option_2);
|
||||
symbol->option_2 = 0;
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
}
|
||||
|
||||
if ((symbol->option_2 == 2) && (mclength + structapp_cp > 37)) {
|
||||
/* the user specified 2 columns but the data doesn't fit - go to automatic */
|
||||
strcpy(symbol->errtxt, "470: Specified symbol size too small for data");
|
||||
if (symbol->warn_level == WARN_FAIL_ALL) {
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
}
|
||||
symbol->option_2 = 0;
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
}
|
||||
|
||||
if ((symbol->option_2 == 3) && (mclength + structapp_cp > 82)) {
|
||||
/* the user specified 3 columns but the data doesn't fit - go to automatic */
|
||||
strcpy(symbol->errtxt, "471: Specified symbol size too small for data");
|
||||
if (symbol->warn_level == WARN_FAIL_ALL) {
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
}
|
||||
symbol->option_2 = 0;
|
||||
error_number = ZINT_WARN_INVALID_OPTION;
|
||||
}
|
||||
|
||||
if (symbol->option_2 == 1) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* pdf417.h - PDF417 tables and coefficients declarations */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
Portions Copyright (C) 2004 Grandzebu
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -36,6 +36,10 @@
|
||||
#ifndef Z_PDF417_H
|
||||
#define Z_PDF417_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* PDF417 error correction coefficients from Grand Zebu */
|
||||
INTERNAL_DATA_EXTERN const unsigned short pdf_coefrs[1022];
|
||||
|
||||
@ -57,7 +61,11 @@ INTERNAL_DATA_EXTERN const unsigned short pdf_rap_side[52];
|
||||
INTERNAL_DATA_EXTERN const unsigned short pdf_rap_centre[52];
|
||||
|
||||
INTERNAL void pdf_byteprocess(short *chainemc, int *p_mclength, const unsigned char chaine[], int start,
|
||||
const int length, const int lastmode, const int debug);
|
||||
const int length, const int lastmode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
#endif /* Z_PDF417_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* pdf417_tabs.h - PDF417 tables and coefficients */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
Portions Copyright (C) 2004 Grandzebu
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -39,6 +39,10 @@
|
||||
#ifndef Z_PDF417_TABS_H
|
||||
#define Z_PDF417_TABS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* PDF417 error correction coefficients from Grand Zebu */
|
||||
INTERNAL_DATA const unsigned short pdf_coefrs[1022] = {
|
||||
/* k = 2 */
|
||||
@ -510,5 +514,9 @@ INTERNAL_DATA const unsigned short pdf_rap_centre[52] = {
|
||||
0x2DC, 0x2DE
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
#endif /* Z_PDF417_TABS_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* plessey.c - Handles Plessey and MSI Plessey */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -62,12 +62,11 @@ INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
int error_number = 0;
|
||||
|
||||
if (length > 67) { /* 16 + 67 * 16 + 4 * 8 + 19 = 1139 */
|
||||
strcpy(symbol->errtxt, "370: Input too long (67 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 370, "Input length %d too long (maximum 67)", length);
|
||||
}
|
||||
if (!is_sane(SSET_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "371: Invalid character in data (digits and \"ABCDEF\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(SSET_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 371,
|
||||
"Invalid character at position %d in input (digits and \"ABCDEF\" only)", i);
|
||||
}
|
||||
|
||||
/* Start character */
|
||||
@ -123,7 +122,7 @@ INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
/* Modulo 10 check digit - Luhn algorithm
|
||||
See https://en.wikipedia.org/wiki/Luhn_algorithm */
|
||||
static char msi_check_digit_mod10(const unsigned char source[], const int length) {
|
||||
static const int vals[2][10] = {
|
||||
static const char vals[2][10] = {
|
||||
{ 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 }, /* Doubled and digits summed */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, /* Single */
|
||||
};
|
||||
@ -308,18 +307,18 @@ static char *msi_plessey_mod1110(struct zint_symbol *symbol, const unsigned char
|
||||
|
||||
INTERNAL int msi_plessey(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int error_number = 0;
|
||||
int i;
|
||||
char dest[766]; /* 2 + 92 * 8 + 3 * 8 + 3 + 1 = 766 */
|
||||
char *d = dest;
|
||||
int check_option = symbol->option_2;
|
||||
int no_checktext = 0;
|
||||
|
||||
if (length > 92) { /* 3 (Start) + 92 * 12 + 3 * 12 + 4 (Stop) = 1147 */
|
||||
strcpy(symbol->errtxt, "372: Input too long (92 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 372, "Input length %d too long (maximum 92)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "377: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 377,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
if (check_option >= 11 && check_option <= 16) { /* +10 means don't print check digits in HRT */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* png.c - Handles output to PNG file */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -35,16 +35,15 @@
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <png.h>
|
||||
#include <zlib.h>
|
||||
#include <setjmp.h>
|
||||
#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;
|
||||
@ -62,7 +61,7 @@ static void wpng_error_handler(png_structp png_ptr, png_const_charp msg) {
|
||||
fflush(stderr);
|
||||
return; /* libpng will call abort() */
|
||||
}
|
||||
sprintf(wpng_error_ptr->symbol->errtxt, "635: libpng error: %.60s", msg ? msg : "<NULL>");
|
||||
errtxtf(0, wpng_error_ptr->symbol, 635, "libpng error: %s", msg ? msg : "<NULL>");
|
||||
longjmp(wpng_error_ptr->jmpbuf, 1);
|
||||
}
|
||||
|
||||
@ -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,58 +211,40 @@ 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")) {
|
||||
return errtxtf(ZINT_ERROR_FILE_ACCESS, symbol, 632, "Could not open PNG output file (%1$d: %2$s)", fmp->err,
|
||||
strerror(fmp->err));
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
return ZINT_ERROR_MEMORY;
|
||||
(void) fm_close(fmp, symbol);
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 633, "Insufficient memory for PNG write structure buffer");
|
||||
}
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
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);
|
||||
}
|
||||
return ZINT_ERROR_MEMORY;
|
||||
(void) fm_close(fmp, symbol);
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 634, "Insufficient memory for PNG info structure buffer");
|
||||
}
|
||||
|
||||
/* 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 +311,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)) {
|
||||
errtxtf(0, symbol, 638, "Incomplete write of PNG output (%1$d: %2$s)", 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)) {
|
||||
return errtxtf(ZINT_ERROR_FILE_WRITE, symbol, 960, "Failure on closing PNG output file (%1$d: %2$s)",
|
||||
fmp->err, strerror(fmp->err));
|
||||
}
|
||||
|
||||
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 */
|
||||
|
170
backend/postal.c
@ -1,7 +1,7 @@
|
||||
/* postal.c - Handles POSTNET, PLANET, CEPNet, FIM. RM4SCC and Flattermarken */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
Including bug fixes by Bryan Hatton
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -99,18 +99,18 @@ static int usps_set_height(struct zint_symbol *symbol, const int no_errtxt) {
|
||||
*/
|
||||
/* CEPNet e Código Bidimensional Datamatrix 2D (26/05/2021) 3.3.2 Arquitetura das barras - same as POSTNET */
|
||||
int error_number = 0;
|
||||
float h_ratio; /* Half ratio */
|
||||
|
||||
/* No legacy for CEPNet as new */
|
||||
if ((symbol->output_options & COMPLIANT_HEIGHT) || symbol->symbology == BARCODE_CEPNET) {
|
||||
symbol->row_height[0] = stripf(0.075f * 43); /* 3.225 */
|
||||
symbol->row_height[1] = stripf(0.05f * 43); /* 2.15 */
|
||||
symbol->row_height[0] = 3.2249999f; /* 0.075 * 43 */
|
||||
symbol->row_height[1] = 2.1500001f; /* 0.05 * 43 */
|
||||
} else {
|
||||
symbol->row_height[0] = 6.0f;
|
||||
symbol->row_height[1] = 6.0f;
|
||||
}
|
||||
if (symbol->height) {
|
||||
h_ratio = symbol->row_height[1] / (symbol->row_height[0] + symbol->row_height[1]); /* 0.4 */
|
||||
/* Half ratio */
|
||||
const float h_ratio = symbol->row_height[1] / (symbol->row_height[0] + symbol->row_height[1]); /* 0.4 */
|
||||
symbol->row_height[1] = stripf(symbol->height * h_ratio);
|
||||
if (symbol->row_height[1] < 0.5f) { /* Absolute minimum */
|
||||
symbol->row_height[1] = 0.5f;
|
||||
@ -125,7 +125,7 @@ static int usps_set_height(struct zint_symbol *symbol, const int no_errtxt) {
|
||||
if (symbol->height < 4.6f || symbol->height > 9.0f) {
|
||||
error_number = ZINT_WARN_NONCOMPLIANT;
|
||||
if (!no_errtxt) {
|
||||
strcpy(symbol->errtxt, "498: Height not compliant with standards");
|
||||
errtxt(0, symbol, 498, "Height not compliant with standards");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,31 +135,31 @@ static int usps_set_height(struct zint_symbol *symbol, const int no_errtxt) {
|
||||
|
||||
/* Handles the POSTNET system used for Zip codes in the US */
|
||||
/* Also handles Brazilian CEPNet - more information CEPNet e Código Bidimensional Datamatrix 2D (26/05/2021) at
|
||||
* https://www.correios.com.br/enviar/correspondencia/arquivos/nacional/guia-tecnico-cepnet-e-2d-triagem-enderecamento-27-04-2021.pdf/view
|
||||
https://www.correios.com.br/enviar/correspondencia/arquivos/nacional/
|
||||
guia-tecnico-cepnet-e-2d-triagem-enderecamento-27-04-2021.pdf/view
|
||||
*/
|
||||
static int postnet_enc(struct zint_symbol *symbol, const unsigned char source[], char *d, const int length) {
|
||||
int i, sum, check_digit;
|
||||
int error_number = 0;
|
||||
|
||||
if (length > 38) {
|
||||
strcpy(symbol->errtxt, "480: Input too long (38 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 480, "Input length %d too long (maximum 38)", length);
|
||||
}
|
||||
|
||||
if (symbol->symbology == BARCODE_CEPNET) {
|
||||
if (length != 8) {
|
||||
strcpy(symbol->errtxt, "780: Input is wrong length (should be 8 digits)");
|
||||
error_number = ZINT_WARN_NONCOMPLIANT;
|
||||
error_number = errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 780, "Input length %d wrong (should be 8 digits)",
|
||||
length);
|
||||
}
|
||||
} else {
|
||||
if (length != 5 && length != 9 && length != 11) {
|
||||
strcpy(symbol->errtxt, "479: Input length is not standard (5, 9 or 11 characters)");
|
||||
error_number = ZINT_WARN_NONCOMPLIANT;
|
||||
error_number = errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 479,
|
||||
"Input length %d is not standard (5, 9 or 11)", length);
|
||||
}
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "481: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 481,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
sum = 0;
|
||||
|
||||
@ -186,7 +186,8 @@ static int postnet_enc(struct zint_symbol *symbol, const unsigned char source[],
|
||||
|
||||
/* Puts POSTNET barcodes into the pattern matrix */
|
||||
INTERNAL int postnet(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
|
||||
/* Suppress clang-tidy-20 garbage value false positive by initializing (see "vector.c" `vection_add_rect()`) */
|
||||
char height_pattern[256] = {0}; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
|
||||
unsigned int loopey, h;
|
||||
int writer;
|
||||
int error_number, warn_number;
|
||||
@ -218,16 +219,15 @@ static int planet_enc(struct zint_symbol *symbol, const unsigned char source[],
|
||||
int error_number = 0;
|
||||
|
||||
if (length > 38) {
|
||||
strcpy(symbol->errtxt, "482: Input too long (38 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 482, "Input length %d too long (maximum 38)", length);
|
||||
}
|
||||
if (length != 11 && length != 13) {
|
||||
strcpy(symbol->errtxt, "478: Input length is not standard (11 or 13 characters)");
|
||||
error_number = ZINT_WARN_NONCOMPLIANT;
|
||||
error_number = errtxtf(ZINT_WARN_NONCOMPLIANT, symbol, 478, "Input length %d is not standard (11 or 13)",
|
||||
length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "483: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 483,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
sum = 0;
|
||||
|
||||
@ -254,7 +254,8 @@ static int planet_enc(struct zint_symbol *symbol, const unsigned char source[],
|
||||
|
||||
/* Puts PLANET barcodes into the pattern matrix */
|
||||
INTERNAL int planet(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
|
||||
/* Suppress clang-tidy-20 garbage value false positive by initializing (see "vector.c" `vection_add_rect()`) */
|
||||
char height_pattern[256] = {0}; /* 5 + 38 * 5 + 5 + 5 + 1 = 206 */
|
||||
unsigned int loopey, h;
|
||||
int writer;
|
||||
int error_number, warn_number;
|
||||
@ -282,27 +283,26 @@ INTERNAL int planet(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
|
||||
/* Korean Postal Authority */
|
||||
INTERNAL int koreapost(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int total, loop, check, zeroes, error_number = 0;
|
||||
int total, i, check, zeroes, error_number = 0;
|
||||
char localstr[8], dest[80];
|
||||
char *d = dest;
|
||||
int posns[6];
|
||||
|
||||
if (length > 6) {
|
||||
strcpy(symbol->errtxt, "484: Input too long (6 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 484, "Input length %d too long (maximum 6)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "485: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 485,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
zeroes = 6 - length;
|
||||
memset(localstr, '0', zeroes);
|
||||
ustrcpy(localstr + zeroes, source);
|
||||
|
||||
total = 0;
|
||||
for (loop = 0; loop < 6; loop++) {
|
||||
posns[loop] = ctoi(localstr[loop]);
|
||||
total += posns[loop];
|
||||
for (i = 0; i < 6; i++) {
|
||||
posns[i] = ctoi(localstr[i]);
|
||||
total += posns[i];
|
||||
}
|
||||
check = 10 - (total % 10);
|
||||
if (check == 10) {
|
||||
@ -311,8 +311,8 @@ INTERNAL int koreapost(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
localstr[6] = itoc(check);
|
||||
localstr[7] = '\0';
|
||||
|
||||
for (loop = 5; loop >= 0; loop--) {
|
||||
const char *const entry = KoreaTable[posns[loop]];
|
||||
for (i = 5; i >= 0; i--) {
|
||||
const char *const entry = KoreaTable[posns[i]];
|
||||
memcpy(d, entry, 10);
|
||||
d += entry[8] ? 10 : 8;
|
||||
}
|
||||
@ -334,8 +334,7 @@ INTERNAL int fim(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
int error_number = 0;
|
||||
|
||||
if (length > 1) {
|
||||
strcpy(symbol->errtxt, "486: Input too long (1 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 486, "Input length %d too long (maximum 1)", length);
|
||||
}
|
||||
|
||||
switch ((char) source[0]) {
|
||||
@ -360,16 +359,18 @@ INTERNAL int fim(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
expand(symbol, "1317131", 7);
|
||||
break;
|
||||
default:
|
||||
strcpy(symbol->errtxt, "487: Invalid character in data (\"A\", \"B\", \"C\", \"D\" or \"E\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 487,
|
||||
"Invalid character in input (\"A\", \"B\", \"C\", \"D\" or \"E\" only)");
|
||||
break;
|
||||
}
|
||||
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* USPS Domestic Mail Manual (USPS DMM 300) Jan 8, 2006 (updated 2011) 708.9.3
|
||||
X 0.03125" (1/32) +- 0.008" so X max 0.03925", height 0.625" (5/8) +- 0.125" (1/8) */
|
||||
error_number = set_height(symbol, stripf(0.5f / 0.03925f), 20.0f /*0.625 / 0.03125*/,
|
||||
stripf(0.75f / 0.02415f), 0 /*no_errtxt*/);
|
||||
const float min_height = 12.7388535f; /* 0.5 / 0.03925 */
|
||||
const float default_height = 20.0f; /* 0.625 / 0.03125 */
|
||||
const float max_height = 31.0559006f; /* 0.75 / 0.02415 */
|
||||
error_number = set_height(symbol, min_height, default_height, max_height, 0 /*no_errtxt*/);
|
||||
} else {
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
@ -381,10 +382,11 @@ INTERNAL int fim(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
/* Used by auspost.c also */
|
||||
INTERNAL int daft_set_height(struct zint_symbol *symbol, const float min_height, const float max_height) {
|
||||
int error_number = 0;
|
||||
float t_ratio; /* Tracker ratio */
|
||||
|
||||
if (symbol->height) {
|
||||
t_ratio = stripf(symbol->row_height[1] / stripf(symbol->row_height[0] * 2 + symbol->row_height[1]));
|
||||
/* Tracker ratio */
|
||||
const float t_ratio = stripf(symbol->row_height[1] / stripf(symbol->row_height[0] * 2
|
||||
+ symbol->row_height[1]));
|
||||
symbol->row_height[1] = stripf(symbol->height * t_ratio);
|
||||
if (symbol->row_height[1] < 0.5f) { /* Absolute minimum */
|
||||
symbol->row_height[1] = 0.5f;
|
||||
@ -402,8 +404,7 @@ INTERNAL int daft_set_height(struct zint_symbol *symbol, const float min_height,
|
||||
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
if ((min_height && symbol->height < min_height) || (max_height && symbol->height > max_height)) {
|
||||
error_number = ZINT_WARN_NONCOMPLIANT;
|
||||
strcpy(symbol->errtxt, "499: Height not compliant with standards");
|
||||
error_number = errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 499, "Height not compliant with standards");
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,6 +450,7 @@ static void rm4scc_enc(const struct zint_symbol *symbol, const int *posns, char
|
||||
|
||||
/* Puts RM4SCC into the data matrix */
|
||||
INTERNAL int rm4scc(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int i;
|
||||
char height_pattern[210];
|
||||
int posns[50];
|
||||
int loopey, h;
|
||||
@ -456,13 +458,12 @@ INTERNAL int rm4scc(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
int error_number = 0;
|
||||
|
||||
if (length > 50) {
|
||||
strcpy(symbol->errtxt, "488: Input too long (50 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 488, "Input length %d too long (maximum 50)", length);
|
||||
}
|
||||
to_upper(source, length);
|
||||
if (!is_sane_lookup(KRSET, 36, source, length, posns)) {
|
||||
strcpy(symbol->errtxt, "489: Invalid character in data (alphanumerics only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane_lookup(KRSET, 36, source, length, posns))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 489,
|
||||
"Invalid character at position %d in input (alphanumerics only)", i);
|
||||
}
|
||||
rm4scc_enc(symbol, posns, height_pattern, length);
|
||||
|
||||
@ -486,10 +487,12 @@ INTERNAL int rm4scc(struct zint_symbol *symbol, unsigned char source[], int leng
|
||||
Bar pitch and min/maxes same as Mailmark, so using recommendations from
|
||||
Royal Mail Mailmark Barcode Definition Document (15 Sept 2015) Section 3.5.1
|
||||
*/
|
||||
symbol->row_height[0] = stripf((1.9f * 42.3f) / 25.4f); /* ~3.16 */
|
||||
symbol->row_height[1] = stripf((1.3f * 42.3f) / 25.4f); /* ~2.16 */
|
||||
const float min_height = 6.47952747f; /* (4.22 * 39) / 25.4 */
|
||||
const float max_height = 10.8062992f; /* (5.84 * 47) / 25.4 */
|
||||
symbol->row_height[0] = 3.16417313f; /* (1.9 * 42.3) / 25.4 */
|
||||
symbol->row_height[1] = 2.16496062f; /* (1.3 * 42.3) / 25.4 */
|
||||
/* Note using max X for minimum and min X for maximum */
|
||||
error_number = daft_set_height(symbol, stripf((4.22f * 39) / 25.4f), stripf((5.84f * 47) / 25.4f));
|
||||
error_number = daft_set_height(symbol, min_height, max_height);
|
||||
} else {
|
||||
symbol->row_height[0] = 3.0f;
|
||||
symbol->row_height[1] = 2.0f;
|
||||
@ -513,13 +516,12 @@ INTERNAL int kix(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
int error_number = 0;
|
||||
|
||||
if (length > 18) {
|
||||
strcpy(symbol->errtxt, "490: Input too long (18 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 490, "Input length %d too long (maximum 18)", length);
|
||||
}
|
||||
to_upper(source, length);
|
||||
if (!is_sane_lookup(KRSET, 36, source, length, posns)) {
|
||||
strcpy(symbol->errtxt, "491: Invalid character in data (alphanumerics only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane_lookup(KRSET, 36, source, length, posns))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 491,
|
||||
"Invalid character at position %d in input (alphanumerics only)", i);
|
||||
}
|
||||
|
||||
/* Encode data */
|
||||
@ -542,10 +544,12 @@ INTERNAL int kix(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* Dimensions same as RM4SCC */
|
||||
symbol->row_height[0] = stripf((1.9f * 42.3f) / 25.4f); /* ~3.16 */
|
||||
symbol->row_height[1] = stripf((1.3f * 42.3f) / 25.4f); /* ~2.16 */
|
||||
const float min_height = 6.47952747f; /* (4.22 * 39) / 25.4 */
|
||||
const float max_height = 10.8062992f; /* (5.84 * 47) / 25.4 */
|
||||
symbol->row_height[0] = 3.16417313f; /* (1.9 * 42.3) / 25.4 */
|
||||
symbol->row_height[1] = 2.16496062f; /* (1.3 * 42.3) / 25.4 */
|
||||
/* Note using max X for minimum and min X for maximum */
|
||||
error_number = daft_set_height(symbol, stripf((4.22f * 39) / 25.4f), stripf((5.84f * 47) / 25.4f));
|
||||
error_number = daft_set_height(symbol, min_height, max_height);
|
||||
} else {
|
||||
symbol->row_height[0] = 3.0f;
|
||||
symbol->row_height[1] = 2.0f;
|
||||
@ -559,19 +563,19 @@ INTERNAL int kix(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
|
||||
/* Handles DAFT Code symbols */
|
||||
INTERNAL int daft(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int i;
|
||||
int posns[576];
|
||||
int loopey;
|
||||
int writer;
|
||||
|
||||
if (length > 576) { /* 576 * 2 = 1152 */
|
||||
strcpy(symbol->errtxt, "492: Input too long (576 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 492, "Input length %d too long (maximum 576)", length);
|
||||
}
|
||||
to_upper(source, length);
|
||||
|
||||
if (!is_sane_lookup(DAFTSET, 4, source, length, posns)) {
|
||||
strcpy(symbol->errtxt, "493: Invalid character in data (\"D\", \"A\", \"F\" and \"T\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane_lookup(DAFTSET, 4, source, length, posns))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 493,
|
||||
"Invalid character at position %d in input (\"D\", \"A\", \"F\" and \"T\" only)", i);
|
||||
}
|
||||
|
||||
writer = 0;
|
||||
@ -609,21 +613,20 @@ INTERNAL int daft(struct zint_symbol *symbol, unsigned char source[], int length
|
||||
|
||||
/* Flattermarken - Not really a barcode symbology! */
|
||||
INTERNAL int flat(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int loop, error_number = 0;
|
||||
int i, error_number = 0;
|
||||
char dest[512]; /* 128 * 4 = 512 */
|
||||
char *d = dest;
|
||||
|
||||
if (length > 128) { /* 128 * 9 = 1152 */
|
||||
strcpy(symbol->errtxt, "494: Input too long (128 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 494, "Input length %d too long (maximum 128)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "495: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 495,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
for (loop = 0; loop < length; loop++) {
|
||||
const char *const entry = FlatTable[source[loop] - '0'];
|
||||
for (i = 0; i < length; i++) {
|
||||
const char *const entry = FlatTable[source[i] - '0'];
|
||||
memcpy(d, entry, 4);
|
||||
d += entry[2] ? 4 : 2;
|
||||
}
|
||||
@ -645,15 +648,14 @@ INTERNAL int japanpost(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
char inter[20 + 1];
|
||||
|
||||
if (length > 20) {
|
||||
strcpy(symbol->errtxt, "496: Input too long (20 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 496, "Input length %d too long (maximum 20)", length);
|
||||
}
|
||||
|
||||
to_upper(source, length);
|
||||
|
||||
if (!is_sane(SHKASUTSET_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "497: Invalid character in data (alphanumerics and \"-\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(SHKASUTSET_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 497,
|
||||
"Invalid character at position %d in input (alphanumerics and \"-\" only)", i);
|
||||
}
|
||||
memset(inter, 'd', 20); /* Pad character CC4 */
|
||||
inter[20] = '\0';
|
||||
@ -681,8 +683,8 @@ INTERNAL int japanpost(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
} while ((i < length) && (inter_posn < 20));
|
||||
|
||||
if (i != length || inter[20] != '\0') {
|
||||
strcpy(symbol->errtxt, "477: Input too long (20 symbol character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxt(ZINT_ERROR_TOO_LONG, symbol, 477,
|
||||
"Input too long, requires too many symbol characters (maximum 20)");
|
||||
}
|
||||
|
||||
memcpy(d, "13", 2); /* Start */
|
||||
@ -736,9 +738,11 @@ INTERNAL int japanpost(struct zint_symbol *symbol, unsigned char source[], int l
|
||||
X 0.6mm (0.5mm - 0.7mm)
|
||||
Tracker height 1.2mm (1.05mm - 1.35mm) / 0.6mm = 2,
|
||||
Ascender/descender = 1.2mm (Full 3.6mm (3.4mm - 3.6mm, max preferred) less T divided by 2) / 0.6mm = 2 */
|
||||
const float min_height = 4.85714293f; /* 3.4 / 0.7 */
|
||||
const float max_height = 7.19999981f; /* 3.6 / 0.5 */
|
||||
symbol->row_height[0] = 2.0f;
|
||||
symbol->row_height[1] = 2.0f;
|
||||
error_number = daft_set_height(symbol, stripf(3.4f / 0.7f) /*~4.857*/, stripf(3.6f / 0.5f) /*7.2*/);
|
||||
error_number = daft_set_height(symbol, min_height, max_height);
|
||||
} else {
|
||||
symbol->row_height[0] = 3.0f;
|
||||
symbol->row_height[1] = 2.0f;
|
||||
|
246
backend/ps.c
@ -1,7 +1,7 @@
|
||||
/* ps.c - Post Script output */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -35,10 +35,11 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#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,14 +170,14 @@ 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` */
|
||||
float red_paper = 0.0f, green_paper = 0.0f, blue_paper = 0.0f;
|
||||
float cyan_ink = 0.0f, magenta_ink = 0.0f, yellow_ink = 0.0f, black_ink = 0.0f;
|
||||
float cyan_paper = 0.0f, magenta_paper = 0.0f, yellow_paper = 0.0f, black_paper = 0.0f;
|
||||
int error_number = 0;
|
||||
float previous_diameter;
|
||||
float radius;
|
||||
int colour_rect_flag;
|
||||
@ -190,21 +192,14 @@ 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;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 646, "Vector header NULL");
|
||||
}
|
||||
|
||||
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")) {
|
||||
return errtxtf(ZINT_ERROR_FILE_ACCESS, symbol, 645, "Could not open EPS output file (%1$d: %2$s)", fmp->err,
|
||||
strerror(fmp->err));
|
||||
}
|
||||
|
||||
if (is_rgb) {
|
||||
@ -266,52 +261,52 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
|
||||
}
|
||||
|
||||
/* Start writing the header */
|
||||
fputs("%!PS-Adobe-3.0 EPSF-3.0\n", feps);
|
||||
if (ZINT_VERSION_BUILD) {
|
||||
fprintf(feps, "%%%%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);
|
||||
}
|
||||
fputs("%%Title: Zint Generated Symbol\n"
|
||||
"%%Pages: 0\n", feps);
|
||||
fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n",
|
||||
(int) ceilf(symbol->vector->width), (int) ceilf(symbol->vector->height));
|
||||
fputs("%%EndComments\n", feps);
|
||||
fm_puts("%!PS-Adobe-3.0 EPSF-3.0\n"
|
||||
"%%Creator: Zint ", fmp);
|
||||
#if ZINT_VERSION_BUILD
|
||||
fm_printf(fmp, "%d.%d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE, ZINT_VERSION_BUILD);
|
||||
#else
|
||||
fm_printf(fmp, "%d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE);
|
||||
#endif
|
||||
fm_puts("%%Title: Zint Generated Symbol\n"
|
||||
"%%Pages: 0\n"
|
||||
"%%BoundingBox: 0 0 ", fmp);
|
||||
fm_printf(fmp, "%d %d\n", (int) ceilf(symbol->vector->width), (int) ceilf(symbol->vector->height));
|
||||
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 +314,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 +357,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 +380,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 +395,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 +420,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,73 +460,64 @@ 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)) {
|
||||
errtxtf(0, symbol, 647, "Incomplete write of EPS output (%1$d: %2$s)", 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)) {
|
||||
return errtxtf(ZINT_ERROR_FILE_WRITE, symbol, 649, "Failure on closing EPS output file (%1$d: %2$s)",
|
||||
fmp->err, strerror(fmp->err));
|
||||
}
|
||||
|
||||
return error_number;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
958
backend/qr.c
349
backend/qr.h
@ -1,7 +1,7 @@
|
||||
/* qr.h Data for QR Code, Micro QR Code and rMQR */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2006 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -34,96 +34,100 @@
|
||||
#ifndef Z_QR_H
|
||||
#define Z_QR_H
|
||||
|
||||
/* From ISO/IEC 18004:2015 Table 5 Encoding/decoding table for Alphanumeric mode */
|
||||
static const char qr_alphanumeric[59] = {
|
||||
/* From ISO/IEC 18004:2015 Table 5 - Encoding/decoding table for Alphanumeric mode */
|
||||
static const signed char qr_alphanumeric[59] = {
|
||||
36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, /* SP-/ */
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, /* 0-? */
|
||||
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* @-O */
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 /* P-Z */
|
||||
};
|
||||
|
||||
/* From ISO/IEC 18004:2015 Table 7 */
|
||||
static const unsigned short qr_data_codewords_L[] = {
|
||||
19, 34, 55, 80, 108, 136, 156, 194, 232, 274, 324, 370, 428, 461, 523, 589, 647,
|
||||
721, 795, 861, 932, 1006, 1094, 1174, 1276, 1370, 1468, 1531, 1631,
|
||||
1735, 1843, 1955, 2071, 2191, 2306, 2434, 2566, 2702, 2812, 2956
|
||||
/* From ISO/IEC 18004:2015 Table 7 - Number of symbol characters and input data capacity for QR Code */
|
||||
static const unsigned short qr_data_codewords[4][40] = { {
|
||||
19, 34, 55, 80, 108, 136, 156, 194, 232, 274, /* L */
|
||||
324, 370, 428, 461, 523, 589, 647, 721, 795, 861,
|
||||
932, 1006, 1094, 1174, 1276, 1370, 1468, 1531, 1631, 1735,
|
||||
1843, 1955, 2071, 2191, 2306, 2434, 2566, 2702, 2812, 2956
|
||||
}, {
|
||||
16, 28, 44, 64, 86, 108, 124, 154, 182, 216, /* M */
|
||||
254, 290, 334, 365, 415, 453, 507, 563, 627, 669,
|
||||
714, 782, 860, 914, 1000, 1062, 1128, 1193, 1267, 1373,
|
||||
1455, 1541, 1631, 1725, 1812, 1914, 1992, 2102, 2216, 2334
|
||||
}, {
|
||||
13, 22, 34, 48, 62, 76, 88, 110, 132, 154, /* Q */
|
||||
180, 206, 244, 261, 295, 325, 367, 397, 445, 485,
|
||||
512, 568, 614, 664, 718, 754, 808, 871, 911, 985,
|
||||
1033, 1115, 1171, 1231, 1286, 1354, 1426, 1502, 1582, 1666
|
||||
}, {
|
||||
9, 16, 26, 36, 46, 60, 66, 86, 100, 122, /* H */
|
||||
140, 158, 180, 197, 223, 253, 283, 313, 341, 385,
|
||||
406, 442, 464, 514, 538, 596, 628, 661, 701, 745,
|
||||
793, 845, 901, 961, 986, 1054, 1096, 1142, 1222, 1276
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned short qr_data_codewords_M[] = {
|
||||
16, 28, 44, 64, 86, 108, 124, 154, 182, 216, 254, 290, 334, 365, 415, 453, 507,
|
||||
563, 627, 669, 714, 782, 860, 914, 1000, 1062, 1128, 1193, 1267,
|
||||
1373, 1455, 1541, 1631, 1725, 1812, 1914, 1992, 2102, 2216, 2334
|
||||
/* From ISO/IEC 18004:2015 Table 1 - Codeword capacity of all versions of QRCode */
|
||||
static const unsigned short qr_total_codewords[40] = {
|
||||
26, 44, 70, 100, 134, 172, 196, 242, 292, 346,
|
||||
404, 466, 532, 581, 655, 733, 815, 901, 991, 1085,
|
||||
1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 2185,
|
||||
2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706
|
||||
};
|
||||
|
||||
static const unsigned short qr_data_codewords_Q[] = {
|
||||
13, 22, 34, 48, 62, 76, 88, 110, 132, 154, 180, 206, 244, 261, 295, 325, 367,
|
||||
397, 445, 485, 512, 568, 614, 664, 718, 754, 808, 871, 911,
|
||||
985, 1033, 1115, 1171, 1231, 1286, 1354, 1426, 1502, 1582, 1666
|
||||
};
|
||||
|
||||
static const unsigned short qr_data_codewords_H[] = {
|
||||
9, 16, 26, 36, 46, 60, 66, 86, 100, 122, 140, 158, 180, 197, 223, 253, 283,
|
||||
313, 341, 385, 406, 442, 464, 514, 538, 596, 628, 661, 701,
|
||||
745, 793, 845, 901, 961, 986, 1054, 1096, 1142, 1222, 1276
|
||||
};
|
||||
|
||||
static const unsigned short qr_total_codewords[] = {
|
||||
26, 44, 70, 100, 134, 172, 196, 242, 292, 346, 404, 466, 532, 581, 655, 733, 815,
|
||||
901, 991, 1085, 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051,
|
||||
2185, 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706
|
||||
};
|
||||
|
||||
static const unsigned short rmqr_height[] = {
|
||||
7, 7, 7, 7, 7,
|
||||
9, 9, 9, 9, 9,
|
||||
/* From ISO/IEC 23941:2022 Table 1 - Codeword capacity of all versions of rMQR symbols */
|
||||
static const unsigned char rmqr_height[32] = {
|
||||
7, 7, 7, 7, 7,
|
||||
9, 9, 9, 9, 9,
|
||||
11, 11, 11, 11, 11, 11,
|
||||
13, 13, 13, 13, 13, 13,
|
||||
15, 15, 15, 15, 15,
|
||||
17, 17, 17, 17, 17
|
||||
};
|
||||
|
||||
static const unsigned short rmqr_width[] = {
|
||||
static const unsigned char rmqr_width[32] = {
|
||||
43, 59, 77, 99, 139,
|
||||
43, 59, 77, 99, 139,
|
||||
27, 43, 59, 77, 99, 139,
|
||||
27, 43, 59, 77, 99, 139,
|
||||
27, 43, 59, 77, 99, 139,
|
||||
27, 43, 59, 77, 99, 139,
|
||||
43, 59, 77, 99, 139,
|
||||
43, 59, 77, 99, 139
|
||||
};
|
||||
|
||||
static const unsigned short rmqr_data_codewords_M[] = {
|
||||
6, 12, 20, 28, 44, /* R7x */
|
||||
12, 21, 31, 42, 63, /* R9x */
|
||||
7, 19, 31, 43, 57, 84, /* R11x */
|
||||
12, 27, 38, 53, 73, 106, /* R13x */
|
||||
33, 48, 67, 88, 127, /* R15x */
|
||||
39, 56, 78, 100, 152 /* R17x */
|
||||
/* From ISO/IEC 23941:2022 Table 6 - Number of data codewords and input data capacity for rMQR */
|
||||
static const unsigned char rmqr_data_codewords[2][32] = { {
|
||||
6, 12, 20, 28, 44, /* R7x */ /* M */
|
||||
12, 21, 31, 42, 63, /* R9x */
|
||||
7, 19, 31, 43, 57, 84, /* R11x */
|
||||
12, 27, 38, 53, 73, 106, /* R13x */
|
||||
33, 48, 67, 88, 127, /* R15x */
|
||||
39, 56, 78, 100, 152 /* R17x */
|
||||
}, {
|
||||
3, 7, 10, 14, 24, /* R7x */ /* H */
|
||||
7, 11, 17, 22, 33, /* R9x */
|
||||
5, 11, 15, 23, 29, 42, /* R11x */
|
||||
7, 13, 20, 29, 35, 54, /* R13x */
|
||||
15, 26, 31, 48, 69, /* R15x */
|
||||
21, 28, 38, 56, 76 /* R17x */
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned short rmqr_data_codewords_H[] = {
|
||||
3, 7, 10, 14, 24, /* R7x */
|
||||
7, 11, 17, 22, 33, /* R9x */
|
||||
5, 11, 15, 23, 29, 42, /* R11x */
|
||||
7, 13, 20, 29, 35, 54, /* R13x */
|
||||
15, 26, 31, 48, 69, /* R15x */
|
||||
21, 28, 38, 56, 76 /* R17x */
|
||||
};
|
||||
|
||||
static const short rmqr_fixed_height_upper_bound[] = {
|
||||
/* Highest index in `rmqr_total_codewords` for each given row (R7x, R9x etc) */
|
||||
static const signed char rmqr_fixed_height_upper_bound[7] = {
|
||||
-1, 4, 9, 15, 21, 26, 31
|
||||
};
|
||||
|
||||
static const unsigned short rmqr_total_codewords[] = {
|
||||
13, 21, 32, 44, 68, /* R7x */
|
||||
21, 33, 49, 66, 99, /* R9x */
|
||||
15, 31, 47, 67, 89, 132, /* R11x */
|
||||
21, 41, 60, 85, 113, 166, /* R13x */
|
||||
/* From ISO/IEC 23941:2022 Table 1 - Codeword capacity of all versions of rMQR symbols */
|
||||
static const unsigned char rmqr_total_codewords[32] = {
|
||||
13, 21, 32, 44, 68, /* R7x */
|
||||
21, 33, 49, 66, 99, /* R9x */
|
||||
15, 31, 47, 67, 89, 132, /* R11x */
|
||||
21, 41, 60, 85, 113, 166, /* R13x */
|
||||
51, 74, 103, 136, 199, /* R15x */
|
||||
61, 88, 122, 160, 232 /* R17x */
|
||||
};
|
||||
|
||||
|
||||
static const unsigned short rmqr_numeric_cci[] = {
|
||||
/* From ISO/IEC 23941:2022 Table 3 - Number of bits of character count indicator */
|
||||
static const unsigned char rmqr_numeric_cci[32] = {
|
||||
4, 5, 6, 7, 7,
|
||||
5, 6, 7, 7, 8,
|
||||
4, 6, 7, 7, 8, 8,
|
||||
@ -132,7 +136,7 @@ static const unsigned short rmqr_numeric_cci[] = {
|
||||
7, 8, 8, 8, 9
|
||||
};
|
||||
|
||||
static const unsigned short rmqr_alphanum_cci[] = {
|
||||
static const unsigned char rmqr_alphanum_cci[32] = {
|
||||
3, 5, 5, 6, 6,
|
||||
5, 5, 6, 6, 7,
|
||||
4, 5, 6, 6, 7, 7,
|
||||
@ -141,7 +145,7 @@ static const unsigned short rmqr_alphanum_cci[] = {
|
||||
6, 7, 7, 8, 8
|
||||
};
|
||||
|
||||
static const unsigned short rmqr_byte_cci[] = {
|
||||
static const unsigned char rmqr_byte_cci[32] = {
|
||||
3, 4, 5, 5, 6,
|
||||
4, 5, 5, 6, 6,
|
||||
3, 5, 5, 6, 6, 7,
|
||||
@ -150,7 +154,7 @@ static const unsigned short rmqr_byte_cci[] = {
|
||||
6, 6, 7, 7, 8
|
||||
};
|
||||
|
||||
static const unsigned short rmqr_kanji_cci[] = {
|
||||
static const unsigned char rmqr_kanji_cci[32] = {
|
||||
2, 3, 4, 5, 5,
|
||||
3, 4, 5, 5, 6,
|
||||
2, 4, 5, 5, 6, 6,
|
||||
@ -159,92 +163,115 @@ static const unsigned short rmqr_kanji_cci[] = {
|
||||
5, 6, 6, 6, 7
|
||||
};
|
||||
|
||||
static const char qr_blocks_L[] = {
|
||||
1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12,
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25
|
||||
/* From ISO/IEC 18004:2015 Table 9 - Error correction characteristics for QR Code */
|
||||
static const char qr_blocks[4][40] = { {
|
||||
1, 1, 1, 1, 1, 2, 2, 2, 2, 4, /* L */
|
||||
4, 4, 4, 4, 6, 6, 6, 6, 7, 8,
|
||||
8, 9, 9, 10, 12, 12, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 19, 20, 21, 22, 24, 25
|
||||
}, {
|
||||
1, 1, 1, 2, 2, 4, 4, 4, 5, 5, /* M */
|
||||
5, 8, 9, 9, 10, 10, 11, 13, 14, 16,
|
||||
17, 17, 18, 20, 21, 23, 25, 26, 28, 29,
|
||||
31, 33, 35, 37, 38, 40, 43, 45, 47, 49
|
||||
}, {
|
||||
1, 1, 2, 2, 4, 4, 6, 6, 8, 8, /* Q */
|
||||
8, 10, 12, 16, 12, 17, 16, 18, 21, 20,
|
||||
23, 23, 25, 27, 29, 34, 34, 35, 38, 40,
|
||||
43, 45, 48, 51, 53, 56, 59, 62, 65, 68
|
||||
}, {
|
||||
1, 1, 2, 4, 4, 4, 5, 6, 8, 8, /* H */
|
||||
11, 11, 16, 16, 18, 16, 19, 21, 25, 25,
|
||||
25, 34, 30, 32, 35, 37, 40, 42, 45, 48,
|
||||
51, 54, 57, 60, 63, 66, 70, 74, 77, 81
|
||||
}
|
||||
};
|
||||
|
||||
static const char qr_blocks_M[] = {
|
||||
1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20,
|
||||
21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49
|
||||
/* From ISO/IEC 23941:2022 Table 8 - Error correction characteristics for rMQR */
|
||||
static const char rmqr_blocks[2][32] = { {
|
||||
1, 1, 1, 1, 1, /* R7x */ /* M */
|
||||
1, 1, 1, 1, 2, /* R9x */
|
||||
1, 1, 1, 1, 2, 2, /* R11x */
|
||||
1, 1, 1, 2, 2, 3, /* R13x */
|
||||
1, 1, 2, 2, 3, /* R15x */
|
||||
1, 2, 2, 3, 4 /* R17x */
|
||||
}, {
|
||||
1, 1, 1, 1, 2, /* R7x */ /* H */
|
||||
1, 1, 2, 2, 3, /* R9x */
|
||||
1, 1, 2, 2, 2, 3, /* R11x */
|
||||
1, 1, 2, 2, 3, 4, /* R13x */
|
||||
2, 2, 3, 4, 5, /* R15x */
|
||||
2, 2, 3, 4, 6 /* R17x */
|
||||
}
|
||||
};
|
||||
|
||||
static const char qr_blocks_Q[] = {
|
||||
1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25,
|
||||
27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68
|
||||
/* From ISO/IEC 18004:2015 Table 1 - Codeword capacity of all versions of QR Code */
|
||||
static const unsigned char qr_sizes[40] = {
|
||||
21, 25, 29, 33, 37, 41, 45, 49, 53, 57,
|
||||
61, 65, 69, 73, 77, 81, 85, 89, 93, 97,
|
||||
101, 105, 109, 113, 117, 121, 125, 129, 133, 137,
|
||||
141, 145, 149, 153, 157, 161, 165, 169, 173, 177
|
||||
};
|
||||
|
||||
static const char qr_blocks_H[] = {
|
||||
1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30,
|
||||
32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81
|
||||
};
|
||||
|
||||
static const char rmqr_blocks_M[] = {
|
||||
1, 1, 1, 1, 1, /* R7x */
|
||||
1, 1, 1, 1, 2, /* R9x */
|
||||
1, 1, 1, 1, 2, 2, /* R11x */
|
||||
1, 1, 1, 2, 2, 3, /* R13x */
|
||||
1, 1, 2, 2, 3, /* R15x */
|
||||
1, 2, 2, 3, 4 /* R17x */
|
||||
};
|
||||
|
||||
static const char rmqr_blocks_H[] = {
|
||||
1, 1, 1, 1, 2, /* R7x */
|
||||
1, 1, 2, 2, 3, /* R9x */
|
||||
1, 1, 2, 2, 2, 3, /* R11x */
|
||||
1, 1, 2, 2, 3, 4, /* R13x */
|
||||
2, 2, 3, 4, 5, /* R15x */
|
||||
2, 2, 3, 4, 6 /* R17x */
|
||||
};
|
||||
|
||||
static const unsigned short qr_sizes[] = {
|
||||
21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97,
|
||||
101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177
|
||||
};
|
||||
|
||||
static const char micro_qr_sizes[] = {
|
||||
static const char microqr_sizes[4] = {
|
||||
11, 13, 15, 17
|
||||
};
|
||||
|
||||
static const char qr_align_loopsize[] = {
|
||||
0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7
|
||||
/* From ISO/IEC 18004:2015 Table 7 - Number of symbol characters and input data capacity for QR Code and
|
||||
Table 9 — Error correction characteristics for QR Code, M1-4 only, indexed by ecc_level & version as
|
||||
{ data bits, data codewords, ecc codewords } */
|
||||
static const unsigned char microqr_data[3][4][3] = { {
|
||||
{ 20, 3, 2 }, { 40, 5, 5 }, { 84, 11, 6 }, { 128, 16, 8 } /* L */
|
||||
}, {
|
||||
{ 0, 0, 0 }, { 32, 4, 6 }, { 68, 9, 8 }, { 112, 14, 10 } /* M */
|
||||
}, {
|
||||
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 80, 10, 14 } /* Q */
|
||||
}
|
||||
};
|
||||
|
||||
/* Table E1 - Row/column coordinates of center module of alignment patterns */
|
||||
static const unsigned short qr_table_e1[] = {
|
||||
6, 18, 0, 0, 0, 0, 0,
|
||||
6, 22, 0, 0, 0, 0, 0,
|
||||
6, 26, 0, 0, 0, 0, 0,
|
||||
6, 30, 0, 0, 0, 0, 0,
|
||||
6, 34, 0, 0, 0, 0, 0,
|
||||
6, 22, 38, 0, 0, 0, 0,
|
||||
6, 24, 42, 0, 0, 0, 0,
|
||||
6, 26, 46, 0, 0, 0, 0,
|
||||
6, 28, 50, 0, 0, 0, 0,
|
||||
6, 30, 54, 0, 0, 0, 0,
|
||||
6, 32, 58, 0, 0, 0, 0,
|
||||
6, 34, 62, 0, 0, 0, 0,
|
||||
6, 26, 46, 66, 0, 0, 0,
|
||||
6, 26, 48, 70, 0, 0, 0,
|
||||
6, 26, 50, 74, 0, 0, 0,
|
||||
6, 30, 54, 78, 0, 0, 0,
|
||||
6, 30, 56, 82, 0, 0, 0,
|
||||
6, 30, 58, 86, 0, 0, 0,
|
||||
6, 34, 62, 90, 0, 0, 0,
|
||||
6, 28, 50, 72, 94, 0, 0,
|
||||
6, 26, 50, 74, 98, 0, 0,
|
||||
6, 30, 54, 78, 102, 0, 0,
|
||||
6, 28, 54, 80, 106, 0, 0,
|
||||
6, 32, 58, 84, 110, 0, 0,
|
||||
6, 30, 58, 86, 114, 0, 0,
|
||||
6, 34, 62, 90, 118, 0, 0,
|
||||
6, 26, 50, 74, 98, 122, 0,
|
||||
6, 30, 54, 78, 102, 126, 0,
|
||||
6, 26, 52, 78, 104, 130, 0,
|
||||
6, 30, 56, 82, 108, 134, 0,
|
||||
6, 34, 60, 86, 112, 138, 0,
|
||||
6, 30, 58, 86, 114, 142, 0,
|
||||
6, 34, 62, 90, 118, 146, 0,
|
||||
/* No. of entries in `qr_table_e1` (Table E.1) per version */
|
||||
static const char qr_align_loopsize[40] = {
|
||||
0, 2, 2, 2, 2, 2, 3, 3, 3, 3,
|
||||
3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
|
||||
6, 6, 6, 6, 7, 7, 7, 7, 7, 7
|
||||
};
|
||||
|
||||
/* Table E.1 - Row/column coordinates of center module of alignment patterns */
|
||||
static const unsigned char qr_table_e1[40 * 7] = {
|
||||
6, 18, 0, 0, 0, 0, 0,
|
||||
6, 22, 0, 0, 0, 0, 0,
|
||||
6, 26, 0, 0, 0, 0, 0,
|
||||
6, 30, 0, 0, 0, 0, 0,
|
||||
6, 34, 0, 0, 0, 0, 0,
|
||||
6, 22, 38, 0, 0, 0, 0,
|
||||
6, 24, 42, 0, 0, 0, 0,
|
||||
6, 26, 46, 0, 0, 0, 0,
|
||||
6, 28, 50, 0, 0, 0, 0,
|
||||
6, 30, 54, 0, 0, 0, 0,
|
||||
6, 32, 58, 0, 0, 0, 0,
|
||||
6, 34, 62, 0, 0, 0, 0,
|
||||
6, 26, 46, 66, 0, 0, 0,
|
||||
6, 26, 48, 70, 0, 0, 0,
|
||||
6, 26, 50, 74, 0, 0, 0,
|
||||
6, 30, 54, 78, 0, 0, 0,
|
||||
6, 30, 56, 82, 0, 0, 0,
|
||||
6, 30, 58, 86, 0, 0, 0,
|
||||
6, 34, 62, 90, 0, 0, 0,
|
||||
6, 28, 50, 72, 94, 0, 0,
|
||||
6, 26, 50, 74, 98, 0, 0,
|
||||
6, 30, 54, 78, 102, 0, 0,
|
||||
6, 28, 54, 80, 106, 0, 0,
|
||||
6, 32, 58, 84, 110, 0, 0,
|
||||
6, 30, 58, 86, 114, 0, 0,
|
||||
6, 34, 62, 90, 118, 0, 0,
|
||||
6, 26, 50, 74, 98, 122, 0,
|
||||
6, 30, 54, 78, 102, 126, 0,
|
||||
6, 26, 52, 78, 104, 130, 0,
|
||||
6, 30, 56, 82, 108, 134, 0,
|
||||
6, 34, 60, 86, 112, 138, 0,
|
||||
6, 30, 58, 86, 114, 142, 0,
|
||||
6, 34, 62, 90, 118, 146, 0,
|
||||
6, 30, 54, 78, 102, 126, 150,
|
||||
6, 24, 50, 76, 102, 128, 154,
|
||||
6, 28, 54, 80, 106, 132, 158,
|
||||
@ -253,39 +280,41 @@ static const unsigned short qr_table_e1[] = {
|
||||
6, 30, 58, 86, 114, 142, 170
|
||||
};
|
||||
|
||||
/* Table D1 - Column coordinates of centre module of alignment patterns */
|
||||
static const unsigned short rmqr_table_d1[] = {
|
||||
21, 0, 0, 0,
|
||||
19, 39, 0, 0,
|
||||
25, 51, 0, 0,
|
||||
23, 49, 75, 0,
|
||||
/* Table D.1 - Column coordinates of centre module of alignment patterns */
|
||||
static const unsigned char rmqr_table_d1[20] = {
|
||||
21, 0, 0, 0,
|
||||
19, 39, 0, 0,
|
||||
25, 51, 0, 0,
|
||||
23, 49, 75, 0,
|
||||
27, 55, 83, 111
|
||||
};
|
||||
|
||||
static const unsigned int qr_annex_c[] = {
|
||||
/* Format information bit sequences */
|
||||
0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, 0x77c4, 0x72f3, 0x7daa, 0x789d,
|
||||
0x662f, 0x6318, 0x6c41, 0x6976, 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b,
|
||||
0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed
|
||||
/* Format information bit sequences */
|
||||
static const unsigned short qr_annex_c[32] = {
|
||||
0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, 0x77c4, 0x72f3,
|
||||
0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, 0x1689, 0x13be, 0x1ce7, 0x19d0,
|
||||
0x0762, 0x0255, 0x0d0c, 0x083b, 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183,
|
||||
0x2eda, 0x2bed
|
||||
};
|
||||
|
||||
static const unsigned int qr_annex_d[] = {
|
||||
/* Version information bit sequences */
|
||||
/* Version information bit sequences */
|
||||
static const unsigned int qr_annex_d[34] = {
|
||||
0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, 0x0f928, 0x10b78,
|
||||
0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, 0x177ec, 0x18ec4, 0x191e1, 0x1afab,
|
||||
0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b,
|
||||
0x2542e, 0x26a64, 0x27541, 0x28c69
|
||||
};
|
||||
|
||||
static const unsigned int qr_annex_c1[] = {
|
||||
/* Micro QR Code format information */
|
||||
0x4445, 0x4172, 0x4e2b, 0x4b1c, 0x55ae, 0x5099, 0x5fc0, 0x5af7, 0x6793, 0x62a4, 0x6dfd, 0x68ca, 0x7678, 0x734f,
|
||||
0x7c16, 0x7921, 0x06de, 0x03e9, 0x0cb0, 0x0987, 0x1735, 0x1202, 0x1d5b, 0x186c, 0x2508, 0x203f, 0x2f66, 0x2a51, 0x34e3,
|
||||
0x31d4, 0x3e8d, 0x3bba
|
||||
/* Micro QR Code format information */
|
||||
static const unsigned short qr_annex_c1[32] = {
|
||||
0x4445, 0x4172, 0x4e2b, 0x4b1c, 0x55ae, 0x5099, 0x5fc0, 0x5af7, 0x6793, 0x62a4,
|
||||
0x6dfd, 0x68ca, 0x7678, 0x734f, 0x7c16, 0x7921, 0x06de, 0x03e9, 0x0cb0, 0x0987,
|
||||
0x1735, 0x1202, 0x1d5b, 0x186c, 0x2508, 0x203f, 0x2f66, 0x2a51, 0x34e3, 0x31d4,
|
||||
0x3e8d, 0x3bba
|
||||
};
|
||||
|
||||
static const unsigned int rmqr_format_info_left[] = {
|
||||
/* rMQR format information for finder pattern side */
|
||||
/* rMQR format information for finder pattern side */
|
||||
static const unsigned int rmqr_format_info_left[64] = {
|
||||
0x1FAB2, 0x1E597, 0x1DBDD, 0x1C4F8, 0x1B86C, 0x1A749, 0x19903, 0x18626, 0x17F0E, 0x1602B,
|
||||
0x15E61, 0x14144, 0x13DD0, 0x122F5, 0x11CBF, 0x1039A, 0x0F1CA, 0x0EEEF, 0x0D0A5, 0x0CF80,
|
||||
0x0B314, 0x0AC31, 0x0927B, 0x08D5E, 0x07476, 0x06B53, 0x05519, 0x04A3C, 0x036A8, 0x0298D,
|
||||
@ -295,8 +324,8 @@ static const unsigned int rmqr_format_info_left[] = {
|
||||
0x23F7D, 0x22058, 0x21E12, 0x20137
|
||||
};
|
||||
|
||||
static const unsigned int rmqr_format_info_right[] = {
|
||||
/* rMQR format information for subfinder pattern side */
|
||||
/* rMQR format information for subfinder pattern side */
|
||||
static const unsigned int rmqr_format_info_right[64] = {
|
||||
0x20A7B, 0x2155E, 0x22B14, 0x23431, 0x248A5, 0x25780, 0x269CA, 0x276EF, 0x28FC7, 0x290E2,
|
||||
0x2AEA8, 0x2B18D, 0x2CD19, 0x2D23C, 0x2EC76, 0x2F353, 0x30103, 0x31E26, 0x3206C, 0x33F49,
|
||||
0x343DD, 0x35CF8, 0x362B2, 0x37D97, 0x384BF, 0x39B9A, 0x3A5D0, 0x3BAF5, 0x3C661, 0x3D944,
|
||||
|
139
backend/raster.c
@ -1,7 +1,7 @@
|
||||
/* raster.c - Handles output to raster files */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -63,6 +63,17 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix
|
||||
|
||||
static const char ultra_colour[] = "0CBMRYGKW";
|
||||
|
||||
/* Wrapper to pre-check `size` on `malloc()` isn't too big (`prev_size` given if doing 2nd `malloc()` in a row) */
|
||||
static void *raster_malloc(size_t size, size_t prev_size) {
|
||||
/* Check for large image `malloc`s, which produce very large files most systems can't handle anyway */
|
||||
/* Also `malloc()` on Linux will (usually) succeed regardless of request, and then get untrappably killed on
|
||||
access by OOM killer if too much, so this is a crude mitigation */
|
||||
if (size + prev_size < size /*Overflow check*/ || size + prev_size > 0x40000000 /*1GB*/) {
|
||||
return NULL;
|
||||
}
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static int buffer_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf) {
|
||||
/* Place pixelbuffer into symbol */
|
||||
unsigned char alpha[2];
|
||||
@ -80,6 +91,7 @@ static int buffer_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf
|
||||
int row;
|
||||
int plot_alpha = 0;
|
||||
const size_t bm_bitmap_width = (size_t) symbol->bitmap_width * 3;
|
||||
const size_t bm_bitmap_size = bm_bitmap_width * symbol->bitmap_height;
|
||||
|
||||
if (out_colour_get_rgb(symbol->fgcolour, &map[DEFAULT_INK][0], &map[DEFAULT_INK][1], &map[DEFAULT_INK][2],
|
||||
&alpha[0])) {
|
||||
@ -100,27 +112,24 @@ static int buffer_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf
|
||||
symbol->alphamap = NULL;
|
||||
}
|
||||
|
||||
symbol->bitmap = (unsigned char *) malloc(bm_bitmap_width * symbol->bitmap_height);
|
||||
if (symbol->bitmap == NULL) {
|
||||
strcpy(symbol->errtxt, "661: Insufficient memory for bitmap buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
if (!(symbol->bitmap = (unsigned char *) raster_malloc(bm_bitmap_size, 0 /*prev_size*/))) {
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 661, "Insufficient memory for bitmap buffer");
|
||||
}
|
||||
|
||||
if (plot_alpha) {
|
||||
symbol->alphamap = (unsigned char *) malloc((size_t) symbol->bitmap_width * symbol->bitmap_height);
|
||||
if (symbol->alphamap == NULL) {
|
||||
strcpy(symbol->errtxt, "662: Insufficient memory for alphamap buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
const size_t alpha_size = (size_t) symbol->bitmap_width * symbol->bitmap_height;
|
||||
if (!(symbol->alphamap = (unsigned char *) raster_malloc(alpha_size, bm_bitmap_size))) {
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 662, "Insufficient memory for alphamap buffer");
|
||||
}
|
||||
for (row = 0; row < symbol->bitmap_height; row++) {
|
||||
int p = row * symbol->bitmap_width;
|
||||
size_t p = (size_t) symbol->bitmap_width * row;
|
||||
const unsigned char *pb = pixelbuf + p;
|
||||
unsigned char *bitmap = symbol->bitmap + p * 3;
|
||||
if (row && memcmp(pb, pb - symbol->bitmap_width, symbol->bitmap_width) == 0) {
|
||||
memcpy(bitmap, bitmap - bm_bitmap_width, bm_bitmap_width);
|
||||
memcpy(symbol->alphamap + p, symbol->alphamap + p - symbol->bitmap_width, symbol->bitmap_width);
|
||||
} else {
|
||||
const int pe = p + symbol->bitmap_width;
|
||||
const size_t pe = p + symbol->bitmap_width;
|
||||
for (; p < pe; p++, bitmap += 3) {
|
||||
memcpy(bitmap, map[pixelbuf[p]], 3);
|
||||
symbol->alphamap[p] = alpha[pixelbuf[p] == DEFAULT_PAPER];
|
||||
@ -129,7 +138,7 @@ static int buffer_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf
|
||||
}
|
||||
} else {
|
||||
for (row = 0; row < symbol->bitmap_height; row++) {
|
||||
const int r = row * symbol->bitmap_width;
|
||||
const size_t r = (size_t) symbol->bitmap_width * row;
|
||||
const unsigned char *pb = pixelbuf + r;
|
||||
unsigned char *bitmap = symbol->bitmap + r * 3;
|
||||
if (row && memcmp(pb, pb - symbol->bitmap_width, symbol->bitmap_width) == 0) {
|
||||
@ -169,9 +178,9 @@ static int save_raster_image_to_file(struct zint_symbol *symbol, const int image
|
||||
}
|
||||
|
||||
if (rotate_angle) {
|
||||
if (!(rotated_pixbuf = (unsigned char *) malloc((size_t) image_width * image_height))) {
|
||||
strcpy(symbol->errtxt, "650: Insufficient memory for pixel buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
if (!(rotated_pixbuf = (unsigned char *) raster_malloc((size_t) image_width * image_height,
|
||||
0 /*prev_size*/))) {
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 650, "Insufficient memory for pixel buffer");
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,25 +191,28 @@ static int save_raster_image_to_file(struct zint_symbol *symbol, const int image
|
||||
break;
|
||||
case 90: /* Plot 90 degrees clockwise */
|
||||
for (row = 0; row < image_width; row++) {
|
||||
const size_t h_offset = (size_t) image_height * row;
|
||||
for (column = 0; column < image_height; column++) {
|
||||
rotated_pixbuf[(row * image_height) + column] =
|
||||
*(pixelbuf + (image_width * (image_height - column - 1)) + row);
|
||||
const size_t w_offset = (size_t) image_width * (image_height - column - 1);
|
||||
rotated_pixbuf[h_offset + column] = *(pixelbuf + w_offset + row);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 180: /* Plot upside down */
|
||||
for (row = 0; row < image_height; row++) {
|
||||
const size_t w_offset = (size_t) image_width * row;
|
||||
const size_t wh_offset = (size_t) image_width * (image_height - row - 1);
|
||||
for (column = 0; column < image_width; column++) {
|
||||
rotated_pixbuf[(row * image_width) + column] =
|
||||
*(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1));
|
||||
rotated_pixbuf[w_offset + column] = *(pixelbuf + wh_offset + (image_width - column - 1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 270: /* Plot 90 degrees anti-clockwise */
|
||||
for (row = 0; row < image_width; row++) {
|
||||
const size_t h_offset = (size_t) image_height * row;
|
||||
for (column = 0; column < image_height; column++) {
|
||||
rotated_pixbuf[(row * image_height) + column] =
|
||||
*(pixelbuf + (image_width * column) + (image_width - row - 1));
|
||||
const size_t w_offset = (size_t) image_width * column;
|
||||
rotated_pixbuf[h_offset + column] = *(pixelbuf + w_offset + (image_width - row - 1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -228,12 +240,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 ‘<unknown>’ 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;
|
||||
@ -246,6 +260,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) {
|
||||
@ -713,12 +730,14 @@ static void draw_bind_box(const struct zint_symbol *symbol, unsigned char *pixel
|
||||
static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_angle, const int file_type) {
|
||||
int row, column;
|
||||
int image_height, image_width;
|
||||
size_t image_size;
|
||||
unsigned char *pixelbuf;
|
||||
int error_number;
|
||||
float xoffset, yoffset, roffset, boffset;
|
||||
float scaler = symbol->scale;
|
||||
unsigned char *scaled_hexagon;
|
||||
int hex_width, hex_height;
|
||||
size_t hex_size;
|
||||
int hx_start, hy_start, hx_end, hy_end;
|
||||
int hex_image_width, hex_image_height;
|
||||
int yposn_offset;
|
||||
@ -758,19 +777,19 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang
|
||||
image_width = (int) ceilf(hex_image_width + xoffset_si + roffset_si);
|
||||
image_height = (int) ceilf(hex_image_height + yoffset_si + boffset_si);
|
||||
assert(image_width && image_height);
|
||||
image_size = (size_t) image_width * image_height;
|
||||
|
||||
if (!(pixelbuf = (unsigned char *) malloc((size_t) image_width * image_height))) {
|
||||
strcpy(symbol->errtxt, "655: Insufficient memory for pixel buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
if (!(pixelbuf = (unsigned char *) raster_malloc(image_size, 0 /*prev_size*/))) {
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 655, "Insufficient memory for pixel buffer");
|
||||
}
|
||||
memset(pixelbuf, DEFAULT_PAPER, (size_t) image_width * image_height);
|
||||
memset(pixelbuf, DEFAULT_PAPER, image_size);
|
||||
|
||||
if (!(scaled_hexagon = (unsigned char *) malloc((size_t) hex_width * hex_height))) {
|
||||
strcpy(symbol->errtxt, "656: Insufficient memory for pixel buffer");
|
||||
hex_size = (size_t) hex_width * hex_height;
|
||||
if (!(scaled_hexagon = (unsigned char *) raster_malloc(hex_size, image_size))) {
|
||||
free(pixelbuf);
|
||||
return ZINT_ERROR_MEMORY;
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 656, "Insufficient memory for pixel buffer");
|
||||
}
|
||||
memset(scaled_hexagon, DEFAULT_PAPER, (size_t) hex_width * hex_height);
|
||||
memset(scaled_hexagon, DEFAULT_PAPER, hex_size);
|
||||
|
||||
plot_hexagon(scaled_hexagon, hex_width, hex_height, hx_start, hy_start, hx_end, hy_end);
|
||||
|
||||
@ -800,10 +819,11 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, const int rotate_ang
|
||||
}
|
||||
if (error_number == 0) {
|
||||
/* Check whether size is compliant */
|
||||
const float min_ratio = 0.92993629f; /* 24.82 / 26.69 */
|
||||
const float max_ratio = 1.177984f; /* 27.93 / 23.71 */
|
||||
const float size_ratio = (float) hex_image_width / hex_image_height;
|
||||
if (size_ratio < 24.82f / 26.69f || size_ratio > 27.93f / 23.71f) {
|
||||
strcpy(symbol->errtxt, "663: Size not within the minimum/maximum ranges");
|
||||
error_number = ZINT_WARN_NONCOMPLIANT;
|
||||
if (size_ratio < min_ratio || size_ratio > max_ratio) {
|
||||
return errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 663, "Size not within the minimum/maximum ranges");
|
||||
}
|
||||
}
|
||||
return error_number;
|
||||
@ -814,6 +834,7 @@ static int plot_raster_dotty(struct zint_symbol *symbol, const int rotate_angle,
|
||||
unsigned char *scaled_pixelbuf;
|
||||
int r, i;
|
||||
int scale_width, scale_height;
|
||||
size_t scale_size;
|
||||
int error_number = 0;
|
||||
float xoffset, yoffset, roffset, boffset;
|
||||
float dot_offset_s;
|
||||
@ -848,13 +869,13 @@ static int plot_raster_dotty(struct zint_symbol *symbol, const int rotate_angle,
|
||||
|
||||
scale_width = (int) (symbol->width * scaler + xoffset_si + roffset_si + dot_overspill_si);
|
||||
scale_height = (int) (symbol_height_si + yoffset_si + boffset_si + dot_overspill_si);
|
||||
scale_size = (size_t) scale_width * scale_height;
|
||||
|
||||
/* Apply scale options by creating another pixel buffer */
|
||||
if (!(scaled_pixelbuf = (unsigned char *) malloc((size_t) scale_width * scale_height))) {
|
||||
strcpy(symbol->errtxt, "657: Insufficient memory for pixel buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
/* Apply scale options by creating pixel buffer */
|
||||
if (!(scaled_pixelbuf = (unsigned char *) raster_malloc(scale_size, 0 /*prev_size*/))) {
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 657, "Insufficient memory for pixel buffer");
|
||||
}
|
||||
memset(scaled_pixelbuf, DEFAULT_PAPER, (size_t) scale_width * scale_height);
|
||||
memset(scaled_pixelbuf, DEFAULT_PAPER, scale_size);
|
||||
|
||||
/* Plot the body of the symbol to the pixel buffer */
|
||||
for (r = 0; r < symbol->rows; r++) {
|
||||
@ -946,6 +967,7 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
|
||||
int row_heights_si[200];
|
||||
int symbol_height_si;
|
||||
int image_width, image_height;
|
||||
size_t image_size;
|
||||
unsigned char *pixelbuf;
|
||||
float scaler = symbol->scale;
|
||||
int si;
|
||||
@ -1013,12 +1035,12 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
|
||||
|
||||
image_height = symbol_height_si + (int) ceilf(textoffset * si) + yoffset_si + boffset_si;
|
||||
assert(image_width && image_height);
|
||||
image_size = (size_t) image_width * image_height;
|
||||
|
||||
if (!(pixelbuf = (unsigned char *) malloc((size_t) image_width * image_height))) {
|
||||
strcpy(symbol->errtxt, "658: Insufficient memory for pixel buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
if (!(pixelbuf = (unsigned char *) raster_malloc(image_size, 0 /*prev_size*/))) {
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 658, "Insufficient memory for pixel buffer");
|
||||
}
|
||||
memset(pixelbuf, DEFAULT_PAPER, (size_t) image_width * image_height);
|
||||
memset(pixelbuf, DEFAULT_PAPER, image_size);
|
||||
|
||||
yposn_si = yoffset_si;
|
||||
|
||||
@ -1058,9 +1080,9 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
|
||||
addon_text_yposn = yposn_si;
|
||||
yposn_si += addon_row_adj_si;
|
||||
addon_row_height_si = row_height_si - addon_row_adj_si;
|
||||
if (upceanflag != 12 && upceanflag != 6) { /* UPC-A/E add-ons don't descend */
|
||||
addon_row_height_si += guard_descent * si;
|
||||
}
|
||||
/* Following ISO/IEC 15420:2009 Figure 5 — UPC-A bar code symbol with 2-digit add-on (contrary to
|
||||
GS1 General Specs v24.0 Figure 5.2.6.6-5) descends for all including UPC-A/E */
|
||||
addon_row_height_si += guard_descent * si;
|
||||
if (addon_row_height_si == 0) {
|
||||
addon_row_height_si = 1;
|
||||
}
|
||||
@ -1188,7 +1210,9 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
|
||||
text_xposn = 24 * si + xoffset_comp_si;
|
||||
draw_string(pixelbuf, symbol->text + 1, 6, text_xposn, text_yposn, textflags, image_width,
|
||||
image_height, si);
|
||||
text_xposn = (51 + 3) * si + xoffset_comp_si;
|
||||
/* TODO: GS1 General Specs v24.0 5.2.5 Human readable interpretation says 3X but this could cause
|
||||
digit's righthand to touch any add-on, now that they descend, so use 2X, until clarified */
|
||||
text_xposn = (51 + 2) * si + xoffset_comp_si;
|
||||
draw_string(pixelbuf, symbol->text + 7, 1, text_xposn, text_yposn + upcea_height_adj,
|
||||
textflags | SMALL_TEXT | ZFONT_HALIGN_LEFT, image_width, image_height, si);
|
||||
if (addon_len) {
|
||||
@ -1240,7 +1264,9 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
|
||||
text_xposn = 67 * si + xoffset_comp_si;
|
||||
draw_string(pixelbuf, symbol->text + 6, 5, text_xposn, text_yposn, textflags, image_width,
|
||||
image_height, si);
|
||||
text_xposn = (95 + 5) * si + xoffset_comp_si;
|
||||
/* TODO: GS1 General Specs v24.0 5.2.5 Human readable interpretation says 5X but this could cause
|
||||
digit's righthand to touch any add-on, now that they descend, so use 4X, until clarified */
|
||||
text_xposn = (95 + 4) * si + xoffset_comp_si;
|
||||
draw_string(pixelbuf, symbol->text + 11, 1, text_xposn, text_yposn + upcea_height_adj,
|
||||
textflags | SMALL_TEXT | ZFONT_HALIGN_LEFT, image_width, image_height, si);
|
||||
if (addon_len) {
|
||||
@ -1341,16 +1367,15 @@ static int plot_raster_default(struct zint_symbol *symbol, const int rotate_angl
|
||||
const int scale_height = (int) stripf(image_height * scaler);
|
||||
|
||||
/* Apply scale options by creating another pixel buffer */
|
||||
if (!(scaled_pixelbuf = (unsigned char *) malloc((size_t) scale_width * scale_height))) {
|
||||
if (!(scaled_pixelbuf = (unsigned char *) raster_malloc((size_t) scale_width * scale_height, image_size))) {
|
||||
free(pixelbuf);
|
||||
strcpy(symbol->errtxt, "659: Insufficient memory for scaled pixel buffer");
|
||||
return ZINT_ERROR_MEMORY;
|
||||
return errtxt(ZINT_ERROR_MEMORY, symbol, 659, "Insufficient memory for scaled pixel buffer");
|
||||
}
|
||||
memset(scaled_pixelbuf, DEFAULT_PAPER, (size_t) scale_width * scale_height);
|
||||
|
||||
/* Interpolate */
|
||||
for (r = 0; r < scale_height; r++) {
|
||||
size_t scaled_row = r * scale_width;
|
||||
size_t scaled_row = (size_t) scale_width * r;
|
||||
size_t image_row = (size_t) stripf(r / scaler) * image_width;
|
||||
if (r && (image_row == prev_image_row
|
||||
|| memcmp(pixelbuf + image_row, pixelbuf + prev_image_row, image_width) == 0)) {
|
||||
@ -1384,8 +1409,7 @@ INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_
|
||||
|
||||
#ifdef ZINT_NO_PNG
|
||||
if (file_type == OUT_PNG_FILE) {
|
||||
strcpy(symbol->errtxt, "660: PNG format disabled at compile time");
|
||||
return ZINT_ERROR_INVALID_OPTION;
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 660, "PNG format disabled at compile time");
|
||||
}
|
||||
#endif /* ZINT_NO_PNG */
|
||||
|
||||
@ -1393,6 +1417,9 @@ INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
if (symbol->rows <= 0) {
|
||||
return errtxt(ZINT_ERROR_INVALID_OPTION, symbol, 664, "No rows");
|
||||
}
|
||||
|
||||
if (symbol->symbology == BARCODE_MAXICODE) {
|
||||
error = plot_raster_maxicode(symbol, rotate_angle, file_type);
|
||||
|
163
backend/rss.c
@ -1,7 +1,7 @@
|
||||
/* rss.c - GS1 DataBar (formerly Reduced Space Symbology) */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -247,7 +247,6 @@ static void dbar_omn_separator(struct zint_symbol *symbol, int width, const int
|
||||
|
||||
/* Set Databar Stacked height, maintaining 5:7 ratio of the 2 main row heights */
|
||||
INTERNAL int dbar_omnstk_set_height(struct zint_symbol *symbol, const int first_row) {
|
||||
int error_number = 0;
|
||||
float fixed_height = 0.0f;
|
||||
int second_row = first_row + 2; /* 2 row separator */
|
||||
int i;
|
||||
@ -274,12 +273,11 @@ INTERNAL int dbar_omnstk_set_height(struct zint_symbol *symbol, const int first_
|
||||
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
if (symbol->row_height[first_row] < 5.0f || symbol->row_height[second_row] < 7.0f) {
|
||||
error_number = ZINT_WARN_NONCOMPLIANT;
|
||||
strcpy(symbol->errtxt, "379: Height not compliant with standards");
|
||||
return errtxt(ZINT_WARN_NONCOMPLIANT, symbol, 379, "Height not compliant with standards");
|
||||
}
|
||||
}
|
||||
|
||||
return error_number;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* GS1 DataBar Omnidirectional/Truncated/Stacked, allowing for composite if `cc_rows` set */
|
||||
@ -296,19 +294,17 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
separator_row = 0;
|
||||
|
||||
if (length > 14) { /* Allow check digit to be specified (will be verified and ignored) */
|
||||
strcpy(symbol->errtxt, "380: Input too long (14 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 380, "Input length %d too long (maximum 14)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "381: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 381,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
if (length == 14) { /* Verify check digit */
|
||||
if (gs1_check_digit(source, 13) != source[13]) {
|
||||
sprintf(symbol->errtxt, "388: Invalid check digit '%c', expecting '%c'",
|
||||
source[13], gs1_check_digit(source, 13));
|
||||
return ZINT_ERROR_INVALID_CHECK;
|
||||
return errtxtf(ZINT_ERROR_INVALID_CHECK, symbol, 388, "Invalid check digit '%1$c', expecting '%2$c'",
|
||||
source[13], gs1_check_digit(source, 13));
|
||||
}
|
||||
length--; /* Ignore */
|
||||
}
|
||||
@ -390,35 +386,35 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
data_group[2] = 4;
|
||||
}
|
||||
|
||||
v_odd[0] = (data_character[0] - g_sum_table[data_group[0]]) / t_table[data_group[0]];
|
||||
v_even[0] = (data_character[0] - g_sum_table[data_group[0]]) % t_table[data_group[0]];
|
||||
v_odd[1] = (data_character[1] - g_sum_table[data_group[1]]) % t_table[data_group[1]];
|
||||
v_even[1] = (data_character[1] - g_sum_table[data_group[1]]) / t_table[data_group[1]];
|
||||
v_odd[3] = (data_character[3] - g_sum_table[data_group[3]]) % t_table[data_group[3]];
|
||||
v_even[3] = (data_character[3] - g_sum_table[data_group[3]]) / t_table[data_group[3]];
|
||||
v_odd[2] = (data_character[2] - g_sum_table[data_group[2]]) / t_table[data_group[2]];
|
||||
v_even[2] = (data_character[2] - g_sum_table[data_group[2]]) % t_table[data_group[2]];
|
||||
v_odd[0] = (data_character[0] - dbar_g_sum_table[data_group[0]]) / dbar_t_table[data_group[0]];
|
||||
v_even[0] = (data_character[0] - dbar_g_sum_table[data_group[0]]) % dbar_t_table[data_group[0]];
|
||||
v_odd[1] = (data_character[1] - dbar_g_sum_table[data_group[1]]) % dbar_t_table[data_group[1]];
|
||||
v_even[1] = (data_character[1] - dbar_g_sum_table[data_group[1]]) / dbar_t_table[data_group[1]];
|
||||
v_odd[3] = (data_character[3] - dbar_g_sum_table[data_group[3]]) % dbar_t_table[data_group[3]];
|
||||
v_even[3] = (data_character[3] - dbar_g_sum_table[data_group[3]]) / dbar_t_table[data_group[3]];
|
||||
v_odd[2] = (data_character[2] - dbar_g_sum_table[data_group[2]]) / dbar_t_table[data_group[2]];
|
||||
v_even[2] = (data_character[2] - dbar_g_sum_table[data_group[2]]) % dbar_t_table[data_group[2]];
|
||||
|
||||
/* Use DataBar subset width algorithm */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((i == 0) || (i == 2)) {
|
||||
getRSSwidths(widths, v_odd[i], modules_odd[data_group[i]], 4, widest_odd[data_group[i]], 1);
|
||||
getRSSwidths(widths, v_odd[i], dbar_modules_odd[data_group[i]], 4, dbar_widest_odd[data_group[i]], 1);
|
||||
data_widths[0][i] = widths[0];
|
||||
data_widths[2][i] = widths[1];
|
||||
data_widths[4][i] = widths[2];
|
||||
data_widths[6][i] = widths[3];
|
||||
getRSSwidths(widths, v_even[i], modules_even[data_group[i]], 4, widest_even[data_group[i]], 0);
|
||||
getRSSwidths(widths, v_even[i], dbar_modules_even[data_group[i]], 4, dbar_widest_even[data_group[i]], 0);
|
||||
data_widths[1][i] = widths[0];
|
||||
data_widths[3][i] = widths[1];
|
||||
data_widths[5][i] = widths[2];
|
||||
data_widths[7][i] = widths[3];
|
||||
} else {
|
||||
getRSSwidths(widths, v_odd[i], modules_odd[data_group[i]], 4, widest_odd[data_group[i]], 0);
|
||||
getRSSwidths(widths, v_odd[i], dbar_modules_odd[data_group[i]], 4, dbar_widest_odd[data_group[i]], 0);
|
||||
data_widths[0][i] = widths[0];
|
||||
data_widths[2][i] = widths[1];
|
||||
data_widths[4][i] = widths[2];
|
||||
data_widths[6][i] = widths[3];
|
||||
getRSSwidths(widths, v_even[i], modules_even[data_group[i]], 4, widest_even[data_group[i]], 1);
|
||||
getRSSwidths(widths, v_even[i], dbar_modules_even[data_group[i]], 4, dbar_widest_even[data_group[i]], 1);
|
||||
data_widths[1][i] = widths[0];
|
||||
data_widths[3][i] = widths[1];
|
||||
data_widths[5][i] = widths[2];
|
||||
@ -429,10 +425,10 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
checksum = 0;
|
||||
/* Calculate the checksum */
|
||||
for (i = 0; i < 8; i++) {
|
||||
checksum += checksum_weight[i] * data_widths[i][0];
|
||||
checksum += checksum_weight[i + 8] * data_widths[i][1];
|
||||
checksum += checksum_weight[i + 16] * data_widths[i][2];
|
||||
checksum += checksum_weight[i + 24] * data_widths[i][3];
|
||||
checksum += dbar_checksum_weight[i] * data_widths[i][0];
|
||||
checksum += dbar_checksum_weight[i + 8] * data_widths[i][1];
|
||||
checksum += dbar_checksum_weight[i + 16] * data_widths[i][2];
|
||||
checksum += dbar_checksum_weight[i + 24] * data_widths[i][3];
|
||||
}
|
||||
checksum %= 79;
|
||||
|
||||
@ -462,8 +458,8 @@ INTERNAL int dbar_omn_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
total_widths[i + 36] = data_widths[7 - i][2];
|
||||
}
|
||||
for (i = 0; i < 5; i++) {
|
||||
total_widths[i + 10] = finder_pattern[i + (5 * c_left)];
|
||||
total_widths[i + 31] = finder_pattern[(4 - i) + (5 * c_right)];
|
||||
total_widths[i + 10] = dbar_finder_pattern[i + (5 * c_left)];
|
||||
total_widths[i + 31] = dbar_finder_pattern[(4 - i) + (5 * c_right)];
|
||||
}
|
||||
|
||||
/* Put this data into the symbol */
|
||||
@ -633,27 +629,24 @@ INTERNAL int dbar_ltd_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
separator_row = 0;
|
||||
|
||||
if (length > 14) { /* Allow check digit to be specified (will be verified and ignored) */
|
||||
strcpy(symbol->errtxt, "382: Input too long (14 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 382, "Input length %d too long (maximum 14)", length);
|
||||
}
|
||||
if (!is_sane(NEON_F, source, length)) {
|
||||
strcpy(symbol->errtxt, "383: Invalid character in data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 383,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
|
||||
if (length == 14) { /* Verify check digit */
|
||||
if (gs1_check_digit(source, 13) != source[13]) {
|
||||
sprintf(symbol->errtxt, "389: Invalid check digit '%c', expecting '%c'",
|
||||
source[13], gs1_check_digit(source, 13));
|
||||
return ZINT_ERROR_INVALID_CHECK;
|
||||
return errtxtf(ZINT_ERROR_INVALID_CHECK, symbol, 389, "Invalid check digit '%1$c', expecting '%2$c'",
|
||||
source[13], gs1_check_digit(source, 13));
|
||||
}
|
||||
length--; /* Ignore */
|
||||
}
|
||||
|
||||
if (length == 13) {
|
||||
if ((source[0] != '0') && (source[0] != '1')) {
|
||||
strcpy(symbol->errtxt, "384: Input out of range (0 to 1999999999999)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 384, "Input value out of range (0 to 1999999999999)");
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,24 +713,24 @@ INTERNAL int dbar_ltd_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
right_group = 0;
|
||||
}
|
||||
|
||||
left_odd = (int) (left_character / t_even_ltd[left_group]);
|
||||
left_even = (int) (left_character % t_even_ltd[left_group]);
|
||||
right_odd = (int) (right_character / t_even_ltd[right_group]);
|
||||
right_even = (int) (right_character % t_even_ltd[right_group]);
|
||||
left_odd = (int) (left_character / dbar_ltd_t_even[left_group]);
|
||||
left_even = (int) (left_character % dbar_ltd_t_even[left_group]);
|
||||
right_odd = (int) (right_character / dbar_ltd_t_even[right_group]);
|
||||
right_even = (int) (right_character % dbar_ltd_t_even[right_group]);
|
||||
|
||||
getRSSwidths(widths, left_odd, modules_odd_ltd[left_group], 7, widest_odd_ltd[left_group], 1);
|
||||
getRSSwidths(widths, left_odd, dbar_ltd_modules_odd[left_group], 7, dbar_ltd_widest_odd[left_group], 1);
|
||||
for (i = 0; i <= 6; i++) {
|
||||
left_widths[i * 2] = widths[i];
|
||||
}
|
||||
getRSSwidths(widths, left_even, modules_even_ltd[left_group], 7, widest_even_ltd[left_group], 0);
|
||||
getRSSwidths(widths, left_even, dbar_ltd_modules_even[left_group], 7, dbar_ltd_widest_even[left_group], 0);
|
||||
for (i = 0; i <= 6; i++) {
|
||||
left_widths[i * 2 + 1] = widths[i];
|
||||
}
|
||||
getRSSwidths(widths, right_odd, modules_odd_ltd[right_group], 7, widest_odd_ltd[right_group], 1);
|
||||
getRSSwidths(widths, right_odd, dbar_ltd_modules_odd[right_group], 7, dbar_ltd_widest_odd[right_group], 1);
|
||||
for (i = 0; i <= 6; i++) {
|
||||
right_widths[i * 2] = widths[i];
|
||||
}
|
||||
getRSSwidths(widths, right_even, modules_even_ltd[right_group], 7, widest_even_ltd[right_group], 0);
|
||||
getRSSwidths(widths, right_even, dbar_ltd_modules_even[right_group], 7, dbar_ltd_widest_even[right_group], 0);
|
||||
for (i = 0; i <= 6; i++) {
|
||||
right_widths[i * 2 + 1] = widths[i];
|
||||
}
|
||||
@ -748,13 +741,13 @@ INTERNAL int dbar_ltd_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1900 && defined(_WIN64) /* MSVC 2015 x64 */
|
||||
checksum %= 89; /* Hack to get around optimizer bug */
|
||||
#endif
|
||||
checksum += checksum_weight_ltd[i] * left_widths[i];
|
||||
checksum += checksum_weight_ltd[i + 14] * right_widths[i];
|
||||
checksum += dbar_ltd_checksum_weight[i] * left_widths[i];
|
||||
checksum += dbar_ltd_checksum_weight[i + 14] * right_widths[i];
|
||||
}
|
||||
checksum %= 89;
|
||||
|
||||
for (i = 0; i < 14; i++) {
|
||||
check_elements[i] = finder_pattern_ltd[i + (checksum * 14)];
|
||||
check_elements[i] = dbar_ltd_finder_pattern[i + (checksum * 14)];
|
||||
}
|
||||
|
||||
total_widths[0] = 1;
|
||||
@ -842,6 +835,11 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha
|
||||
int remainder, d1, d2;
|
||||
int cdf_bp_start; /* Compressed data field start - debug only */
|
||||
|
||||
if (length > 77) { /* ISO/IEC 24724:2011 4.2.d.2 */
|
||||
/* Caught below anyway but catch here also for better feedback */
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 378, "Processed input length %d too long (maximum 77)", length);
|
||||
}
|
||||
|
||||
/* Decide whether a compressed data field is required and if so what
|
||||
method to use - method 2 = no compressed data field */
|
||||
|
||||
@ -966,10 +964,10 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha
|
||||
before carrying out compression */
|
||||
for (i = 0; i < read_posn; i++) {
|
||||
if (!z_isdigit(source[i])) {
|
||||
if (source[i] != '[') {
|
||||
if (source[i] != '\x1D') {
|
||||
/* Something is wrong */
|
||||
strcpy(symbol->errtxt, "385: Invalid character in Compressed Field data (digits only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 385,
|
||||
"Invalid character in Compressed Field data (digits only)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1062,10 +1060,9 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha
|
||||
if (debug_print) printf("General field data = %s\n", general_field);
|
||||
|
||||
if (j != 0) { /* If general field not empty */
|
||||
if (!general_field_encode(general_field, j, &mode, &last_digit, binary_string, &bp)) { /* Should not happen */
|
||||
/* Not reachable */
|
||||
strcpy(symbol->errtxt, "386: Invalid character in General Field data");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if (!general_field_encode(general_field, j, &mode, &last_digit, binary_string, &bp)) {
|
||||
/* Will happen if character not in CSET 82 + space */
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 386, "Invalid character in General Field data");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1134,8 +1131,8 @@ static int dbar_exp_binary_string(struct zint_symbol *symbol, const unsigned cha
|
||||
}
|
||||
|
||||
if (bp > 252) { /* 252 = (21 * 12) */
|
||||
strcpy(symbol->errtxt, "387: Input too long"); /* TODO: Better error message */
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 387, /* TODO: Better error message */
|
||||
"Input too long, requires %d symbol characters (maximum 21)", (bp + 11) / 12);
|
||||
}
|
||||
|
||||
if (min_cols_per_row && min_cols_per_row > *p_cols_per_row) {
|
||||
@ -1250,15 +1247,21 @@ static void dbar_exp_separator(struct zint_symbol *symbol, int width, const int
|
||||
|
||||
/* Set HRT for DataBar Expanded */
|
||||
static void dbar_exp_hrt(struct zint_symbol *symbol, unsigned char source[], const int length) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= length; i++) { /* Include terminating NUL */
|
||||
if (source[i] == '[') {
|
||||
symbol->text[i] = '(';
|
||||
} else if (source[i] == ']') {
|
||||
symbol->text[i] = ')';
|
||||
} else {
|
||||
symbol->text[i] = source[i];
|
||||
/* Max possible length is 77 digits so will fit */
|
||||
if (symbol->input_mode & GS1PARENS_MODE) {
|
||||
memcpy(symbol->text, source, length + 1); /* Include terminating NUL */
|
||||
} else {
|
||||
int i;
|
||||
/* Can't have square brackets in content so bracket level not required */
|
||||
for (i = 0; i <= length /* Include terminating NUL */; i++) {
|
||||
if (source[i] == '[') {
|
||||
symbol->text[i] = '(';
|
||||
} else if (source[i] == ']') {
|
||||
symbol->text[i] = ')';
|
||||
} else {
|
||||
symbol->text[i] = source[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1350,16 +1353,16 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
} else {
|
||||
group = 5;
|
||||
}
|
||||
v_odd = (vs - g_sum_exp[group - 1]) / t_even_exp[group - 1];
|
||||
v_even = (vs - g_sum_exp[group - 1]) % t_even_exp[group - 1];
|
||||
v_odd = (vs - dbar_exp_g_sum[group - 1]) / dbar_exp_t_even[group - 1];
|
||||
v_even = (vs - dbar_exp_g_sum[group - 1]) % dbar_exp_t_even[group - 1];
|
||||
if (debug_print) printf("%s%d", i == 0 || (i & 1) ? " " : ",", vs);
|
||||
|
||||
getRSSwidths(widths, v_odd, modules_odd_exp[group - 1], 4, widest_odd_exp[group - 1], 0);
|
||||
getRSSwidths(widths, v_odd, dbar_exp_modules_odd[group - 1], 4, dbar_exp_widest_odd[group - 1], 0);
|
||||
char_widths[i][0] = widths[0];
|
||||
char_widths[i][2] = widths[1];
|
||||
char_widths[i][4] = widths[2];
|
||||
char_widths[i][6] = widths[3];
|
||||
getRSSwidths(widths, v_even, modules_even_exp[group - 1], 4, widest_even_exp[group - 1], 1);
|
||||
getRSSwidths(widths, v_even, dbar_exp_modules_even[group - 1], 4, dbar_exp_widest_even[group - 1], 1);
|
||||
char_widths[i][1] = widths[0];
|
||||
char_widths[i][3] = widths[1];
|
||||
char_widths[i][5] = widths[2];
|
||||
@ -1372,9 +1375,9 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
elements in the data characters. */
|
||||
checksum = 0;
|
||||
for (i = 0; i < data_chars; i++) {
|
||||
int row = weight_rows[(((data_chars - 2) / 2) * 21) + i];
|
||||
int row = dbar_exp_weight_rows[(((data_chars - 2) / 2) * 21) + i];
|
||||
for (j = 0; j < 8; j++) {
|
||||
checksum += (char_widths[i][j] * checksum_weight_exp[(row * 8) + j]);
|
||||
checksum += (char_widths[i][j] * dbar_exp_checksum_weight[(row * 8) + j]);
|
||||
|
||||
}
|
||||
}
|
||||
@ -1397,15 +1400,15 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
c_group = 5;
|
||||
}
|
||||
|
||||
c_odd = (check_char - g_sum_exp[c_group - 1]) / t_even_exp[c_group - 1];
|
||||
c_even = (check_char - g_sum_exp[c_group - 1]) % t_even_exp[c_group - 1];
|
||||
c_odd = (check_char - dbar_exp_g_sum[c_group - 1]) / dbar_exp_t_even[c_group - 1];
|
||||
c_even = (check_char - dbar_exp_g_sum[c_group - 1]) % dbar_exp_t_even[c_group - 1];
|
||||
|
||||
getRSSwidths(widths, c_odd, modules_odd_exp[c_group - 1], 4, widest_odd_exp[c_group - 1], 0);
|
||||
getRSSwidths(widths, c_odd, dbar_exp_modules_odd[c_group - 1], 4, dbar_exp_widest_odd[c_group - 1], 0);
|
||||
check_widths[0] = widths[0];
|
||||
check_widths[2] = widths[1];
|
||||
check_widths[4] = widths[2];
|
||||
check_widths[6] = widths[3];
|
||||
getRSSwidths(widths, c_even, modules_even_exp[c_group - 1], 4, widest_even_exp[c_group - 1], 1);
|
||||
getRSSwidths(widths, c_even, dbar_exp_modules_even[c_group - 1], 4, dbar_exp_widest_even[c_group - 1], 1);
|
||||
check_widths[1] = widths[0];
|
||||
check_widths[3] = widths[1];
|
||||
check_widths[5] = widths[2];
|
||||
@ -1421,7 +1424,7 @@ INTERNAL int dbar_exp_cc(struct zint_symbol *symbol, unsigned char source[], int
|
||||
for (i = 0; i < codeblocks; i++) {
|
||||
k = p + i;
|
||||
for (j = 0; j < 5; j++) {
|
||||
elements[(21 * i) + j + 10] = finder_pattern_exp[((finder_sequence[k] - 1) * 5) + j];
|
||||
elements[(21 * i) + j + 10] = dbar_exp_finder_pattern[((dbar_exp_finder_sequence[k] - 1) * 5) + j];
|
||||
}
|
||||
}
|
||||
|
||||
|
152
backend/rss.h
@ -1,7 +1,7 @@
|
||||
/* rss.h - Data tables for Reduced Space Symbology */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2007-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2007-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -34,31 +34,31 @@
|
||||
#define Z_RSS_H
|
||||
|
||||
/* RSS-14 Tables */
|
||||
static const unsigned short g_sum_table[9] = {
|
||||
static const unsigned short dbar_g_sum_table[9] = {
|
||||
0, 161, 961, 2015, 2715, 0, 336, 1036, 1516
|
||||
};
|
||||
|
||||
static const char t_table[9] = {
|
||||
static const char dbar_t_table[9] = {
|
||||
1, 10, 34, 70, 126, 4, 20, 48, 81
|
||||
};
|
||||
|
||||
static const char modules_odd[9] = {
|
||||
static const char dbar_modules_odd[9] = {
|
||||
12, 10, 8, 6, 4, 5, 7, 9, 11
|
||||
};
|
||||
|
||||
static const char modules_even[9] = {
|
||||
static const char dbar_modules_even[9] = {
|
||||
4, 6, 8, 10, 12, 10, 8, 6, 4
|
||||
};
|
||||
|
||||
static const char widest_odd[9] = {
|
||||
static const char dbar_widest_odd[9] = {
|
||||
8, 6, 4, 3, 1, 2, 4, 6, 8
|
||||
};
|
||||
|
||||
static const char widest_even[9] = {
|
||||
static const char dbar_widest_even[9] = {
|
||||
1, 3, 5, 6, 8, 7, 5, 3, 1
|
||||
};
|
||||
|
||||
static const char finder_pattern[45] = {
|
||||
static const char dbar_finder_pattern[45] = {
|
||||
3, 8, 2, 1, 1,
|
||||
3, 5, 5, 1, 1,
|
||||
3, 3, 7, 1, 1,
|
||||
@ -70,42 +70,42 @@ static const char finder_pattern[45] = {
|
||||
1, 3, 9, 1, 1
|
||||
};
|
||||
|
||||
static const char checksum_weight[32] = {
|
||||
/* Table 5 */
|
||||
1, 3, 9, 27, 2, 6, 18, 54,
|
||||
4, 12, 36, 29, 8, 24, 72, 58,
|
||||
/* Table 5 */
|
||||
static const char dbar_checksum_weight[32] = {
|
||||
1, 3, 9, 27, 2, 6, 18, 54,
|
||||
4, 12, 36, 29, 8, 24, 72, 58,
|
||||
16, 48, 65, 37, 32, 17, 51, 74,
|
||||
64, 34, 23, 69, 49, 68, 46, 59
|
||||
};
|
||||
|
||||
/* RSS Limited Tables */
|
||||
static const unsigned short t_even_ltd[7] = {
|
||||
static const unsigned short dbar_ltd_t_even[7] = {
|
||||
28, 728, 6454, 203, 2408, 1, 16632
|
||||
};
|
||||
|
||||
static const char modules_odd_ltd[7] = {
|
||||
static const char dbar_ltd_modules_odd[7] = {
|
||||
17, 13, 9, 15, 11, 19, 7
|
||||
};
|
||||
|
||||
static const char modules_even_ltd[7] = {
|
||||
static const char dbar_ltd_modules_even[7] = {
|
||||
9, 13, 17, 11, 15, 7, 19
|
||||
};
|
||||
|
||||
static const char widest_odd_ltd[7] = {
|
||||
static const char dbar_ltd_widest_odd[7] = {
|
||||
6, 5, 3, 5, 4, 8, 1
|
||||
};
|
||||
|
||||
static const char widest_even_ltd[7] = {
|
||||
static const char dbar_ltd_widest_even[7] = {
|
||||
3, 4, 6, 4, 5, 1, 8
|
||||
};
|
||||
|
||||
static const char checksum_weight_ltd[28] = {
|
||||
/* Table 7 */
|
||||
1, 3, 9, 27, 81, 65, 17, 51, 64, 14, 42, 37, 22, 66,
|
||||
20, 60, 2, 6, 18, 54, 73, 41, 34, 13, 39, 28, 84, 74
|
||||
/* Table 7 */
|
||||
static const char dbar_ltd_checksum_weight[28] = {
|
||||
1, 3, 9, 27, 81, 65, 17, 51, 64, 14, 42, 37, 22, 66,
|
||||
20, 60, 2, 6, 18, 54, 73, 41, 34, 13, 39, 28, 84, 74
|
||||
};
|
||||
|
||||
static const char finder_pattern_ltd[1246] = {
|
||||
static const char dbar_ltd_finder_pattern[1246] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1,
|
||||
@ -198,59 +198,59 @@ static const char finder_pattern_ltd[1246] = {
|
||||
};
|
||||
|
||||
/* RSS Expanded Tables */
|
||||
static const unsigned short g_sum_exp[5] = {
|
||||
static const unsigned short dbar_exp_g_sum[5] = {
|
||||
0, 348, 1388, 2948, 3988
|
||||
};
|
||||
|
||||
static const unsigned short t_even_exp[5] = {
|
||||
static const unsigned char dbar_exp_t_even[5] = {
|
||||
4, 20, 52, 104, 204
|
||||
};
|
||||
|
||||
static const char modules_odd_exp[5] = {
|
||||
static const char dbar_exp_modules_odd[5] = {
|
||||
12, 10, 8, 6, 4
|
||||
};
|
||||
|
||||
static const char modules_even_exp[5] = {
|
||||
static const char dbar_exp_modules_even[5] = {
|
||||
5, 7, 9, 11, 13
|
||||
};
|
||||
|
||||
static const char widest_odd_exp[5] = {
|
||||
static const char dbar_exp_widest_odd[5] = {
|
||||
7, 5, 4, 3, 1
|
||||
};
|
||||
|
||||
static const char widest_even_exp[5] = {
|
||||
static const char dbar_exp_widest_even[5] = {
|
||||
2, 4, 5, 6, 8
|
||||
};
|
||||
|
||||
static const unsigned short checksum_weight_exp[184] = {
|
||||
/* Table 14 */
|
||||
1, 3, 9, 27, 81, 32, 96, 77,
|
||||
20, 60, 180, 118, 143, 7, 21, 63,
|
||||
189, 145, 13, 39, 117, 140, 209, 205,
|
||||
193, 157, 49, 147, 19, 57, 171, 91,
|
||||
62, 186, 136, 197, 169, 85, 44, 132,
|
||||
185, 133, 188, 142, 4, 12, 36, 108,
|
||||
113, 128, 173, 97, 80, 29, 87, 50,
|
||||
150, 28, 84, 41, 123, 158, 52, 156,
|
||||
46, 138, 203, 187, 139, 206, 196, 166,
|
||||
76, 17, 51, 153, 37, 111, 122, 155,
|
||||
43, 129, 176, 106, 107, 110, 119, 146,
|
||||
16, 48, 144, 10, 30, 90, 59, 177,
|
||||
static const unsigned char dbar_exp_checksum_weight[184] = {
|
||||
1, 3, 9, 27, 81, 32, 96, 77,
|
||||
20, 60, 180, 118, 143, 7, 21, 63,
|
||||
189, 145, 13, 39, 117, 140, 209, 205,
|
||||
193, 157, 49, 147, 19, 57, 171, 91,
|
||||
62, 186, 136, 197, 169, 85, 44, 132,
|
||||
185, 133, 188, 142, 4, 12, 36, 108,
|
||||
113, 128, 173, 97, 80, 29, 87, 50,
|
||||
150, 28, 84, 41, 123, 158, 52, 156,
|
||||
46, 138, 203, 187, 139, 206, 196, 166,
|
||||
76, 17, 51, 153, 37, 111, 122, 155,
|
||||
43, 129, 176, 106, 107, 110, 119, 146,
|
||||
16, 48, 144, 10, 30, 90, 59, 177,
|
||||
109, 116, 137, 200, 178, 112, 125, 164,
|
||||
70, 210, 208, 202, 184, 130, 179, 115,
|
||||
134, 191, 151, 31, 93, 68, 204, 190,
|
||||
148, 22, 66, 198, 172, 94, 71, 2,
|
||||
6, 18, 54, 162, 64, 192, 154, 40,
|
||||
120, 149, 25, 75, 14, 42, 126, 167,
|
||||
79, 26, 78, 23, 69, 207, 199, 175,
|
||||
103, 98, 83, 38, 114, 131, 182, 124,
|
||||
161, 61, 183, 127, 170, 88, 53, 159,
|
||||
55, 165, 73, 8, 24, 72, 5, 15,
|
||||
45, 135, 194, 160, 58, 174, 100, 89
|
||||
70, 210, 208, 202, 184, 130, 179, 115,
|
||||
134, 191, 151, 31, 93, 68, 204, 190,
|
||||
148, 22, 66, 198, 172, 94, 71, 2,
|
||||
6, 18, 54, 162, 64, 192, 154, 40,
|
||||
120, 149, 25, 75, 14, 42, 126, 167,
|
||||
79, 26, 78, 23, 69, 207, 199, 175,
|
||||
103, 98, 83, 38, 114, 131, 182, 124,
|
||||
161, 61, 183, 127, 170, 88, 53, 159,
|
||||
55, 165, 73, 8, 24, 72, 5, 15,
|
||||
45, 135, 194, 160, 58, 174, 100, 89
|
||||
};
|
||||
|
||||
static const char finder_pattern_exp[60] = {
|
||||
/* Table 15 */
|
||||
/* Table 15 */
|
||||
static const char dbar_exp_finder_pattern[60] = {
|
||||
1, 8, 4, 1, 1,
|
||||
1, 1, 4, 8, 1,
|
||||
3, 6, 4, 1, 1,
|
||||
@ -265,31 +265,31 @@ static const char finder_pattern_exp[60] = {
|
||||
1, 1, 9, 2, 2
|
||||
};
|
||||
|
||||
static const char finder_sequence[198] = {
|
||||
/* Table 16 */
|
||||
1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 6, 3, 8, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 10, 3, 8, 5, 0, 0, 0, 0, 0, 0,
|
||||
1, 10, 3, 8, 7, 12, 0, 0, 0, 0, 0,
|
||||
1, 10, 3, 8, 9, 12, 11, 0, 0, 0, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 10, 9, 0, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 0,
|
||||
1, 2, 3, 4, 5, 8, 7, 10, 9, 12, 11
|
||||
/* Table 16 */
|
||||
static const char dbar_exp_finder_sequence[198] = {
|
||||
1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 6, 3, 8, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 10, 3, 8, 5, 0, 0, 0, 0, 0, 0,
|
||||
1, 10, 3, 8, 7, 12, 0, 0, 0, 0, 0,
|
||||
1, 10, 3, 8, 9, 12, 11, 0, 0, 0, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 10, 9, 0, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 0,
|
||||
1, 2, 3, 4, 5, 8, 7, 10, 9, 12, 11
|
||||
};
|
||||
|
||||
static const char weight_rows[210] = {
|
||||
0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 5, 6, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 9, 10, 3, 4, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 17, 18, 3, 4, 13, 14, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 17, 18, 3, 4, 13, 14, 11, 12, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 17, 18, 3, 4, 13, 14, 15, 16, 21, 22, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 15, 16, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 19, 20, 21, 22, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 11, 12, 17, 18, 15, 16, 21, 22, 19, 20
|
||||
static const char dbar_exp_weight_rows[210] = {
|
||||
0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 5, 6, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 9, 10, 3, 4, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 17, 18, 3, 4, 13, 14, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 17, 18, 3, 4, 13, 14, 11, 12, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 17, 18, 3, 4, 13, 14, 15, 16, 21, 22, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 15, 16, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 19, 20, 21, 22, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 11, 12, 17, 18, 15, 16, 21, 22, 19, 20
|
||||
};
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
223
backend/svg.c
@ -1,7 +1,7 @@
|
||||
/* svg.c - Scalable Vector Graphics */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -35,6 +35,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "filemem.h"
|
||||
#include "output.h"
|
||||
#include "fonts/normal_woff2.h"
|
||||
#include "fonts/upcean_woff2.h"
|
||||
@ -95,27 +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;
|
||||
int error_number = 0;
|
||||
struct filemem fm;
|
||||
struct filemem *const fmp = &fm;
|
||||
float previous_diameter;
|
||||
float radius, half_radius, half_sqrt3_radius;
|
||||
int i;
|
||||
@ -135,7 +136,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);
|
||||
@ -172,72 +172,70 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
|
||||
/* Check for no created vector set */
|
||||
/* E-Mail Christian Schmitz 2019-09-10: reason unknown Ticket #164 */
|
||||
if (symbol->vector == NULL) {
|
||||
strcpy(symbol->errtxt, "681: Vector header NULL");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 681, "Vector header NULL");
|
||||
}
|
||||
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")) {
|
||||
return errtxtf(ZINT_ERROR_FILE_ACCESS, symbol, 680, "Could not open SVG output file (%1$d: %2$s)", fmp->err,
|
||||
strerror(fmp->err));
|
||||
}
|
||||
|
||||
/* Start writing the header */
|
||||
fputs("<?xml version=\"1.0\" standalone=\"no\"?>\n"
|
||||
fm_puts("<?xml version=\"1.0\" standalone=\"no\"?>\n"
|
||||
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
|
||||
fsvg);
|
||||
fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n",
|
||||
fmp);
|
||||
fm_printf(fmp, "<svg width=\"%d\" height=\"%d\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n",
|
||||
(int) ceilf(symbol->vector->width), (int) ceilf(symbol->vector->height));
|
||||
fputs(" <desc>Zint Generated Symbol</desc>\n", fsvg);
|
||||
fm_puts(" <desc>Zint Generated Symbol</desc>\n", fmp);
|
||||
if ((symbol->output_options & EMBED_VECTOR_FONT) && symbol->vector->strings) {
|
||||
fprintf(fsvg, " <style>@font-face {font-family:\"%s\"; src:url(data:font/woff2;base64,%s);}</style>\n",
|
||||
upcean ? "OCRB" : "Arimo", upcean ? upcean_woff2 : normal_woff2);
|
||||
/* Split into `puts()` rather than one very large `printf()` */
|
||||
fm_printf(fmp, " <style>@font-face {font-family:\"%s\"; src:url(data:font/woff2;base64,",
|
||||
upcean ? "OCRB" : "Arimo");
|
||||
fm_puts(upcean ? upcean_woff2 : normal_woff2, fmp);
|
||||
fm_puts(");}</style>\n", fmp);
|
||||
}
|
||||
fprintf(fsvg, " <g id=\"barcode\" fill=\"#%s\">\n", fgcolour_string);
|
||||
fm_printf(fmp, " <g id=\"barcode\" fill=\"#%s\">\n", fgcolour_string);
|
||||
|
||||
if (bg_alpha != 0) {
|
||||
fprintf(fsvg, " <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\"",
|
||||
fm_printf(fmp, " <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\"",
|
||||
(int) ceilf(symbol->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(" <path d=\"", fsvg);
|
||||
fm_puts(" <path d=\"", fmp);
|
||||
while (rect) {
|
||||
if (current_colour && rect->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(" <path d=\"", fsvg);
|
||||
svg_put_opacity_close(fg_alpha, fg_alpha_opacity, 1 /*close*/, fmp);
|
||||
fm_puts(" <path d=\"", fmp);
|
||||
}
|
||||
current_colour = rect->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(" <path d=\"", fsvg);
|
||||
fm_puts(" <path d=\"", fmp);
|
||||
while (hex) {
|
||||
if (previous_diameter != hex->diameter) {
|
||||
previous_diameter = hex->diameter;
|
||||
@ -246,37 +244,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 +284,28 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
|
||||
previous_diameter = circle->diameter;
|
||||
radius = 0.5f * previous_diameter;
|
||||
}
|
||||
fputs(" <circle", fsvg);
|
||||
svg_put_fattrib(" cx=\"", 2, circle->x, fsvg);
|
||||
svg_put_fattrib(" cy=\"", 2, circle->y, fsvg);
|
||||
svg_put_fattrib(" r=\"", circle->width ? 3 : 2, radius, fsvg);
|
||||
fm_puts(" <circle", fmp);
|
||||
svg_put_fattrib(" cx=\"", 2, circle->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,56 +314,47 @@ 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(" <text", fsvg);
|
||||
svg_put_fattrib(" x=\"", 2, string->x, fsvg);
|
||||
svg_put_fattrib(" y=\"", 2, string->y, fsvg);
|
||||
fprintf(fsvg, " text-anchor=\"%s\"", halign);
|
||||
fm_puts(" <text", fmp);
|
||||
svg_put_fattrib(" x=\"", 2, string->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(" </text>\n", fsvg);
|
||||
fm_printf(fmp, " %s\n", html_string);
|
||||
fm_puts(" </text>\n", fmp);
|
||||
string = string->next;
|
||||
}
|
||||
|
||||
fputs(" </g>\n"
|
||||
"</svg>\n", fsvg);
|
||||
fm_puts(" </g>\n"
|
||||
"</svg>\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)) {
|
||||
errtxtf(0, symbol, 682, "Incomplete write to SVG output (%1$d: %2$s)", 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)) {
|
||||
return errtxtf(ZINT_ERROR_FILE_WRITE, symbol, 684, "Failure on closing SVG output file (%1$d: %2$s)",
|
||||
fmp->err, strerror(fmp->err));
|
||||
}
|
||||
|
||||
return error_number;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* telepen.c - Handles Telepen and Telepen numeric */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008-2023 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2008-2024 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -86,7 +86,7 @@ static const char TeleLens[128] = {
|
||||
12, 10, 8, 14, 10, 12, 12, 12, 10, 14, 12, 12, 14, 12, 12, 16
|
||||
};
|
||||
|
||||
INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], int src_len) {
|
||||
INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int i, count, check_digit;
|
||||
int error_number;
|
||||
char dest[1145]; /* 12 (Start) + 69 * 16 (max for DELs) + 16 (Check) + 12 (stop) + 1 = 1145 */
|
||||
@ -96,19 +96,18 @@ INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], int src
|
||||
|
||||
count = 0;
|
||||
|
||||
if (src_len > 69) { /* 16 (Start) + 69 * 16 + 16 (Check) + 16 (Stop) = 1152 */
|
||||
strcpy(symbol->errtxt, "390: Input too long (69 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
if (length > 69) { /* 16 (Start) + 69 * 16 + 16 (Check) + 16 (Stop) = 1152 */
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 390, "Input length %d too long (maximum 69)", length);
|
||||
}
|
||||
/* Start character */
|
||||
memcpy(d, TeleTable['_'], 12);
|
||||
d += 12;
|
||||
|
||||
for (i = 0; i < src_len; i++) {
|
||||
for (i = 0; i < length; i++) {
|
||||
if (source[i] > 127) {
|
||||
/* Cannot encode extended ASCII */
|
||||
strcpy(symbol->errtxt, "391: Invalid character in input data, extended ASCII not allowed");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 391,
|
||||
"Invalid character at position %d in input, extended ASCII not allowed", i + 1);
|
||||
}
|
||||
memcpy(d, TeleTable[source[i]], TeleLens[source[i]]);
|
||||
d += TeleLens[source[i]];
|
||||
@ -138,18 +137,18 @@ INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], int src
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0, 1 /*no_errtxt*/);
|
||||
}
|
||||
|
||||
for (i = 0; i < src_len; i++) {
|
||||
for (i = 0; i < length; i++) {
|
||||
if (source[i] == '\0') {
|
||||
symbol->text[i] = ' ';
|
||||
} else {
|
||||
symbol->text[i] = source[i];
|
||||
}
|
||||
}
|
||||
symbol->text[src_len] = '\0';
|
||||
symbol->text[length] = '\0';
|
||||
return error_number;
|
||||
}
|
||||
|
||||
INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], int src_len) {
|
||||
INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int count, check_digit, glyph;
|
||||
int error_number = 0;
|
||||
int i;
|
||||
@ -159,33 +158,32 @@ INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], int
|
||||
|
||||
count = 0;
|
||||
|
||||
if (src_len > 136) { /* 68*2 */
|
||||
strcpy(symbol->errtxt, "392: Input too long (136 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
if (length > 136) { /* 68*2 */
|
||||
return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 392, "Input length %d too long (maximum 136)", length);
|
||||
}
|
||||
if (!is_sane(SODIUM_X_F, source, src_len)) {
|
||||
strcpy(symbol->errtxt, "393: Invalid character in data (digits and \"X\" only)");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
if ((i = not_sane(SODIUM_X_F, source, length))) {
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 393,
|
||||
"Invalid character at position %d in input (digits and \"X\" only)", i);
|
||||
}
|
||||
|
||||
/* Add a leading zero if required */
|
||||
if (src_len & 1) {
|
||||
memcpy(temp + 1, source, src_len++);
|
||||
if (length & 1) {
|
||||
memcpy(temp + 1, source, length++);
|
||||
temp[0] = '0';
|
||||
} else {
|
||||
memcpy(temp, source, src_len);
|
||||
memcpy(temp, source, length);
|
||||
}
|
||||
temp[src_len] = '\0';
|
||||
to_upper(temp, src_len);
|
||||
temp[length] = '\0';
|
||||
to_upper(temp, length);
|
||||
|
||||
/* Start character */
|
||||
memcpy(d, TeleTable['_'], 12);
|
||||
d += 12;
|
||||
|
||||
for (i = 0; i < src_len; i += 2) {
|
||||
for (i = 0; i < length; i += 2) {
|
||||
if (temp[i] == 'X') {
|
||||
strcpy(symbol->errtxt, "394: Invalid position of X in Telepen data");
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 394, "Invalid odd position %d of \"X\" in Telepen data",
|
||||
i + 1);
|
||||
}
|
||||
|
||||
if (temp[i + 1] == 'X') {
|
||||
|
@ -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)
|
||||
|
@ -1,3 +1,5 @@
|
||||
% backend/tests/README 2024-01-17
|
||||
|
||||
Zint backend test suite
|
||||
-----------------------
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 276 118
|
||||
@ -39,7 +39,7 @@ I 174 6 R
|
||||
I 194 6 R
|
||||
I 202 2 R
|
||||
206 2 R
|
||||
82 18 I 226 2 R
|
||||
92 8 I 226 2 R
|
||||
I 230 4 R
|
||||
I 238 2 R
|
||||
I 244 4 R
|
||||
@ -58,7 +58,7 @@ I 254 2 R
|
||||
(67890) stringwidth pop -2 div 0 rmoveto
|
||||
(67890) show
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
217.3 0.8 moveto
|
||||
215.3 0.8 moveto
|
||||
(5) show
|
||||
/Helvetica findfont 21.4 scalefont setfont
|
||||
246 102.4 moveto
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 276 118
|
||||
@ -39,7 +39,7 @@ I 174 6 R
|
||||
I 194 6 R
|
||||
I 202 2 R
|
||||
206 2 R
|
||||
82 18 I 226 2 R
|
||||
92 8 I 226 2 R
|
||||
I 230 4 R
|
||||
I 238 2 R
|
||||
I 244 4 R
|
||||
@ -58,7 +58,7 @@ I 254 2 R
|
||||
(67890) stringwidth pop -2 div 0 rmoveto
|
||||
(67890) show
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
217.3 0.8 moveto
|
||||
215.3 0.8 moveto
|
||||
(5) show
|
||||
/Helvetica findfont 21.4 scalefont setfont
|
||||
246 102.4 moveto
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 276 118
|
||||
@ -39,7 +39,7 @@ I 96 6 R
|
||||
I 76 6 R
|
||||
I 72 2 R
|
||||
68 2 R
|
||||
82 18 I 48 2 R
|
||||
92 18 I 48 2 R
|
||||
I 42 4 R
|
||||
I 36 2 R
|
||||
I 28 4 R
|
||||
@ -67,7 +67,7 @@ I 20 2 R
|
||||
(67890) show
|
||||
grestore
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
58.7 117.2 moveto
|
||||
60.7 117.2 moveto
|
||||
gsave
|
||||
180 rotate
|
||||
(5) show
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 118 292
|
||||
@ -39,13 +39,13 @@
|
||||
6 202 0 110 R
|
||||
2 210 0 110 R
|
||||
2 214 0 110 R
|
||||
2 234 18 82 R
|
||||
4 238 18 82 R
|
||||
2 246 18 82 R
|
||||
4 252 18 82 R
|
||||
2 258 18 82 R
|
||||
2 262 18 82 R
|
||||
4 270 18 82 R
|
||||
2 234 18 92 R
|
||||
4 238 18 92 R
|
||||
2 246 18 92 R
|
||||
4 252 18 92 R
|
||||
2 258 18 92 R
|
||||
2 262 18 92 R
|
||||
4 270 18 92 R
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
117.2 16.7 moveto
|
||||
gsave
|
||||
@ -67,7 +67,7 @@
|
||||
(67890) show
|
||||
grestore
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
117.2 225.3 moveto
|
||||
117.2 223.3 moveto
|
||||
gsave
|
||||
90 rotate
|
||||
(5) show
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 280 130
|
||||
@ -39,7 +39,7 @@ I 176 6 R
|
||||
I 196 6 R
|
||||
I 204 2 R
|
||||
208 2 R
|
||||
82 24 I 228 2 R
|
||||
92 14 I 228 2 R
|
||||
I 232 4 R
|
||||
I 240 2 R
|
||||
I 246 4 R
|
||||
@ -58,7 +58,7 @@ I 256 2 R
|
||||
(67890) stringwidth pop -2 div 0 rmoveto
|
||||
(67890) show
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
219.3 6.8 moveto
|
||||
217.3 6.8 moveto
|
||||
(5) show
|
||||
/Helvetica findfont 21.4 scalefont setfont
|
||||
248 108.4 moveto
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 118 276
|
||||
@ -39,13 +39,13 @@
|
||||
6 76 8 110 R
|
||||
2 72 8 110 R
|
||||
2 68 8 110 R
|
||||
2 48 18 82 R
|
||||
4 42 18 82 R
|
||||
2 36 18 82 R
|
||||
4 28 18 82 R
|
||||
2 24 18 82 R
|
||||
2 20 18 82 R
|
||||
4 10 18 82 R
|
||||
2 48 8 92 R
|
||||
4 42 8 92 R
|
||||
2 36 8 92 R
|
||||
4 28 8 92 R
|
||||
2 24 8 92 R
|
||||
2 20 8 92 R
|
||||
4 10 8 92 R
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
0.8 267.3 moveto
|
||||
gsave
|
||||
@ -67,7 +67,7 @@
|
||||
(67890) show
|
||||
grestore
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
0.8 58.7 moveto
|
||||
0.8 60.7 moveto
|
||||
gsave
|
||||
270 rotate
|
||||
(5) show
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 238 118
|
||||
@ -26,7 +26,7 @@ I 96 2 R
|
||||
110 8 I 110 2 R
|
||||
I 114 2 R
|
||||
118 2 R
|
||||
82 18 I 134 2 R
|
||||
92 8 I 134 2 R
|
||||
I 138 4 R
|
||||
I 144 4 R
|
||||
I 152 4 R
|
||||
@ -51,7 +51,7 @@ I 216 4 R
|
||||
(123456) stringwidth pop -2 div 0 rmoveto
|
||||
(123456) show
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
125.3 0.8 moveto
|
||||
123.3 0.8 moveto
|
||||
(5) show
|
||||
/Helvetica findfont 21.4 scalefont setfont
|
||||
182 102.4 moveto
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 238 118
|
||||
@ -26,7 +26,7 @@ I 96 2 R
|
||||
110 8 I 110 2 R
|
||||
I 114 2 R
|
||||
118 2 R
|
||||
82 18 I 134 2 R
|
||||
92 8 I 134 2 R
|
||||
I 138 4 R
|
||||
I 144 4 R
|
||||
I 152 4 R
|
||||
@ -51,7 +51,7 @@ I 216 4 R
|
||||
(123456) stringwidth pop -2 div 0 rmoveto
|
||||
(123456) show
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
125.3 0.8 moveto
|
||||
123.3 0.8 moveto
|
||||
(5) show
|
||||
/Helvetica findfont 21.4 scalefont setfont
|
||||
182 102.4 moveto
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 118 238
|
||||
@ -26,22 +26,22 @@
|
||||
2 110 0 110 R
|
||||
2 114 0 110 R
|
||||
2 118 0 110 R
|
||||
2 134 18 82 R
|
||||
4 138 18 82 R
|
||||
4 144 18 82 R
|
||||
4 152 18 82 R
|
||||
2 158 18 82 R
|
||||
2 164 18 82 R
|
||||
4 170 18 82 R
|
||||
2 176 18 82 R
|
||||
2 180 18 82 R
|
||||
2 190 18 82 R
|
||||
2 194 18 82 R
|
||||
2 198 18 82 R
|
||||
4 206 18 82 R
|
||||
2 212 18 82 R
|
||||
4 216 18 82 R
|
||||
2 226 18 82 R
|
||||
2 134 18 92 R
|
||||
4 138 18 92 R
|
||||
4 144 18 92 R
|
||||
4 152 18 92 R
|
||||
2 158 18 92 R
|
||||
2 164 18 92 R
|
||||
4 170 18 92 R
|
||||
2 176 18 92 R
|
||||
2 180 18 92 R
|
||||
2 190 18 92 R
|
||||
2 194 18 92 R
|
||||
2 198 18 92 R
|
||||
4 206 18 92 R
|
||||
2 212 18 92 R
|
||||
4 216 18 92 R
|
||||
2 226 18 92 R
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
117.2 8.7 moveto
|
||||
gsave
|
||||
@ -57,7 +57,7 @@
|
||||
(123456) show
|
||||
grestore
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
117.2 125.3 moveto
|
||||
117.2 123.3 moveto
|
||||
gsave
|
||||
90 rotate
|
||||
(5) show
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 238 114
|
||||
@ -26,7 +26,7 @@ I 96 2 R
|
||||
110 3.2 I 110 2 R
|
||||
I 114 2 R
|
||||
118 2 R
|
||||
86.8 13.2 I 134 2 R
|
||||
96.8 3.2 I 134 2 R
|
||||
I 138 4 R
|
||||
I 144 4 R
|
||||
I 152 4 R
|
||||
@ -51,7 +51,7 @@ I 216 4 R
|
||||
(123456) stringwidth pop -2 div 0 rmoveto
|
||||
(123456) show
|
||||
/Helvetica findfont 12.84 scalefont setfont
|
||||
125.3 0.56 moveto
|
||||
123.3 0.56 moveto
|
||||
(5) show
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
182 102.28 moveto
|
||||
|
@ -1,5 +1,5 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: Zint 2.12.0.9
|
||||
%%Creator: Zint 2.13.0.9
|
||||
%%Title: Zint Generated Symbol
|
||||
%%Pages: 0
|
||||
%%BoundingBox: 0 0 238 114
|
||||
@ -26,7 +26,7 @@ I 96 2 R
|
||||
110 3.2 I 110 2 R
|
||||
I 114 2 R
|
||||
118 2 R
|
||||
86.8 13.2 I 134 2 R
|
||||
96.8 3.2 I 134 2 R
|
||||
I 138 4 R
|
||||
I 144 4 R
|
||||
I 152 4 R
|
||||
@ -51,7 +51,7 @@ I 216 4 R
|
||||
(123456) stringwidth pop -2 div 0 rmoveto
|
||||
(123456) show
|
||||
/Helvetica findfont 12.84 scalefont setfont
|
||||
125.3 0.56 moveto
|
||||
123.3 0.56 moveto
|
||||
(5) show
|
||||
/Helvetica findfont 14.98 scalefont setfont
|
||||
182 102.28 moveto
|
||||
|
Before Width: | Height: | Size: 162 B After Width: | Height: | Size: 162 B |
Before Width: | Height: | Size: 548 B After Width: | Height: | Size: 548 B |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 330 B After Width: | Height: | Size: 359 B |
BIN
backend/tests/data/gif/ultra_fgbg_hvwsp1_box1_bgfgtrans.gif
Normal file
After Width: | Height: | Size: 367 B |
BIN
backend/tests/data/gif/ultra_fgbg_hvwsp1_box1_bgtrans.gif
Normal file
After Width: | Height: | Size: 367 B |
BIN
backend/tests/data/gif/ultra_fgbg_hvwsp1_box1_fgtrans.gif
Normal file
After Width: | Height: | Size: 367 B |