One develop engine
Exposure, white balance, curves, HSL, color grading, texture, clarity, dehaze, detail, crop, and lens-aware local adjustments render through one deterministic engine.
Open source · Non-destructive · Deterministic
An AI decides what to change. A deterministic Rust engine does it. In the recipe-development path, the AI never touches a pixel.
.ARW, 61 MP: neutral engine conversion at left; AI-proposed crop, global tone, a radial cat lift, and a linear water hold at right. The model judge moved from 62 to 86; that score is automated review, not human aesthetic approval.What it is
Autoshop is a non-destructive photo developer for RAW and baked images. Its main workflow turns an AI proposal into a small, inspectable EditRecipe, then applies that recipe with the same local Rust renderer used by the desktop app, CLI, and embedded web UI.
Exposure, white balance, curves, HSL, color grading, texture, clarity, dehaze, detail, crop, and lens-aware local adjustments render through one deterministic engine.
analyze and auto propose recipes, validate them against image statistics, render them, and can run one bounded visual-review revision.
Linear, radial, brush, luminance-range, and color-range masks sit alongside local subject, sky, and point-prompted object selection.
Lightroom/ACR sidecars round-trip with conservative merge behavior for fields Autoshop does not model.
Ordinary develops, generated targets, and reverse-fitted looks remain distinct without rewriting the source photo.
The desktop GUI, scriptable CLI, and small local web UI all use the same library.
Download
The documented release provides both Windows front ends: autoshop.exe for the CLI and autoshop-gui.exe for the desktop app. Linux and macOS are built and tested in CI, but prebuilt binaries are not published for them.
Extract the release archive and keep the executable beside its bundled assets and Python sidecars.
autoshop-gui.autoshop decode "photo.ARW" -o "preview.jpg"
autoshop apply "photo.ARW" "recipe.json" -o "developed.tif"
With the image/vision role configured:
autoshop auto "photo.ARW" --guidance "natural color; protect highlights" -o "developed.tif"
Showcase · Part A
The cat comparison above is the first analyze example: a Sony α7R IVA 61 MP .ARW, shown as straight conversion and AI develop. The AI chose the crop and a restrained global develop plus radial and linear parametric masks; it did not use an AI bitmap segmentation mask.
The three established pairs below show different decisions and two current failure modes. Each before is Autoshop's neutral conversion of the same Sony α7R IVA .ARW; each after is an AI-proposed engine render, not a generated image. The faint watermark is identical on both halves of these three older pairs.
01
_DSC9706: tonal rangeThe proposal protected white brick while opening the porch and black wall. Its model judge moved from 84 to 86 after a bounded revision. Honest blemish: the linear sky mask leaves a faint lighter band near the top-left corner.
02
_DSC9711: detail and textureThe siding and shaded structure gain separation; the model judge moved from 78 to 84. Counter-example: the sky is paler than the neutral base even though the local mask asks for more sky depth.
03
_DSC9712: establishing sceneAutomated visual model review rejected the first acidic-green proposal at 63 and retained a revision scored 87. The landscape gains separation, but the sky is again paler and milkier than the neutral conversion; that known behavior is not captioned as an improvement.
Style read
These triptychs show three states of the same Sony α7R IVA 61 MP .ARW: straight conversion, an AI develop with style influence disabled, and an AI develop that read similar edits from the local style library. They demonstrate the style retrieval path, not a pixel-copy or generative transfer.
_DSC0070. The style-read run referenced four similar edits from the indexed Lightroom library and was accepted. The style-off middle panel rendered under a Revise verdict and therefore has no saved recipe/XMP; it is retained only as a transparent comparison.
DSC09938. The middle panel is an accepted style-off develop. The style-read proposal at right used retrieved references and rendered at full RAW resolution, but the model judge marked it Revise (85); its attempted revision scored 84 and was discarded, so no style-read recipe/XMP was saved.Showcase · Part B
Generate a complete visual target, then fit an ordinary engine recipe to its look. The generated target can invent content; the fitted render cannot. The recovered recipe is editable and can be applied deterministically to the original full-resolution RAW.
.ARW, DSC09938. Left: neutral engine conversion. Center: a 3520×2352 full-image target generated with a configured gpt-image-2. Right: the recovered recipe rendered by Autoshop on the original RAW at 9504×6336. The statistical look error moved from 0.060 to 0.042 at fit confidence 0.746691; this is a deterministic tonal/color approximation, not a pixel-aligned reconstruction of generated detail.
.ARW, _DSC0639. Left: neutral engine conversion. Center: a 3520×2352 full-image target generated with the same configured gpt-image-2. Right: the recovered recipe rendered on the original RAW at 9504×6336. The statistical look error moved from 0.057 to 0.019 at fit confidence 0.678264; the fitted color-cast stage was rejected by the fit's own do-no-harm review, so the recovered recipe carries tone and saturation only.Supported formats
Every tile below is a neutral Autoshop render of one real CC0 file—not an embedded preview. The environment-gated release suite last recorded 9/9.
arw, dng, raw, raf, nef, cr2, cr3, orf, rw2, pef, srw, 3fr, fff, iiq, mef, mos, erf, kdc, dcr, dcs, crw, nrw, mrw, ari
Decoding uses rawler, whose database covers 725 camera models. Twelve formats carry no embedded preview; Autoshop shows its own neutral rendition instead and says so.
jpg, jpeg, png, tif, tiff, bmp, webp, gif
ICC profiles on baked imports are converted through qcms when present. Monochrome and four-colour sensor arrays are refused rather than reinterpreted as three-channel colour.
The nine format samples come from the raw.pixls.us community sample repository under CC0 1.0 Public Domain.
Tech stack & algorithms
Seven parts connect decode, measured rendering, local selection, coordinate transport, sidecars, AI proposal and application infrastructure.
src/decode.rs uses rawler for RAW decode, 24 formats, and the database covers 725 bodies. Bayer files take rawler's normal demosaic path; non-2×2 RGB CFA data uses Autoshop's X-Trans geometric path, which fits color planes over a 5×5 neighborhood per CFA phase while retaining the measured photosite channel. That path closes zero-sample holes but remains an approximate X-Trans develop rather than a directional Markesteijn-class demosaic. src/render.rs applies EXIF orientation at the head of the displayed chain, before masks, straighten, and crop.
src/render.rs is an f32 pipeline with explicit linear-light operations where the algorithm requires them; the standard rawler output is gamma-encoded f32, so the implementation does not pretend every stage is uniformly linear. After orientation and optional denoise, anchored white balance precedes lens/manual vignetting and linear-light dehaze; exposure, contrast, whites, blacks, highlights, shadows, and the base/tone curve are combined in the tone LUT, then RGB curves, HSL, and color grading run in that order. Clarity and Texture, global color/detail, local masks, lens geometry, straighten, and crop follow; the Highlights control belongs to the tone LUT, with no separate highlight-reconstruction pass claimed.
The parity work in src/render.rs is measurement-driven. Period/step-response measurements refuted the earlier band-limited notch model for negative Texture; the current operator mixes fine Gaussian and coarse box low-passes against 45 anchors spanning nine periods and five slider levels. Radial feather uses a measured 290×11 (radius, feather) alpha LUT, with feather zero kept as an analytic hard edge. Brush dabs use k = (1 - ρm(h))n(h), cubic fits for ln(m) and ln(n) over hardness, screen accumulation, and a measured flow law; the held-out kernel RMS is 0.0109.
src/recipe.rs and src/render.rs implement radial, linear, brush, bitmap, luminance-range, and color-range masks with Add/Subtract/Intersect composition. src/segment.rs and python/segment.py add local BiRefNet subject selection, U²-Net fallback, OneFormer sky segmentation, and SAM 2.1 point-prompted object gestures. Cached alphas record the photo, mask subtype, orientation/click data, and backend generation, so provenance changes trigger re-derivation rather than silent reuse.
src/lensmeta.rs reads camera metadata corrections, including Sony tag 0x7037 distortion as a 16-sample piecewise-linear spline; the related camera knots are applied during render. src/lcp.rs reads Adobe .lcp perspective polynomials and solves their inverse for Lightroom mask-coordinate transport when camera knots are unavailable, while refusing unsupported fisheye profiles.
Measurements against real Lightroom exports showed that brush masks are rasterized before lens correction while radial masks are interpreted after it. src/render.rs and src/xmp.rs therefore transport mask coordinates through the engine's inverse geometry model instead of treating every mask as if it lived in one frame; the measured probe lands within 0.3 px.
src/xmp.rs is a hand-written sidecar reader/writer designed around conservative round trips: replace fields Autoshop owns, preserve unmodeled document content, and refuse unsupported semantics rather than silently flattening them. src/pipeline.rs connects that layer to the recipe/version store. The reader also imports Lightroom's sibling MaskBrushTable, validates its structure, and Brotli-decodes brush dab groups for the measured renderer; AI selection intent round-trips, but proprietary computed alpha is re-derived locally.
src/advisor/mod.rs turns the vision proposal into a bounded EditRecipe, and src/advisor/claude.rs supplies the Claude-based data-only verifier; pixels are not sent to that verifier. src/style.rs indexes prior RAW+XMP edits and retrieves similar examples, optionally with local SigLIP 2 embeddings.
src/fit.rs performs inverse rendering for match: luminance-CDF matching, exposure search, regularized engine-basis fitting and a residual tone curve are followed by closed-loop saturation and gated cast curves. src/generative.rs supports the configured gpt-image-2 used for the Part B reimagine; generation produces a lossy target, while fit/apply returns an editable deterministic full-resolution approximation. Style indexes, develop state, and segmentation alphas are cached locally.
Rust (rustc/cargo 1.94, edition 2024) · rawler (RAW decode, 24 formats / 725 bodies) · image and qcms for raster/color I/O · rayon for row-parallel stages · clap, serde, and ureq · eframe/egui for the desktop GUI · tiny_http for serve. The embedded web UI is compiled with include_str!, so it has no runtime CDN or frontend build step.
The build workflow builds and tests the default and GUI feature sets on Ubuntu and macOS. The documented battery is 857 library (9 #[ignore]d forensic probes) / 14 CLI / 132 GUI / 2+2 contract tests, and both default and GUI Clippy runs are clean. The scripts/check_docs.py release gate re-derives pinned version, format, camera, dependency, toolchain, and battery claims from the tree.
Local ML sidecars use SCUNet for denoise, BiRefNet/U²-Net for subject masks, OneFormer for sky, SAM 2.1 for object prompts, and optional SigLIP 2 for style embeddings. Model weights are not stored in the repository.
Documentation