mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-07 10:54:10 +00:00
* TIFF: open YCbCr images as RGB (#10316) Scanners often write JPEG-compressed YCbCr TIFFs with 2x2 chroma subsampling. The tiff crate decodes and upsamples them but returns raw YCbCr samples, which the decoder rejected with "colour type YCbCr(8)". The new tiff/ycbcr.rs converts them to RGB after decoding: JPEG data uses the JFIF full-range BT.601 conversion (as libtiff does), other compressions honour ReferenceBlackWhite and YCbCrCoefficients with the TIFF defaults as fallback. 8 and 16-bit. YCbCr with extra samples, or in other sample formats, fails with a clear unsupported error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Contributors: add Yuki-init's display name Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * TIFF YCbCr: test that YCbCrCoefficients set the luma weights Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * TIFF: YCbCr tags with the wrong value count use the defaults tag_f64s now returns None unless the tag holds exactly n values, so a YCbCrCoefficients or ReferenceBlackWhite tag with extra values falls back to the TIFF defaults instead of being truncated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lrgj5pnShYtsSnrsZq5iRn * TIFF YCbCr: tests for tiled JPEG with ICC, big-endian 16-bit and planar Covers the layouts the review asked for: a tiled 4:2:0 JPEG file with an embedded profile (checked against an independent JPEG decoder), a big-endian 16-bit file, and planar data in both byte orders. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lrgj5pnShYtsSnrsZq5iRn * TIFF YCbCr: cite the formula sources and pin the green-channel choice Documents where the conversion comes from: TIFF 6.0 Section 21 (YCbCrCoefficients, pp. 90-91) and libtiff's tif_color.c (TIFFYCbCrToRGBInit, TIFFYCbCrtoRGB). Red and blue follow the spec; green follows libtiff and adds Y unscaled, which matches the spec only when the luma weights sum to 1. The module doc records this as a deliberate compatibility choice, and a new test pins it: with weights 0.25/0.25/0.25, mid gray stays (128, 128, 128). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lrgj5pnShYtsSnrsZq5iRn * Codecs README: YCbCr TIFFs with three 8- or 16-bit samples decode to RGB Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lrgj5pnShYtsSnrsZq5iRn * Format tiff_ycbcr tests with rustfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(tiff): compare grouped YCbCr decoding and update support notes * style(tiff): align grouped decode call with test formatting * style(tiff): apply repository rustfmt to grouped YCbCr regression --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com> Co-authored-by: FredApps <FredApps@users.noreply.github.com>