Skip to content

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

Open
changhee-somite wants to merge 1 commit intoseqscope:mainfrom
changhee-somite:fix/enable-libpng-for-large-images
Open

Enable native libpng support to fix truncated PNG output for large images#28
changhee-somite wants to merge 1 commit intoseqscope:mainfrom
changhee-somite:fix/enable-libpng-for-large-images

Conversation

@changhee-somite
Copy link

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