feat: add YCbCr chroma subsampling support for non-JPEG compression

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.
This commit is contained in:
Lilith River committed 2026-03-10 22:46:59 -06:00
1 parent 26301fc3f1
commit 83409cbdf3
3 files changed
+107 -14

No files matched your search

+4 -4
View File
@@ -173,7 +173,7 @@ const FILES: &[(&str, Option<u32>)] = &[
("tests/libtiffpic/depth/genimages", None),
("tests/libtiffpic/depth/README.txt", None),
("tests/libtiffpic/depth/summary.txt", None),
("tests/libtiffpic/dscf0013.tif", Some(0)), // unsupported YCbCr chroma subsampling
("tests/libtiffpic/dscf0013.tif", Some(0x6896e83a)),
("tests/libtiffpic/fax2d.tif", Some(0xc2f30c6f)),
// No support for direct CCITT Group 3 1D format
("tests/libtiffpic/g3test.g3", None),
@@ -193,11 +193,11 @@ const FILES: &[(&str, Option<u32>)] = &[
("tests/libtiffpic/quad-lzw.tif", Some(0)), // invalid LZW stream
("tests/libtiffpic/quad-tile.tif", Some(0x6055f9ee)),
("tests/libtiffpic/README", None),
("tests/libtiffpic/smallliz.tif", Some(0)), // unsupported YCbCr chroma subsampling
("tests/libtiffpic/smallliz.tif", Some(0)), // unsupported Old JPEG compression (type 6)
("tests/libtiffpic/strike.tif", Some(0x016b0f6a)),
("tests/libtiffpic/text.tif", Some(0)), // unsupported compression
("tests/libtiffpic/ycbcr-cat.tif", Some(0)), // unsupported YCbCr chroma subsampling
("tests/libtiffpic/zackthecat.tif", Some(0)), // unsupported YCbCr chroma subsampling
("tests/libtiffpic/ycbcr-cat.tif", Some(0x388a9d8f)),
("tests/libtiffpic/zackthecat.tif", Some(0)), // unsupported Old JPEG compression (type 6)
];
fn main() {