Files
photocraft/Cargo.toml
T
Elvis33LE b75267899d DNG: lossy compression 34892 (baseline JPEG tiles) (#2021)
* 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.
2026-10-10 13:39:57 -04:00

106 lines
3.4 KiB
TOML

[workspace]
resolver = "3"
members = ["crates/*", "apps/*", "xtask"]
default-members = ["crates/*", "apps/photocraft", "apps/photocraft-cli", "xtask"]
[workspace.package]
version = "0.6.0"
edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.95"
[workspace.dependencies]
# internal
photocraft-geom = { path = "crates/geom" }
photocraft-color = { path = "crates/color" }
photocraft-cms = { path = "crates/cms" }
photocraft-raster = { path = "crates/raster" }
photocraft-doc = { path = "crates/doc" }
photocraft-ops = { path = "crates/ops" }
photocraft-psd = { path = "crates/psd" }
photocraft-codecs = { path = "crates/codecs" }
photocraft-raw = { path = "crates/raw" }
photocraft-affinity = { path = "crates/affinity" }
photocraft-compose = { path = "crates/compose" }
photocraft-gpu = { path = "crates/gpu" }
photocraft-paint = { path = "crates/paint" }
photocraft-algo = { path = "crates/algo" }
photocraft-io = { path = "crates/io" }
photocraft-text = { path = "crates/text" }
photocraft-vector = { path = "crates/vector" }
photocraft-format = { path = "crates/format" }
photocraft-automation = { path = "crates/automation" }
photocraft-plugins = { path = "crates/plugins" }
photocraft-engine = { path = "crates/engine" }
photocraft-ui-egui = { path = "crates/ui-egui" }
photocraft-testkit = { path = "crates/testkit" }
photocraft-tablet = { path = "crates/tablet" }
# external
thiserror = "2"
serde = { version = "1", features = ["derive", "rc"] }
serde_json = "1"
arc-swap = "1"
bytemuck = { version = "1", features = ["derive"] }
flate2 = { version = "1", default-features = false, features = ["rust_backend"] }
image = { version = "0.25", default-features = false }
# Baseline-JPEG decode of lossy DNG tiles (compression 34892), shared with zune-jpeg.
zune-core = "0.5"
zune-jpeg = "0.5"
proptest = "1"
eframe = { version = "0.36", default-features = false }
egui = "0.36"
egui_kittest = "0.36"
rfd = "0.17"
log = "0.4"
rayon = "1"
criterion = { version = "0.5", default-features = false }
getrandom = "0.3"
[workspace.lints.rust]
unsafe_code = "forbid"
[workspace.lints.clippy]
dbg_macro = "warn"
todo = "warn"
[profile.dev.package."*"]
opt-level = 2
[profile.dev]
opt-level = 1
[profile.release]
lto = "thin"
codegen-units = 1
# The browser build (apps/photocraft-web, `data-cargo-profile` in its index.html). Hosts cap the
# size of a single file (Cloudflare Pages/Workers: 25 MiB), and the wasm is downloaded on every
# visit, so this profile optimizes for size: fat LTO, and opt-level "s" for everything except the
# pixel-processing crates, which keep opt-level 3 so filters and compositing stay fast. panic
# stays the target default (wasm32-unknown-unknown aborts; AGENTS.md's `panic = "unwind"` is for
# the native app shell). packaging/web/package.sh fails the build above 24 MiB. Issue #198:
# this took the wasm from 26.3 MiB (release profile) to 18.8 MiB.
[profile.wasm-release]
inherits = "release"
opt-level = "s"
lto = "fat"
codegen-units = 1
strip = "debuginfo"
[profile.wasm-release.package."*"]
opt-level = "s"
[profile.wasm-release.package.photocraft-raster]
opt-level = 3
[profile.wasm-release.package.photocraft-color]
opt-level = 3
[profile.wasm-release.package.photocraft-cms]
opt-level = 3
[profile.wasm-release.package.photocraft-compose]
opt-level = 3
[profile.wasm-release.package.photocraft-algo]
opt-level = 3
[profile.wasm-release.package.photocraft-paint]
opt-level = 3