Skip to content

Upgrade bundled third-party libraries (zlib, libpng, libjpeg, libtiff, FreeType) - #222

Open
FabienMathieu wants to merge 10 commits into
MicBosi:masterfrom
FabienMathieu:chore/upgrade-third-party
Open

FabienMathieu wants to merge 10 commits into
MicBosi:masterfrom
FabienMathieu:chore/upgrade-third-party

Conversation

@FabienMathieu

Copy link
Copy Markdown
Contributor

Summary

The libraries bundled in src/external/ were 10 to 28 years old, and VL no longer built with current toolchains. On recent macOS SDKs the old zlib, libpng and FreeType took classic Mac OS code paths, and libtiff's VERSION file shadowed the C++ <version> header. This PR replaces each library with its current upstream release, without patching any vendored code.

Library Old version (release date) New version (release date)
zlib 1.2.8 (2013-04-28) 1.3.2 (2026-02-17)
libpng 1.2.56 (2015-12-17) 1.6.59 (2026-09-28)
libjpeg 6b (1998-03-27) 9f (2024-01-14)
libtiff 3.8.2 (2006-03-23) 4.7.2 (2026-06-27)
FreeType 2.4.12 (2013-05-08) 2.15.0 (2026-10-12)

All downloads were verified. zlib and libpng match their published SHA-256 checksums, libtiff and FreeType have valid GPG signatures, and libjpeg matches the SHA-256 recorded by Homebrew.

Changes

  • CMake
    • cmake_minimum_required(VERSION 3.5...3.31) lets CMake 4 configure without extra flags.
    • Removed the obsolete cmake/ParseArguments.cmake, which overrode a built-in command and broke CMake's own modules.
    • New cmake/ThirdParty.cmake holds the platform checks and shared target settings: PIC, MSVC defines, and warnings off for third-party code.
  • zlib 1.3.2: drop-in replacement with no API change.
  • libpng 1.6.59
    • ioPNG.cpp uses png_sig_cmp and proper setjmp/png_longjmp error handling, since libpng 1.6 aborts if the error handler returns.
    • SIMD optimisations are disabled, so no per-architecture sources are needed.
  • libjpeg 9f
    • One jconfig.h is shared by libjp on every platform, so they agree onboolean`.
    • The directory was renamed from `jp
  • libtiff 4.7.2
    • ioTIFF.cpp is ported to the 4.x off_t, uint32_t/uint16_t`.
    • Config headers are generated by CMake from the upstream templates, and tif_win32.c is used on
      Windows.
  • FreeType 2.15.0
    • The source list follows upstream.
    • Dropped ftmac.c and the AppKit link; VL loads fonts from memory.
  • Bug fixes
    • Corrupt JPEGs crashed the application (segfault), and a failed JPEG save called exit(). Both now return an error. Corrupt PNGs are hand
    • VL_TRAP uses __builtin_trap() on non-x86 targets, which fixes arm64 builds.
    • A stray line in `GLFunctionList.hp
  • CI: new GitHub Actions workflow covering Linux GCC, Linux Clang, macOS and Windows MSVC, each in
    Debug/Release and shared/static.
  • Docs: src/external/README.md lists the bundled versions and the upgrade procedure.

Testing

  • macOS (arm64): Debug shared, Release shared and Debug static build with no warnings from the
    bundled code.
  • Linux (Ubuntu 24.04): GCC 13 and Clang 18, Debug shared and Release static.
  • Runtime test (macOS and Linux)
    • PNG, JPEG and TIFF load/save round trips, including cross-format.
    • Corrupt and truncated files are re
    • A gzip round trip works, and FreeType renders a glyph.
  • Windows (MSVC): not tested localworkflow.

Notes

  • libjpeg 10 (2026-01-25) was evaluatee tests without VL changes, but addsnothing for 8-bit images, so the PR stays on 9f. - Linux builds need libglu1-mesa-devecule uses GLU.
  • Branches that use FreeType bitmap fields may need (int) casts, because FT_Bitmap::rows/width are now unsigned.

Fabien MATHIEU added 10 commits October 29, 2026 17:03
…cludes

