Skip to content

Support GIF output and palette PNG output - #51

Merged
zoellner merged 2 commits into
mainfrom
feature/gif-palette-png-output
Oct 9, 2026
Merged

zoellner merged 2 commits into
mainfrom
feature/gif-palette-png-output

Conversation

@zoellner

@zoellner zoellner commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Fixes #13.

Problem

Saving a GIF fails with VipsOperation: class "gifsave_buffer" not found, and png({ palette: true }) quietly writes a truecolour PNG. Stock sharp (prebuilt binaries) supports both, so switching to this layer silently drops them.

libvips 8.18 writes GIF files through cgif, and its meson.build only looks for cgif once an image quantiser (libimagequant or quantizr) has been found. Palette PNG output needs the same quantiser; without one libvips logs ignoring palette (no quantisation support) and carries on. The layer built neither.

Changes

  • layer/Makefile
    • Build libimagequant 2.4.1 (lovell/libimagequant, the BSD-2-Clause fork used by sharp's prebuilt binaries; upstream 4.x is GPL-3.0) and cgif 0.5.4 (MIT), both from pinned tarballs with SHA256 checks, the same versions sharp-libvips uses.
    • Pass -Dimagequant=enabled -Dcgif=enabled to libvips. Without forcing the quantiser on, a missing libimagequant would quietly disable cgif instead of failing the build.
    • verifyLibvips now also checks for gifsave_buffer.
    • Both libraries are built as shared libraries into /usr/local/lib, and the existing ldd-based step copies them into the layer's lib/.
  • test/layer.test.js
    • The format support test now also covers gif.
    • Resize the synthetic HEIC to GIF and check the size, the GIF89a signature and the quadrant colours.
    • Build a 2-frame animated GIF, then run the pipeline from Can't save GIFs - gifsave_buffer not found #13 on it (sharp(buf, { animated: true }).resize().gif()). Check the frame count and size, and the colours of both frames.
    • Encode a palette PNG and check that the IHDR colour type is 3 (indexed) and isPalette is true. Because libvips silently falls back to truecolour, checking only that the call succeeds would not catch a missing quantiser.
  • README.md: a note on GIF and palette PNG output, plus license and repository entries for cgif and libimagequant.

Testing

  • The new tests pass locally against stock prebuilt sharp 0.35.5, run on a PNG version of the quadrants fixture because stock sharp can't decode HEVC.
  • With palette: true removed, the palette PNG test fails as expected (PNG colour type should be indexed).
  • The full layer build and the tests in the Lambda runtime image run in the Test layer workflow on this PR.

libvips writes GIF files through cgif and only enables cgif when an image
quantiser is available; the same quantiser is needed for palette PNG output.
Neither was built, so gifsave_buffer was missing and png({ palette: true })
was silently ignored.

Build libimagequant 2.4.1 (the BSD-licensed fork used by sharp's prebuilt
binaries) and cgif 0.5.4 from pinned, checksum-verified tarballs, enable both
explicitly in libvips so a missing dependency fails the build, and check for
gifsave_buffer after building libvips.

Add layer tests for static GIF, animated GIF and palette PNG output.

Fixes #13
@zoellner
zoellner merged commit ca2e159 into main Oct 9, 2026
3 checks passed
@zoellner
zoellner deleted the feature/gif-palette-png-output branch October 9, 2026 10:53
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.

Can't save GIFs - gifsave_buffer not found

1 participant