Compare commits

...

53 Commits

Author SHA1 Message Date
gitlost
c9909d3d91 tests: BWIPP: update CODE128/MAXICODE to use "newencoder"
BWIPP: update to latest
AZTEC/CODE16K/DATAMATRIX: harmonize GS1 and READER_INIT error
  messages
2024-11-12 11:25:22 +00:00
gitlost
88155343bf MAXICODE: maintain current set between segments to prevent invalid
encodation;
  use code set E for padding as well, saves codeword, props Bue
  Jensen (BWIPP PR #279);
  add padding after all segments and limit loops to length to make
  NS compression work better;
  all the above temporary fixes until Bue Jensen's merge request
  with the BWIPP PR #279 algorithm
GUI: expand linux "xcb" platform hack for >= Qt 5.1
2024-11-08 16:54:38 +00:00
gitlost
f1f283d6a1 docs: update doc images and ChangeLog for last commit [705b72] 2024-11-05 23:18:42 +00:00
gitlost
705b7254f2 UPCA/UPCE: descend add-ons to same level as guards following
ISO/IEC 15420:2009 4.3.5 (and BWIPP) and adjust righthand outside
  digit to be 4X/2X instead of 5X/3X (ISO/IEC 15420:2009
  Annex A.2) away from main symbol so as not to touch add-on
  TODO: revisit when standard clarified
2024-11-05 22:50:03 +00:00
gitlost
71b2dc50b7 library: move check for valid UTF-8 after de-escaping
CODE128: fix bad index 0 -> i in `c128_glyph_count()`
2024-10-30 16:37:42 +00:00
gitlost
7e6da28761 tests: test_library: fix snafus from previous commit [5e2044]
(Windows)
2024-10-27 22:19:43 +00:00
gitlost
5e2044ff2e CODE128: reduce extended latch cut-off from 5 to 4 for better
encodation in certain cases (and no pessimizations found so far),
  props lyngklip (BWIPP);
  fix extended char latching when exactly 3 extended chars at end;
  count code set C (not digits) in loop deciding when to
  shift/latch to extended for better estimate
AZTEC: return warning if ECC < 5% (due to bit-stuffing when version
  given); return error if > 22 layers (Zint 26) for Reader
  Initialisation symbol requested for better error message
AZTEC/HANXIN/QRCODE: consolidate different ECC data size tables
  into one indexed by ECC
DBAR_EXP: check for reduced length <= 77 up front for better error
  message
HANXIN: use `malloc()` rather than `z_alloca()` for large binary
  array
QRCODE: `ecc_level` now 0-based (not 1-based)
MICROQR: consolidate different version end routines into one
  `microqr_end()` and use new `microqr_data` table to simplify code
MICROPDF417: use table for max codewords per column
library: centralize all error messages using new `errtxt()`,
  `errtxtf()`, `errtxt_adj()` funcs that protect `symbol->errtxt`
  from overflow, & try to make error messages more consistent
  thru-out, adding more feedback info to many, & use positional
  args "%n$" in prep for l10n (maybe);
  `is_sane/is_sane_lookup()` -> `not_sane/not_sane_lookup()`,
  returning 1-based position (zero on failure) instead of bool;
  `long` ints -> plain `int` (except those dealing with `ftell()`,
  `fread()` etc) as depend on int being 32-bits already
GUI: in "grpDATF.ui" use "PlainText" rather than "RichText" for
  tracker ratio examples as height of text messing up sometimes
manual: clarify Codablock-F length maximum & add examples
docs: README: pandoc 3.5, Ubuntu 24.04
CMake: use "-Wpedantic" for Clang only as GNU complains about
  `errtxtf()` positional args "%n$"
2024-10-27 21:33:33 +00:00
gitlost
752c1fae5d MAXICODE: Zero-pad US postcodes that lack "+4" (Annex B.1.4a)
Adapted from OkapiBarcode, with stricter interpretation (only pad
  if "+4" totally absent), props Daniel Gredler
gs1: update to latest gs1-syntax-dictionary (linter mm -> mi)
bwipp: update to latest
2024-10-09 18:25:38 +01:00
gitlost
c1666cf350 GUI: use X11 (xcb) as platform instead of Wayland on Linux to
avoid various weird behaviours
tests: disable GUI-dependent tests (`TestQZint::renderTest()`) if
  ZINT_SANITIZE and on Linux for later versions of Qt (5 and 6)
  to avoid ASAN "detected memory leaks" errors on exit
2024-10-07 16:04:22 +01:00
gitlost
34be69d241 library: check d/o escape seq value <= 255, better error messages
GUI: cliwindow: `#if _WIN32` -> `#ifdef _WIN32`, add "-Wundef"
  check to cmake
cmake: backend: add C90 (C89) compat compiler check
docs: update "README" pandoc, "README.linux" (Fedora 39 -> 40)
tests: test_png: add some more text examples
2024-09-29 15:18:56 +01:00
gitlost
b42d5baf4c gs1: New AIs 7041 (GSCN 23-272) (packagetype) and 716 (GSCN-24-157)
CODE49: Better error message on ZINT_ERROR_TOO_LONG
manual: Use floating pt notation for floating pt args on options
backend/tools/data: Remove overlooked "GB2312.TXT" from git
raster: `size2` -> `prev_size`; one line `malloc()`s
C25/CODE128: some code fiddling
tests/PNG: Add some more text examples
2024-09-18 03:40:45 +01:00
gitlost
93c3e27fba CODE128: Add minimal encodation algorithm (non-extended ASCII only)
from ZXing (props Alex Geller) - about 25-60% slower depending on
  data & stack heavy but does improve some outcomes when FNC1s
  present (GS1_MODE or manual) although not much else it appears
  (the previous algorithm was very good), but has a logical clarity
  the other lacked - funcs `c128_dxsmooth()` etc shared with
  CODE16K now moved there and renamed as `c16k_`;
  also fix extended char latching when exactly 4 extended chars
  at end
  also manual code set switching now honoured exactly even if
  immediate shift required;
manual: make explicit that AI "(00)" and "(01)" prefixes added by
  Zint are HRT-only
general: add `extern "C"` wrappers to a few header files
2024-09-07 12:44:16 +01:00
gitlost
10747d6385 CODE128: Add new extra escape \^1 for manual insertion of FNC1s,
ticket #324, props Jim Shank;
  also improve encodation for a few limited cases;
  also some code fiddling
BWIPP: update to latest
raster: check for overflow on `size + size2` in `raster_malloc()`
vector: put `malloc()`s on one line for grep ease
docs: pandoc-3.3, clang-tidy-20
2024-09-03 11:55:55 +01:00
gitlost
7f4ccccb98 GS1: update to latest gs1-syntax-dictionary, new AI 8014 (GSCN
21-283) MUDI, and AI 03 MTO GTIN);
  hhmm -> hh,mm, mmoptss -> mm,ss, yymmddhh obsolete
