Skip to content

Enable native libpng support to fix truncated PNG output for large images#28

Merged
hyunminkang merged 1 commit into
seqscope:libpng-supportfrom
changhee-somite:fix/enable-libpng-for-large-images
Mar 5, 2026
Merged

Enable native libpng support to fix truncated PNG output for large images#28
hyunminkang merged 1 commit into
seqscope:libpng-supportfrom
changhee-somite:fix/enable-libpng-for-large-images

Conversation

@changhee-somite

Copy link
Copy Markdown

Summary

  • Fix truncated PNG output when processing large images with draw-xy command
  • Enable native libpng support in CImg by adding cimg_use_png compile definition
  • Link against system libpng library

Problem

When cimg_use_png is not defined, CImg falls back to ImageMagick's convert command for PNG encoding. ImageMagick has policy-enforced resource limits (typically 256MP area, 1GiB memory in /etc/ImageMagick-6/policy.xml) that cause silent failures when processing large images.

For example, an 11460×22360 pixel image (256.3 megapixels) exceeds the default 256MP limit, resulting in a truncated PNG file containing only header chunks (IHDR, cHRM, bKGD) but no image data (IDAT) or end marker (IEND). This causes downstream tools like GDAL to fail with ERROR 1: libpng: Read Error.

Root Cause Analysis

Traced via strace:

convert-im6.q16: cache resources exhausted
convert-im6.q16: No IDATs written into file

The CImg → ImageMagick pipeline:

  1. CImg saves temporary PPM file
  2. CImg calls convert -quality 100 /tmp/xxx.ppm output.png
  3. ImageMagick exceeds resource limits and fails silently
  4. CImg sees the (truncated) output file exists and reports success

Solution

Enable native libpng support so CImg writes PNG directly without ImageMagick:

  1. find_package(PNG REQUIRED) - locate system libpng
  2. add_compile_definitions(cimg_use_png) - enable CImg's native PNG code path
  3. Link PNG::PNG to the executable

Test Results

Tested with a 675M line Xenium dataset producing an 11460×22360 PNG:

Metric Before After
PNG file size 91 bytes 98 MB
PNG valid ❌ Truncated ✅ Valid IEND
GDAL processing libpng: Read Error ✅ Success

Test plan

  • Build spatula with -DUSE_LIBDEFLATE=ON
  • Run spatula draw-xy on large dataset (>256 megapixels)
  • Verify output PNG is valid (has IEND marker)
  • Verify GDAL can process the PNG (gdal_translate)

🤖 Generated with Claude Code

…ages

When cimg_use_png is not defined, CImg falls back to ImageMagick's
convert command for PNG encoding. ImageMagick has policy-enforced
resource limits (typically 256MP area, 1GiB memory) that cause silent
failures when processing large images.

For example, an 11460x22360 pixel image (256.3 megapixels) exceeds
the default 256MP limit, resulting in a truncated PNG file with only
the header chunks (IHDR, cHRM, bKGD) but no image data (IDAT) or
end marker (IEND).

This fix:
- Enables find_package(PNG) to locate the system libpng
- Adds cimg_use_png compile definition so CImg uses native libpng
- Links PNG::PNG to the executable

With this change, CImg writes PNG files directly using libpng,
bypassing ImageMagick entirely and eliminating the resource limit
issue.

Tested with a 675M line dataset producing an 11460x22360 PNG:
- Before: 91 bytes (truncated, GDAL fails with "libpng: Read Error")
- After: 98MB valid PNG (GDAL processes successfully)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hyunminkang
hyunminkang changed the base branch from main to libpng-support March 5, 2026 20:14
@hyunminkang
hyunminkang merged commit caa3625 into seqscope:libpng-support Mar 5, 2026
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.

2 participants