mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-25 23:50:01 +00:00
b75267899d
* 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.
45 lines
1.8 KiB
TOML
45 lines
1.8 KiB
TOML
[package]
|
|
name = "photocraft-raw"
|
|
description = "Clean-room, pure-Rust camera raw decoder and developer (DNG, CR2, TIFF/EP raws)"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
rust-version.workspace = true
|
|
|
|
[features]
|
|
default = []
|
|
# Synthetic raw-file generators (DNG / CR2 / TIFF-EP writers and a lossless-JPEG
|
|
# encoder) for tests and fuzz seeds.
|
|
testgen = ["dep:image"]
|
|
# Real-file corpus tests (opt-in; `cargo xtask test-corpus`). Fail when the corpus is missing.
|
|
corpus = []
|
|
|
|
[dependencies]
|
|
# Adobe DNG compression 8: zlib (RFC 1950) with the TIFF predictor (pure-Rust backend).
|
|
flate2 = { workspace = true }
|
|
# Adobe DNG compression 34892: baseline JPEG tiles (lossy), decoded by zune-jpeg.
|
|
zune-jpeg = { workspace = true }
|
|
# Encodes the lossy-JPEG tiles of the testgen fixtures (feature `testgen`).
|
|
image = { workspace = true, features = ["jpeg"], optional = true }
|
|
zune-core = { workspace = true }
|
|
|
|
# Parallel bands on native; wasm builds stay single-threaded.
|
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
rayon = { workspace = true }
|
|
# JPEG XL-compressed DNG (DNG 1.7, e.g. Samsung Expert RAW). Pure Rust, MIT OR Apache-2.0. Pinned
|
|
# exactly: it parses untrusted files; moving the pin is a reviewed change (re-run the raw fuzz target).
|
|
# Native only: it added 0.88 MB to the browser build's wasm, which has a hard size cap
|
|
# (packaging/web/package.sh); there JPEG XL DNG is reported as unsupported (src/jxl.rs).
|
|
jxl-oxide = { version = "=0.12.6", default-features = false, features = ["rayon"] }
|
|
|
|
[dev-dependencies]
|
|
photocraft-raw = { path = ".", features = ["testgen"] }
|
|
# Writes sRGB PNG previews in the `rawinfo` example.
|
|
png = "0.18"
|
|
# Lossless JPEG XL encoder for the JPEG XL DNG tests (tests only).
|
|
zune-jpegxl = { version = "=0.5.2", default-features = false, features = ["std"] }
|
|
zune-core = "0.5"
|
|
|
|
[lints]
|
|
workspace = true
|