mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-14 19:26:51 -04:00
* DNG: lossy compression 34892 (baseline JPEG tiles) Adobe's lossy DNG (compression 34892) decodes: each tile is a complete baseline JPEG (8-bit luma at tile size), decoded by zune-jpeg into the tile geometry (a mismatch is an error), widened 0xFF -> 0xFFFF like Photoshop's read of 8-bit CFA data. Predictors and the rest of the pipeline are unchanged. testgen grows LossyJpegTiles (image-rs encodes the Q60 fixtures behind the testgen feature), so CI runs a decode oracle: a smooth ramp stays within a few quantisation steps of the 8-bit source, and a tile cut mid-stream fails cleanly. * Lossy DNG: check the tile JPEG header before decoding; zune deps go workspace decode_headers() runs and the (width, height) == (s.w, rows) check fires before decode(), so a hostile SOF cannot allocate the decoder's buffers (up to 16384x16364) before the size mismatch is caught. The mismatch has a regression test that swaps a 32x32 tile JPEG for a 16x16 one. zune-core and zune-jpeg move to [workspace.dependencies] next to image and flate2. * chore(ui): format prefs_ui (the workspace fmt gate is red on main until #2417 lands) * Lossy DNG: 3-sample LinearRaw (YCbCr) decodes to RGB; tiles size-check Real lossy DNGs are 3-sample YCbCr LinearRaw, not single-channel CFA: the tile now decodes through zune-jpeg's YCbCr-to-RGB output when SamplesPerPixel is 3 (gray stays for CFA), the decoded length is checked against the tile's sample count, and other sample counts say unsupported. The generator writes RGB tiles for 3-sample specs. A LinearizationTable maps the decoded samples in the develop stage as before - nothing to add in the sensor. Test: a 3-sample ramp with 64-step channel separation (surviving Q60 chroma quantisation) decodes within the quality band.