Skip to content

feat: YCbCr chroma subsampling for non-JPEG compression#366

Open
lilith wants to merge 1 commit intoimage-rs:mainfrom
lilith:feat/ycbcr-upsampling
Open

feat: YCbCr chroma subsampling for non-JPEG compression#366
lilith wants to merge 1 commit intoimage-rs:mainfrom
lilith:feat/ycbcr-upsampling

Conversation

@lilith
Copy link
Contributor

@lilith lilith commented Mar 11, 2026

Summary

  • Adds YCbCrUpsamplingReader that converts chroma-subsampled block layout (h×v Y samples + shared Cb/Cr) to full-resolution per-pixel (Y, Cb, Cr) triples
  • Wraps the decompressor transparently in expand_chunk() for non-JPEG compression methods
  • JPEG continues to handle its own upsampling internally
  • Planar YCbCr with chroma subsampling remains unsupported (returns ChromaSubsampling error) since the block layout only applies to chunky/interleaved data

Split out from #363 per review request.

Test plan

  • dscf0013.tif (uncompressed, YCbCr 2×1 subsampling): CRC32 hash verified 0x6896e83a
  • ycbcr-cat.tif (LZW, YCbCr 2×2 subsampling): CRC32 hash verified 0x388a9d8f
  • smallliz.tif / zackthecat.tif remain smoke tests (Old JPEG compression type 6, unsupported regardless)
  • All 233 existing tests pass

Add YCbCrUpsamplingReader that converts chroma-subsampled YCbCr block
data to full-resolution 3-bytes-per-pixel output. Each block of h×v
pixels stores h*v Y samples plus one shared Cb and Cr sample; the
reader expands these into per-pixel (Y, Cb, Cr) triples.

This enables decoding YCbCr TIFFs with any supported compression
method (uncompressed, LZW, Deflate, etc.), not just JPEG. Two more
libtiffpic test images now decode with verified hashes:
- dscf0013.tif (uncompressed YCbCr 2,1 subsampling)
- ycbcr-cat.tif (LZW-compressed YCbCr 2,2 subsampling)

The remaining two YCbCr test images (smallliz.tif, zackthecat.tif)
use Old JPEG compression (type 6) which is a separate unsupported
feature.
@lilith lilith force-pushed the feat/ycbcr-upsampling branch from e71b9c8 to 58a76a0 Compare March 12, 2026 03:40
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