2024-07-30 13:11:15 +01:00
gitlost
3c7a702169 test: BWIPP: add fixedeclevel to PDF417/QRCODE variants when
`eclevel` given; update BWIPP to latest
2024-07-22 23:29:37 +01:00
gitlost
9c701f1009 2nd attempt to fix [857021] - add ZINT_NO_PNG define to tests 2024-07-18 01:38:29 +01:00
gitlost
b3a8680a90 Fix previous commit [857021] - allow for ZINT_NO_PNG 2024-07-18 01:26:31 +01:00
gitlost
857021de84 png: allow for use of zlib-ng, a zlib replacement, by Fedora 40,
by avoiding binary comparison in tests
2024-07-18 01:04:50 +01:00
gitlost
fb3b3001aa - 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
- BWIPP: update to latest
2024-07-11 00:35:13 +01:00
gitlost
7246d67175 gs1/gs1_lint: update to latest gs1-syntax-dictionary, removing
`iso3166list` linter and adjusting all others to allow for
  multiple optional linters (by checking `data_len` vs `offset`)
library: change invalid `input_mode` reset to return warning;
  split func table into 2 - func declarations without prototype
  will be error in C23;
  make invalid symbology check a separate function using a table
  and call near beginning of `ZBarcode_Encode_Segs()`;
  in `ZBarcode_BarcodeName()` save some bytes by simplifying
  name table and removing "BARCODE_" prefix from entries