- Call cmake_minimum_required(VERSION 3.5...3.31) before project() so
  CMake 4 configures without -DCMAKE_POLICY_VERSION_MINIMUM.
- Remove the bundled ParseArguments.cmake: it overrode the built-in
  cmake_parse_arguments and broke modules such as CheckTypeSize.
- Add cmake/ThirdParty.cmake with platform checks and a
  VL_THIRDPARTY_TARGET() helper for the bundled libraries.
- Remove include_directories() in vlCore/plugins that pointed to a
  non-existent path.
Vendor only the library sources, headers, LICENSE, README and ChangeLog
from the official release (SHA-256 checked against zlib.net). Upstream
no longer treats modern macOS as classic Mac OS (fdopen defined as NULL),
and HAVE_UNISTD_H/HAVE_STDARG_H now come from configure checks.
- Vendor the library sources/headers plus the upstream prebuilt
  pnglibconf.h (SHA-256 checked against the SourceForge release).
- Build without SIMD filter code on all architectures so no
  per-architecture sources are needed.
- ioPNG: png_check_sig() was removed, use png_sig_cmp(). Re-enable
  setjmp error recovery, which libpng 1.6 requires (otherwise it aborts
  on corrupt files). The setjmp calls live in helpers that hold no C++
  objects with destructors, so longjmp is well-defined. Errors while
  saving now return false instead of aborting.
- Vendor the library sources/headers into src/external/libjpeg (SHA-256
  checked against the Homebrew formula for jpegsrc.v9f).
- Source list follows upstream makefile.vc (adds arithmetic coding,
  drops the 6b progressive/reduced IDCT files merged into others).
- A single VL-owned jconfig.h (from upstream jconfig.vc) is used on all
  platforms so libjpeg, libtiff and ioJPG.cpp agree on 'boolean'. The
  old VL edits to jmorecfg.h are no longer needed: libjpeg 9 handles
  the Windows INT32 clash itself.
- ioJPG: always request RGB output for colour images so libjpeg 9's
  BG_RGB/BG_YCC colour spaces are converted instead of tripping a check.
- Vendor only the upstream libtiff/ subdirectory (GPG signature
  verified). Without the top-level VERSION file in an include
  directory, <version> is no longer shadowed on case-insensitive file
  systems (macOS, Windows).
- Generate tif_config.h/tiffconf.h from the upstream .cmake.in templates
  with platform checks, instead of the hard-coded 3.8.2 headers (which
  e.g. assumed 32-bit long and never included unistd.h).
- Use tif_win32.c on Windows and tif_unix.c elsewhere, as upstream does.
- Link TIFF against ZLib and JPG to get their include paths.
- ioTIFF: use the 4.x callback signatures (tmsize_t, 64-bit toff_t)
  without truncating casts, and uint32_t/uint16_t instead of the
  deprecated libtiff typedefs.
- Vendor include/, the src/ modules in upstream's default build, and the
  licence files (GPG signature verified).
- Source list follows upstream BASE_SRCS (adds sdf, svg, hvf, bzip2
  stub; drops ftxf86, ftlcdfil, gxvalid and otvalid, which were never
  registered in ftmodule.h). Uses the portable ANSI ftsystem.c on every
  platform.
- Drop base/ftmac.c and the AppKit link on macOS: it only provides the
  deprecated Carbon font APIs, and VL loads fonts from memory.
- Stock ftoption.h: no new external dependencies. The internal zlib copy
  used for .gz fonts no longer has the classic Mac OS issues.

No VL source changes needed: Font.cpp's FT_ERRORDEF table still works
with FreeType 2.15's fterrors.h.
ioJPG installed an error_exit handler that longjmp'd to a jmp_buf whose
setjmp() was disabled (#if 0), so any corrupt or truncated JPEG
segfaulted. saveJPG used the default handler, which calls exit().
Both paths now run libjpeg inside helpers that set up setjmp() and hold
no C++ objects, mirroring ioPNG, and return NULL/false on error.

ioPNG's error callback now longjmps itself, so libpng doesn't print
each error a second time.

Verified with truncated and corrupted PNG, JPEG and TIFF files.
Builds Debug/Release, shared/static with GCC and Clang on Linux, Apple
Clang on macOS and MSVC on Windows.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant