AutoShade is a new RAW photo developer that splits the job into two clean layers: an AI model proposes edits, and a deterministic Rust engine applies them. The result is a non-destructive workflow where every adjustment is stored as a small recipe, not pixels, and that same recipe renders identically across the desktop app, CLI, and a local web UI.
One Engine, Three Front Ends
Version 1.2.6 ships a single Rust library backed by three interfaces: an egui desktop GUI, a scriptable CLI, and a loopback web server. The server uses a 32-byte token with Host/Origin and no-store defenses. All three consume the same renderer, so a recipe generated in one place applies without translation in another.
Exposure, white balance, curves, HSL, color grading, texture, clarity, dehaze, detail, crop, and lens-aware local adjustments all pass through one f32 linear-light pipeline. Radial feather uses a measured 290×11 alpha LUT. Brush dabs apply kappa=0.1284 flow. Negative Texture runs through two low-pass arms with measured coefficients A1=0.172443 and A2=0.304888. The tone curve is a monotone Fritsch–Carlson LUT, and all 45 Lightroom Texture anchors land within ±0.02 of their targets.
The AI Advisor Returns Recipes, Not Pixels
The AI layer does three things: analyze the image, propose a bounded recipe, and optionally run one visual-review revision. Every proposal passes a do-no-harm gate before it reaches the renderer. A cast ships only through four vetoes, including a foreign-hue check (≥45° over ≥5% of the frame) and a ≥15° hue fan across luminance.
The catalogue acts as a style reference. Each Lightroom RAW+XMP pair becomes an exemplar with a 14-dimension EXIF and histogram feature, plus the photographer's slider values and tone curve. Local models add a 768-dimensional SigLIP 2 vector and a Qwen3-VL-2B sentence embedding. A develop retrieves its four nearest past shots using a weighted distance metric: d14 plus W_EMB(1−cos) plus W_TXT·z(1−cos−hub) plus W_DESC·z(1−cos). The weights (W_EMB=4, W_TXT=0.5, W_DESC=0.5) are leave-one-out winners on the real corpus. A capped pull at 0.18 (Style 0.3) moves the proposal toward the user's historical means without copying any single image.
The reimagine pipeline composes every prompt onto a faithfulness scaffold. Below a divergence threshold D=0.35 the full solve runs; at or above it a bounded Atmosphere mode takes over. Local work attaches in a fixed order: semantic regions or luminance bands, a frozen-evidence quadtree down to 4×4, then at most two free-form masks, each through a 3% evidence gate (D<0.65, 0.012 rim).
RAW Decode and Format Support
Decoding runs through rawler, which covers 725 camera models across 24 RAW formats: arw, dng, raw, raf, nef, cr2, cr3, orf, rw2, pef, srw, 3fr, fff, iiq, mef, mos, erf, kdc, dcr, dcs, crw, nrw, mrw, and ari. Twelve formats lack an embedded preview, so AutoShade renders its own neutral rendition and says so. Baked imports (jpg, jpeg, png, tif, tiff, bmp, webp, gif) convert ICC profiles through qcms when present. Monochrome and four-colour sensor arrays are refused rather than reinterpreted as three-channel colour.
The X-Trans path fits colour planes over a 5×5 CFA neighbourhood and moved the measured X-S10 G/R ratio from 1.5503 to 0.9476. A Lightroom sidecar's tiff:Orientation selects the quarter turns. The sidecar merge is conservative: a hand-rolled XML layer reads and writes Camera Raw's own scope, and unknown namespaces survive intact.
Subject, Sky, and Object Selection
Subject segmentation uses commit-pinned BiRefNet with a named U²-Net fallback. Sky detection runs OneFormer against a 150-class ADE20K table. Object gestures become ordered positive points for SAM 2.1 over the gp1 contract. Locally derived alpha is disclosed as non-Adobe. Radial, linear, brush, bitmap, luminance-range, and colour-range masks compose as Add, Subtract, or Intersect. Radials close 41/41 vectors to ≤1 px; linear handles remain openly not pixel-closed at 9.748/7.025/6.336 px RMS. The linear falloff uses a smoothstep on the measured abscissa t^1.124 (rms 0.0064 versus 0.0315 for the plain version).
Sidecar Round-Trip and Memory Budget
Lightroom and ACR sidecars round-trip with conservative merge behaviour for fields AutoShade does not model. Tag and scope traversal reads Camera Raw's own scope including nested Look, then the merge preserves unmodeled fields. Measured domains include LocalExposure2012=EV/4, local Hue /180, the other local family /100, and global Sharpness 1:1.
The per-photo memory budget is 1800 MB, set by a 1771 MB probe. Proposals carry store:false. The test battery is 1400 library tests, 24 CLI tests, and 164 GUI tests, plus 2+2 contract tests.
What Ships and What It Costs
The release includes eight assets: autoshade.exe (CLI, 20.6 MB), autoshade-gui.exe (desktop, 26.9 MB), an installer (14.4 MB), a portable Windows ZIP (19.2 MB), a macOS universal app bundle (38.8 MB), a Linux x64 archive (9.3 MB), and a macOS CLI archive (16.8 MB), plus checksums.txt. The installer sets up for the current user with no admin rights. The macOS .app is ad-hoc signed and not notarised, so the first launch needs one Open Anyway per machine.
The package is free and open source. For developers building photography tools, AutoShade's architecture offers a useful pattern: let a cloud or local model propose, let a deterministic engine apply, and keep the two layers connected by a tiny, editable recipe format. The renderer is the single source of truth, and the AI is a suggestions layer that can be swapped, audited, or turned off entirely.