output: fix pack logic to use pragma by default (actually more
  portable than `__attribute__`)
common.h: remove C99 detection which was artifice of specifying
  "-std=", and rejig layout to be more logical
BWIPP: update to latest version
general: change `ZINT_VERSION_BUILD` tests to `#if`s
general: further fiddling with some tables to save a few bytes
CLI: change function arg `optarg` -> `arg` so doesn't shadow
  global
general: library now compilable with Comp Cert C (though as it
  doesn't support `alloca()` will have multiple memory leaks)
2024-06-27 23:00:13 +01:00
gitlost
d70edce067 iso4217: new ISO 4217 currency code 924 for ZWG (amendment no. 177)
(gs1-syntax-dictionary commit [d64e28d])
  TODO: remove 932 ZWL 1 Sept 2024
2024-06-21 16:31:19 +01:00
gitlost
d97fc7e110 CMake: use "GNUInstallDirs" instead of old (2008) KDE
"SetPaths.cmake" (removed) - resolves absolute paths in
  "zint-targets.cmake", ticket #318, props John Alexander;
  also remove "FindZint.cmake" install as not best practice
  (Daniel Pfeifer “Effective CMake"), but retain in tree for now;
  also remove APPLE stuff re UNIVERSAL build, obsolete, and
  setting of CMAKE_OSX_SYSROOT, seems unnecessary
2024-06-21 15:18:00 +01:00
gitlost
04e8cacb81 gs1: Update to latest version of gs1-syntax-dictionary with new AIs
7250-7259 (GSCN 22-246), new checkers `yyyymmdd()`, `iso5218()`,
  `posinseqslash()`; allow for new "?" flag in "gen_gs1_lint.php"
2024-05-29 22:52:34 +01:00
gitlost
83fe2f3fee getopt: fix previous #ifdef 1 -> #if 1 2024-05-28 02:48:08 +01:00
gitlost
a1aefdc50b test_library: suppress size_t -> int warning
getopt: suppress `-Wdeprecated-non-prototype` warnings
2024-05-28 02:39:49 +01:00
gitlost
eb035a6372 GUI: fix foreground/background picker invocations (broken
[f3a982c1dd199a1a02b32d698844b2257c23f01b])
AZTEC/CODE16K/CODEONE/DATAMATRIX/DBAR_EXP/GRIDMATRIX/HANXIN
/MAILMARK_4S/PDF417/MSI_PLESSEY/QRCODE/RMQR/TIF/ULTRA/USPS_IMAIL:
  lessen storage of some tables by using least integral size
  required (saves ~3K); reformat some tables, comments
AUSPOST/AZTEC: remove unnecessary int casts on array indexing
CODE11/CODE39: move start/stop chars into one entry in tables to
  save a few bytes; some reformatting, comments
CODEONE: add `c1_` prefixes
common: more precise compiler/version checks
composite: add `cc_` prefixes; UINT -> unsigned short; use
  `sizeof()` instead of `strlen()` for `in_linear_comp` static;
  some reformatting, comments
EMF: use table instead of string for `ultra_chars[]`
GIF: remove unnecessary cast
library: use `sizeof()` instead of `strlen()` for static;
  add `consts` to `escape_char_process()` & use unsigned for `ch`
DBAR: use `dbar_`, `dbar_ltd_`, `dbar_exp_` prefixes
docs: update pandoc version
2024-05-27 23:19:45 +01:00
gitlost
0a00d04ccc CMakeLists.txt: check against c not c++ (CheckCXX -> CheckC etc)
BMP/EMF/PCX/TIF: use more portable packed attribute instead of
  pragma if not MSVC
CHANNEL: pass ptr not struct to `channel_copy_precalc()`
2024-05-27 20:55:04 +01:00
gitlost
3960dfdbfc AZTEC: workaround MSVC optimizer deciding not to emit code for
inner top/right/bottom/left loops of `az_populate_map()` by
  jiggling them around a bit, ticket #317, props Andre Maute
frontend/tests: clean up any directories created in `test_input()`,
  ticket #316, props Andre Maute
2024-05-27 03:06:27 +01:00
Philip Ye
c8bb299908 Fix legacy width and security level getters/setters in Qt backend
Previously, width is option 2 and security level is option 1.
Seems like in 54947fb4359b01445eb5b8ee456c5acf7a980acb, the definitions
swapped and that breaks the legacy Qt application using setWidth() and
setSecurityLevel().

I know a better solution is make Qt application use setOption2() and
setOption1() respectively, but it's good to keep these legacy APIs
backward-compatible.
2024-05-23 22:46:26 +12:00
gitlost
0eaa9f3e7d GUI: about box: display QSettings config location 2024-03-07 17:03:56 +00:00
gitlost
5390c0df92 GUI: factory reset: reset preview background colour also 2024-03-07 14:16:22 +00:00
gitlost
bdb4fcbcf8 README.macos/windows: fix modified date year 2014 -> 2024 2024-03-07 13:59:09 +00:00
gitlost
55a7369cd8 output: out_fopen() fix _WIN32 def check (ticket #313, props
Axel Waggershauser)
2024-03-05 22:15:00 +00:00
gitlost
624574a64c As get_best_eci() can no longer return 0 remove caller checks
library: simplify dealing one-letter escapes into one case;
  other fiddlings (`first_err` -> `warn_number`)
2024-03-05 22:09:05 +00:00
gitlost
11b3c18aed ECI: get_best_eci(): just assert is_valid_utf8() as checked
prior to being called
manual: update to latest GS1 General Specifications (v24), pandoc
  (3.1.12.1)
2024-02-28 02:57:43 +00:00
gitlost
f0d8901d9e QRCODE: check fopen() return in ZINTLOG debugging code
(ticket #181, props Stf Ortm)
CODE128: suppress gcc -Wmaybe-uninitialized false positive (Release
  only)
CLI: add "isbn" synonym; save a few bytes using `char[]` rather
  than `char *`
2024-02-27 13:36:13 +00:00
gitlost
f312cdf630 CODE128: simplify bitmask in qr_add_version_info() (ticket #110,
props Daniel Gredler);
  check for next shift rather than next in `c128_dxsmooth()` to
  improve encodation on A/B shifting, props Daniel Gredler (Okapi)
2024-02-10 16:08:18 +00:00
gitlost
e167f5b534 test suite: zxing-cpp: adjust for returnCodabarStartEnd no-op;
allow for old "libpng" (`png_set_scale_16()` not available)
general: Solaris compat
library: use proper function ptr instead of `void *` for function
  table; warning suppression "-Wpedantic" -> "-Wstrict-prototypes"
GRIDMATRIX/HANXIN/QRCODE: `xx_define_mode()`: multi-dim `char_modes`
2024-02-06 13:01:35 +00:00
gitlost
7b41dfbee2 - ITF14/DPLEIT/DPIDENT: ignore option_2 (check digit options)
- GUI: scalewindow: fix cropping resolution on initial setup
  (`spnResolution` max 1000 -> 254000) and bound X-dim to <= 10 in
  `set_maxima()`
- GUI: mainwindow: bound X-dim as above and clamp `m_xdimdpVars`
  members on initial load from INI
- GUI: undo `QString::mid()` -> `QString::midRef()` from clazy
  & explicitly include "QObject" in "qzint.h" (not Qt6 compatible)
2024-01-25 00:10:34 +00:00
gitlost
7c1bdba8ae output: use doubles when converting in out_colour_get_rgb()
and `out_colour_get_cmyk()`, to lessen chances of rounding
  errors (in particular for VC6)
test_large: fix regression in change to test for formatting
  `uint64_t` for `printf()`
win32/README: update MinGW/MSYS Qt version
2024-01-19 09:28:03 +00:00
gitlost
57fac4048d frontend/CMake: fix HAVE_GETOPT -> HAVE_GETOPT_LONG_ONLY 2024-01-17 22:04:18 +00:00
gitlost
1449866d18 CMake: check for getopt_long_only() instead of just getopt()
so behaviour of CLI same
general: AIX compat, suppress some warnings
2024-01-17 21:55:11 +00:00
gitlost
bead450f38 - BMP/EMF/PCX/TIF: fix endianness on big-endian machines (note TIF
now always written as little-endian - simplifies testing)
- READMEs: add date updated
2024-01-17 01:45:45 +00:00
gitlost
cf04ac15b0 general: use explicit float consts rather than calced ones
manual: remove extra tags from "manual.txt" and clean up table
  captions
2024-01-09 18:38:21 +00:00
gitlost
f3a982c1dd fuzz.h: fix upper/lowercase flags
GUI: suppress clazy warnings
2024-01-05 22:55:57 +00:00
gitlost
d42eb13841 AZTEC: change max byte count from assert() to if as overlong data
can trigger it (fuzz_data (1st))
2024-01-04 22:43:41 +00:00
gitlost
3cb724253b Add fuzz stuff ("backend/tests/fuzz"), including OSS-Fuzz
"Dockerfile" etc
PDF417: lessen some debug verbosity
gif: use "gif_" prefix; some code fiddling
2024-01-04 20:11:04 +00:00
gitlost
2a55ba0cef GUI/manual/man page: bump year 2023 -> 2024 2024-01-01 13:26:49 +00:00
gitlost
f37831bfef GUI: About box: make smaller so fits on screen in most situations
by removing "Currently supported standards" box (which was
  pretty unreadable anyway)
2024-01-01 13:07:53 +00:00
gitlost
3950b49050 filemem: fix fwrite() return check in fm_write();
test `ferror()` also in `fm_err()` if `err` zero and file
NetBSD: add instructions and some workarounds (`getopt_long_only()`
  in particular)
qzint: check `__GNUC__` version for "-Wstringop-truncation"
  suppression
2023-12-29 19:34:44 +00:00
gitlost
98f86727cc Add BARCODE_MEMORY_FILE to symbol->output_options to allow
outputting to in-memory buffer `symbol->memfile` instead of to
  file `symbol->outfile`, ticket #301
Add "README.clang-tidy" and ".clang-tidy" options file
Suppress some warnings
2023-12-27 19:20:19 +00:00
gitlost
070162214b - raster/BMP/GIF/PCX/TIF: fix dealing with very large data (use
`size_t` as appropriate)
- BMP: lessen heap memory usage by only `malloc()`ing a row, not
  whole file
- GIF: lessen heap memory usage by paging (also simplifies some
  function returns); use standard colour char map
- raster: add `raster_malloc()` to fail > 1GB (avoids very large
  output files that most systems can't handle; 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
2023-12-22 21:29:54 +00:00
gitlost
6ff485e6fa Bump version to 2.13.0.9 (dev) 2023-12-18 10:28:14 +00:00
300 changed files with 19631 additions and 22486 deletions

3
.clang-tidy Normal file
View File

@ -0,0 +1,3 @@
---
Checks: 'clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-clang-analyzer-security.insecureAPI.strcpy'
HeaderFilterRegex: '.*'

View File

@ -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")

View File

@ -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)

View File

@ -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
View 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

View File

@ -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

View File

@ -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
==============================================

View File

@ -1 +1,2 @@
% README.windows 2024-01-17
See "README" in the "win32" sub-directory.

View File

@ -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)

View File

@ -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++) {

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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 : */

View File

@ -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
};

File diff suppressed because it is too large Load Diff

View File

@ -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];

View File

@ -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);

View File

@ -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) */

View File

@ -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 : */

View File

@ -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

View File

@ -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;

View File

@ -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, },

View File

@ -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 : */

View File

@ -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 : */

View File

@ -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;
}

View File

@ -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++;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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
View 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
View 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 */

View File

@ -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;

View File

@ -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;

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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);

View File

@ -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 : */

View File

@ -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;

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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 : */

View File

@ -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
}

View File

@ -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;

View File

@ -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 */

View File

@ -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) {

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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 : */

File diff suppressed because it is too large Load Diff

View File

@ -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,

View File

@ -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);

View File

@ -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];
}
}

View File

@ -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 : */

View File

@ -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 : */

View File

@ -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') {

View File

@ -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)

View File

@ -1,3 +1,5 @@
% backend/tests/README 2024-01-17
Zint backend test suite
-----------------------

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Some files were not shown because too many files have changed in this diff Show More