A native, open-source RAW photo editor for Mac, iPad, and iPhone that anyone who knows Lightroom will find familiar.
Redlamp is built from scratch in Swift and Metal for Apple Silicon. It focuses on one thing, *developing* photos, and aims to do it faster and more natively than anything else on the platform. Watch the film: Introducing Redlamp (1:42, on YouTube)
> **Status: alpha, iteration 2 (macOS).** The core RAW pipeline and the Develop workspace work today: Basic (with Texture, Clarity and Dehaze), Tone Curve, Color Mixer, Color Grading, Detail (noise reduction and sharpening), Effects, lens corrections, crop and Upright, **masking** (gradients, brush, color and luminance range, Subject, Sky, Background, People and its parts, Objects, Landscape and Depth Range) with local adjustments, **healing and removal** (Heal, Clone, Remove, content-aware or generative, and Remove Dust), **focus stacking**, and **Base Looks** and **Recipes**, Redlamp's profiles and presets, with film looks measured from cameras' own renderings and **[film simulations](#film-simulations)** of 36 film looks from 30 stocks, built from the manufacturers' datasheets. AI Denoise and the rest of Develop parity are next, then 1.0 and the iPad and iPhone apps. See [Where we are](#where-we-are), the [Roadmap](#roadmap), and [how Redlamp compares with Lightroom](docs/lightroom-comparison.md). > > This README is the project's primary status page and is kept up to date as work lands. *Last updated: 4 October 2026.* --- ## Contents - [Why Redlamp](#why-redlamp) - [Goals](#goals) - [Where we are](#where-we-are) - [Film simulations](#film-simulations) - [Screenshots](#screenshots) - [Roadmap](#roadmap) - [Installation](#installation) - [Getting started](#getting-started) - [Component harness](#component-harness) - [Using Redlamp](#using-redlamp) - [Architecture](#architecture) - [Contributing](#contributing) - [Support Redlamp](#support-redlamp) - [License and acknowledgements](#license-and-acknowledgements) --- ## Why Redlamp A **red lamp** is the darkroom safelight: the one light you can work by without fogging the paper. That is the idea behind the project: you can see and shape your photo freely, and the original is never harmed. Lightroom defined how millions of photographers edit, but it is a cross-platform application that doesn't feel at home on a Mac, iPad, or iPhone, and it is tied to a subscription and a cloud. Redlamp keeps the workflow photographers already know, including the panel layout, slider names and ranges, and keyboard shortcuts, and rebuilds everything underneath as a native, GPU-first, open-source application. **Redlamp works on your folders.** It keeps a working set of folders, as Lightroom Classic's Folders panel does, and stores edits in small sidecar files next to the photos. A library built the same way is planned for 1.0 ([roadmap](#roadmap)): folders on your disk stay the organisation, ratings, keywords and collections are saved with each photo, and an index on your Mac, there only for speed, is designed for libraries of a million photos. ## Goals 1. **Immediately familiar to Lightroom users.** The Develop module's layout, panel order, slider names, ranges and defaults, and single-key shortcuts all carry over. We copy conventions, never Adobe's assets. Profiles and presets are kept apart, as in Lightroom, under Redlamp's own names: a profile, film stock or LUT is a **Base Look**, and a preset is a **Recipe**, which can set a Base Look as a preset can include a profile. Base Looks have a panel of their own, before Recipes in the left column, because a photographer chooses the look first and edits from there. Lightroom's words still work as tooltips and in search. 2. **Best-in-class masks.** Masks are part of the architecture from day one. Every edit is a layer (adjustments plus a mask), with Lightroom's model of components combined by add, subtract, and intersect, and on-device AI masks built on Apple Vision and SAM-class models. 3. **Modern, native UI and great UX.** The UI follows the macOS and iOS 26 design language. Liquid Glass is used only on floating chrome, and editing surfaces stay neutral grey so nothing distorts your color judgment. It is direct-manipulation first, every action can be undone, and there are no modal dialogs while you edit. 4. **Extreme responsiveness.** Rendering and UI are strictly separated. Slider changes should reach the screen within a frame (under 16 ms), and the UI thread never waits on the engine, the disk, or the GPU. 5. **Serious color science.** The pipeline is linear and scene-referred up to the tone curve: white balance, exposure, tone, Dehaze and the detail stage, and their masked versions, work on the light the camera recorded, and the color controls, the point curve, vignette and grain work on the tone-mapped image after it ([the pipeline](#architecture)). It uses the camera profiles DNG files embed, and has LUTs, lens profiles, and our own looks. Some looks are fitted by measurement to cameras' own renderings. 6. **Computational photography built into the editing workflow.** - **Best-in-class denoise:** a classical, noise-profiled denoiser plus an on-device AI denoiser that runs directly on raw data. - **Focus stacking in one click,** from detecting a bracketed sequence to an editable result, with pro-level strategies and retouching. This is something Lightroom doesn't offer at all, and dedicated tools only offer with a lot of friction. - **AI where it clearly wins:** masks, removal and upscaling, running on the device with no cloud and no credits. 7. **Mac first, then iPad and iPhone from the same engine.** A single platform-neutral engine sits under thin, native shells. The Mac editor comes first; iPad and iPhone follow once the main features are complete, and edits will move between devices through iCloud Drive, Files, and Photos. 8. **Open source (MPL-2.0).** The license is compatible with the App Store. Algorithms are implemented clean-room from papers and specifications. ## Where we are ### What works today (macOS) **RAW pipeline (our own, GPU-first)** - [x] Decodes RAW files through LibRaw (unpacking only). Black levels, white balance, demosaicing, and color are all done by Redlamp on the GPU. - [x] Bayer demosaic by directional filtering with a posteriori decision (Menon, Andriani and Calvagno, 2007), with a dual pass that takes plain green where the neighbours differ only by noise, Markesteijn's X-Trans demosaic (ported from LibRaw under its CDDL licence), and linear DNG support (for example iPhone ProRAW). - [x] Hot pixels are repaired before demosaicing, judged against each photo's own noise level. - [x] Row and column banding is measured in the sensor's masked (optical-black) margins and subtracted with the black level, only where the margins show more than their own noise. - [x] **DNG gain maps** (OpcodeList2), such as phones' lens shading correction, are applied before demosaicing, and noise reduction scales with the noise they amplify. - [x] **Highlight reconstruction:** channels are no longer clipped at 1 after white balance, and photosites that did clip are rebuilt from their bright unclipped neighbours, using the colour measured around the clipped area. Fully blown areas stay neutral. From process version 15, highlights clipped in one or two colours keep the colour of what's around them when Highlights or Exposure pull them below white, so a clipped sky stays blue instead of turning lilac, and areas clipped in every colour fade smoothly to neutral. - [x] **Each camera's brightness:** for new edits (process version 16), a raw opens about as bright as its camera's own JPEG, from a table of 576 cameras Redlamp measures from the camera bench's CC0 files, never from Adobe's data; a camera it lacks gets its maker's value, and a calibration from a target takes its place. Held out, every maker's photos open within a tenth of a stop of their JPEGs in the median, where Redlamp's default ran up to 0.6 stops darker (CAM-29). - [x] Tested on Sony **ARW**, Canon **CR3**, Nikon **NEF**, Fujifilm **RAF** (X-Trans), Apple **ProRAW DNG** and Google **Pixel DNG**, plus JPEG, HEIC, TIFF, and PNG. - [x] The demosaiced image is cached as a full mip pyramid, so interactive renders sample the right resolution for the zoom level. - [x] A single fused Metal kernel applies every per-pixel adjustment. Frames are delivered as IOSurfaces, so pixels are never copied between engine and UI. - [x] Latest-wins render scheduling: a burst of slider events collapses to the newest one. Stills wait in two lanes, previews (look thumbnails) ahead of exports, and yield to the canvas between tiles, so an export never holds up a frame by more than a tile; a cancelled still stops at its next tile, and exports rest between tiles when the Mac runs hot. - [x] Rendering stays off the main thread while you drag a slider. Frames go straight to the canvas, which a dedicated display-link thread presents, and each view observes only the values it shows. - [x] Both side panels are AppKit: the histogram, tool strip and every Develop and Masking panel on the right, and the Navigator, Folders, Base Looks, Recipes, Snapshots and History on the left, built from the same panel component. The right column's panels match their SwiftUI originals pixel for pixel, and a component harness is used to build and review them (see [Component harness](#component-harness)). - [x] Temperature and tint use a proper camera white-balance model (Robertson's method with the camera's color matrix). As Shot, Auto, and the illuminant presets all work. **Develop adjustments that render** - [x] **White balance:** Temp and Tint, the presets, Auto, and the eyedropper. - [x] **Basic:** Exposure, Contrast, Highlights, Shadows, Whites, Blacks, Vibrance, and Saturation, plus the **Auto** button. - [x] **Treatment** (Color or B&W) and **Base Looks** (Lightroom's profiles) with an Amount slider (0–200) and a browser that renders every look on the photo. There are six built-in looks (Redlamp Color, Neutral, Vivid, Landscape, Portrait and Monochrome) and 15 film-style looks built on 3D look tables: slide, chrome, negative, cinema, bleach and black and white through color filters. Four of them are measured from cameras' own renderings by the look profiler (see [Recipes and looks](#recipes-and-looks)). The Base Look menu lists these, Redlamp Reproduction and a photo's own camera look, and for a raw, the photographer's own Adobe camera profiles for its camera, read where Lightroom Classic or Camera Raw installs them or from files they choose and used on that Mac only (TON-51, TON-52); it shows a film look or an imported LUT first only while it's the photo's look (DEC-74). Every look, film stock and LUT is listed in the **Base Looks** panel, before Recipes in the left column, in folders (Favorites, In This Photo, the photo's camera profiles, Redlamp, Film Styles, Film Stocks, Fujifilm LUTs, Imported and Reproduction) and with its own search, which reads names, summaries, makers and kinds: hover a look to preview it, click it to apply it, and the photo's look is highlighted in its folder. Its **+** menu imports a LUT, chooses camera profiles or opens Fujifilm's LUT page. Right-click an imported look for **Show in Finder** and **Move to Trash**, or an installed look no recipe uses for **Remove from Base Looks**; a look moved to the Trash or removed is listed nowhere afterwards, and the photos that use it keep rendering with it. Right-click a built-in folder (Adobe Raw, Camera Matching, Creative, Redlamp, Film Styles, Film Stocks, Firmware Model or Reproduction) to hide it from the panel, its search and ⌘K, as in **Hide “Film Stocks”**; the panel header's right-click menu shows it again (UX-55). Wherever a look is chosen, a film stock brings its own grain, halation and bloom, and B&W for a monochrome stock, and leaves every other setting as it was; a look that isn't a film stock, chosen in place of one, takes the film's grain, halation and bloom away, and a colour look chosen in place of a monochrome one sets Color (UX-54). - [x] **Tone Curve:** a parametric curve with split points, and a point curve with presets, for all three channels together or for red, green and blue on their own. - [x] **Color Mixer:** HSL (Hue, Saturation, Luminance, and All) and a per-color mode, working in OKLCh. - [x] **Color Grading:** 3-way and individual wheels, Blending, and Balance. It also tints B&W images for split-toning. - [x] **Effects:** post-crop vignette (amount, midpoint, roundness, feather, and Highlights to keep bright areas bright under a darkening vignette) and zoom-stable film grain. - [x] **Noise reduction** (Detail panel): Luminance with Detail and Contrast, and Color with Detail and Smoothness. It is scaled to each photo's own noise: the DNG NoiseProfile tag, else its camera's calibrated profile at its ISO, else measured from the raw data when the file opens (a raw far cleaner than its camera's profile has had noise reduction in camera, so the measurement wins). Luminance keeps fine texture: wavelet shrinkage judges each detail by its neighbourhood, and at 1:1 and in exports a non-local-means pass guided by that result brings back texture where the photo repeats it. It runs as a cached stage in front of the fused kernel, so other sliders stay as fast as before, and exports render in tiles. For new edits (process version 16), values below black are kept from the raw data until after it, so the noise in the deepest shadows averages to their true level: at very high ISO they no longer lift and turn magenta (DN-12). - [x] **Sharpening** (Detail panel): Amount, Radius, Detail and Masking, in the same cached stage after noise reduction. It is noise-aware: detail is measured on a denoised copy of the luminance and applied to the untouched image, so the photo's noise and grain pass through as they were instead of being sharpened. Detail moves from a halo-limited unsharp mask towards Richardson–Lucy deconvolution of the Radius's blur, and holds back halos on strong edges; Masking keeps flat areas untouched. It boosts luminance detail in stops, so it doesn't depend on exposure and leaves colors alone. - [x] **Texture and Clarity** (global): gains on medium (about 2–8 px) and larger (about 8–64 px) luminance detail, taken from the image pyramid in the same cached stage, so tiles and zoom levels agree. Negative values soften. For new edits (process version 9) Clarity is edge-aware: a strong edge isn't its detail, so it puts no bright and dark bands along a skyline or around a tree. From process 11, Texture, Clarity and sharpening read one decomposition of the noise-reduced photo: Texture keeps its strength on texture but no longer outlines strong edges, adds less noise, and matches a downscaled export at every preview size, and dragging Texture, Clarity, Amount, Detail or Masking takes a fraction of a millisecond at 1:1. - [x] **Dehaze** (global and in masks): the dark channel prior (He, Sun and Tang, 2009) with the airlight and a haze map measured when the photo opens; negative values add a veil. For new edits (process version 8) the haze map follows the photo's edges, so the sky beside a tree or a ridge has no pale glow. From process version 18, negative values add haze where the haze map finds it, toward a slightly cool veil, so the distance and bright, unsaturated areas fog over while nearby dark, saturated things keep their contrast (TON-55). **Masking** (Lightroom's model) - [x] Each mask is a layer: its own adjustments plus a mask built from components. Components combine with **Add**, **Subtract**, and **Intersect**, and each can be inverted, as can the whole mask (**Invert**, as Lightroom's). - [x] **Linear and radial gradient** components. - Draw them on the photo. - Drag the handles to move, resize, and rotate; radial gradients also have a Feather control. - Pins select the other masks. - [x] **Brush** (`K`): A and B brushes and Erase (hold Option), with Size, Feather, Flow, Density and Auto Mask, and pen pressure. Strokes are kept as vectors in the edit and painted on the GPU in mask space (up to 4096 px), redrawing only the stroke being painted. `[` and `]` or ⌘-scroll change the size, with Shift the feather; the brush's ring shows its size as it changes, also from the panel's sliders, and Space-drag moves the photo while you paint. In every tool the wheel and pinch zoom. - [x] **Luminance Range** (`⇧Q`) and **Color Range** (`⇧J`): sample with the eyedropper, then shape the range with four handles (Show Luminance Map) or Refine up to five color samples. They select on the photo with its global edit, so the selection follows white balance and exposure. - [x] **AI masks:** Subject, Background and People (each person, or parts: face skin, eyebrows, eye sclera, iris, lips, teeth, and hair from iPhone mattes), with Apple Vision's built-in models and nothing to download. **Objects:** hover to preview, then click, drag a box around the thing or brush over it to select it; click or brush again to add, with Option to take away (Segment Anything 2.1, an 80 MB download on first use). **Depth Range:** from a photo's own depth map (iPhone), or estimated by Depth Anything 3 (or V2 Small). **Landscape:** a picker lists the regions found (water, vegetation, mountains, architecture, natural and artificial ground, and snow), each with its share of the photo, to mask together or one each, with adaptive presets such as Brighten Snow: SAM 3, converted to Core ML (a 988 MB download, under Meta's SAM License, which comes with it; Snow's prompt, added later, is in the app with a copy of the licence, so it needs no new download); the same model adds hair on any photo, facial hair, body skin and clothes to People. Sky is Segment Anything prompted inside a classical sky estimate, combined with Depth Anything 3 (converted to Core ML, a 336 MB download); the first time Sky is chosen without them, Redlamp offers both (416 MB together), and without them Sky is the classical estimate alone, which misses sky that objects cut off from the top of the frame; then every edge pixel is solved at full size against the sky's own colour, so twigs, leaf gaps and wires keep their own coverage. Subject, Background, People and Objects edges are solved per pixel too (closed-form matting), which brings back stray hairs and beard curls (see the [bake-off](docs/research/notes/MSK-17-sky-bakeoff.md)); with ViTMatte downloaded (Settings › Models, 111 MB), Subject, Background and People also gain the stray strands it finds beyond them. - [x] AI masks are computed from the photo without its edit and kept as bitmaps in the edit, so they never move when you edit and render the same everywhere. **Update AI Masks** recomputes them with today's models, pasted settings recompute them for the new photo, **Refine Edges** solves their edges again from the photo, as masks of their kind are made now (bringing back strands an older mask missed), the **Refine Edge Brush** solves an edge again, hair by hair, wherever you paint over it (kept with the mask, so Update AI Masks applies it again), and **Feather** and **Edge** soften an AI mask's edge or move it out or in. From process version 13, coarse AI masks (iPhone mattes, face parts) are refined again at the size the photo is drawn at, so they stay sharp at full size. From process version 14, a Sky mask's edit reaches only the sky's share of each pixel along its edge, so twigs and leaves keep their own colour and brightness when the sky is darkened or warmed, and **Feather** and **Edge** shape an AI mask's body while keeping its stray hairs. - [x] **Mask presets:** Blue Sky, Brighten Subject, Darken Background, Smooth Skin, Even Skin Tone, Whiten Teeth, Pop Eyes, Brighten Snow and Enhance Vegetation compute their masks for each photo, on one photo or every selected photo at once; save your own from any mask. - [x] **Beyond Lightroom:** a mask's **Detail** keeps only its textured (or only its flat) areas, and any mask can be reused as a component of another (**Existing Mask** in Add, Subtract and Intersect). - [x] **Local adjustments:** Temp, Tint, Exposure, Contrast, Highlights, Shadows, Whites, Blacks, Texture, Clarity, Dehaze, Hue, Saturation, Sharpness, Noise, a Color swatch that tints what the mask covers, and Curves (RGB, red, green and blue), plus the mask's Amount (0–200%). **Effects**, as in Lightroom's Effect menu, set a mask's sliders and Curves in one choice: Dodge, Burn, Warm, Cool, Add Detail, Reduce Haze, Smooth Skin, Whiten Teeth and Pop Eyes, with values of Redlamp's own, and your own saved from any mask. - [x] **Mask management:** one picker for every mask, also behind a mask's Add, Subtract and Intersect, which asks for a model's download in place. The list shows a thumbnail of each mask's coverage, and the photo shows the overlay while the pointer is over a mask, a component or a mask's pin. Each mask and each component has a menu (show and hide, rename, duplicate, "duplicate and invert", invert, reset, delete), masks and components drag to reorder, and Option-click on an eye shows one mask alone. **People** opens a picker of who is in the photo, as crops to tick, with the parts to mask, and a mask for each person if you like. A mask overlay (`O`) in Lightroom's modes (Color Overlay, on B&W, Image on Black or White, B&W, Image on B&W), colors and opacity. - [x] **Fast by design:** gradients and ranges are evaluated per pixel inside the same fused GPU kernel, and brush and AI masks are read from GPU textures. Up to 16 masks cost well under a millisecond extra at Fit. - [x] **Models on demand:** Settings › Models lists the downloadable models with their size, and removes them. Every model runs on the Mac; photos are never uploaded. Each shows its licence, which comes with the download. Models still under licence review are offered only when you turn on evaluation models. **Focus stacking** (a separate Stack workspace) - [x] **Stacks are found for you:** runs of frames with the same camera settings a moment apart, whose sharp region moves from frame to frame, get a "Focus stack detected: N frames" banner with **Merge**, and the filmstrip slides up for a few seconds to show it. Bursts, time-lapses and pans aren't offered. **Photo › Merge to Focus Stack…** and **Edit Focus Stack…**, also in the command palette, open the Stack workspace from the menus. - [x] **The result develops like a raw.** Frames are stacked as demosaiced camera RGB before any edit, so every Develop slider, white balance included, works on it. The stack is a small `.redlampstack` document beside the frames; the merged pixels are cached and rebuilt when needed. - [x] Alignment follows focus breathing, rotation and shift, brightness is matched frame to frame, and a depth map records which frame is sharpest where. - [x] **Auto, Smooth and Detail:** Auto takes tone and color from the depth map and fine detail from the sharpest frames near it; Smooth blends between frames for clean surfaces; Detail keeps the sharpest detail from anywhere, for hair and bristles. - [x] **The Stack workspace:** leave frames out, switch methods (each merge is cached), view the depth map, and **retouch** by painting the frame under the cursor, a chosen frame or another method's result over the merge. - [x] One frame is in memory at a time, and `redlamp stack` does the same from the command line. **Workspace** - [x] A Lightroom-style layout. On the left: Navigator, Folders, Base Looks, Recipes, Snapshots, and History, as collapsible panels like the Develop panels. In the center: the photo, with the filmstrip below. The filmstrip slides in when the pointer reaches the bottom of the window and away once it leaves; pinned, with the pin at the right end of its line of text, or with **Hide Automatically** turned off (View › Filmstrip, the filmstrip's own right-click menu, or Settings › Appearance), it stays up, and the photo is fitted above it. F6 hides it altogether. On the right: histogram, tool strip, and the Develop panels in Lightroom's order, each a card whose header shows a grey Edited chip while the panel has edits, with how many kinds of setting it has changed, as Copy Settings lists them ("Edited · 2"); hovering it lists them. - [x] **Folders**, as in Lightroom Classic: add folders with **+**, ⌘O or by dropping them on the window, and they're remembered (by bookmark, so a folder that's renamed or moved is followed). Each shows as a tree with the number of photos in every folder; click one to show it and everything beneath it in the filmstrip, its number counting its subfolders' photos too, as in Lightroom Classic, or turn off **Show Photos in Subfolders** (View menu or the folder's context menu) to see only its own photos. Nothing on disk is moved or changed. The filmstrip follows the disk by itself: photos copied in, deleted, renamed or rewritten appear, leave or update in place, a photo still being copied waits until it's complete, and the selection moves to the next photo when its own is deleted. A folder on a disk that isn't connected is dimmed with a question mark, **Locate…** points it at where it went, and it comes back when the disk does. Each folder reopens on the photo you last had in it. - [x] **Built to stay fast with any number of photos:** a folder lists without reading a single sidecar (badges follow from light reads, visible photos first); thumbnails decode in parallel on every core at the cell's size, from the smallest preview the raw file embeds that's big enough (found by LibRaw; 3 to 11 times faster than ImageIO's full-size one for Sony, Canon and Nikon files), are kept within a 128 MB budget in memory and cached on disk in one file per folder (at most 1 GB), and are warmed in the background while you're not waiting; the filmstrip is AppKit with reused cells, so 50,000 photos cost what a screenful does. Focus stacks are looked for one folder at a time in the background, and remembered. See [Measured performance](#measured-performance) and the [design](docs/plans/2026-10-02-folders-design.md). - [x] **Sliders:** click to jump, drag to adjust, Shift-drag for fine control, double-click to reset, and click the value to type one in or drag it to scrub (Shift for fine control). Option-dragging a tone slider shows clipping, as in Lightroom. The Color Grading wheels' hue, saturation and luminance, the tone curve's splits and its selected point's Input and Output, Base Look Amount, and in the Masks panel the overlay's Opacity, the Refine Edge brush's Size and the four stops of a luminance or depth range have values too. - [x] **Panels:** double-click a panel or group title to reset it, and Option-click a header for Solo Mode. The left column's panels collapse the same way when you click their headers, and Option-click shows only one. - [x] **Panel switches,** as in Lightroom: the eye at the right of every Develop panel's header but Basic's turns the panel's settings off and on, each a step in History. A panel that's off keeps its settings, dimmed, and does nothing to the photo, so Detail off is no sharpening and no noise reduction, and Lens Corrections off leaves out the lens correction the file carries. Changing one of its settings, or resetting it, turns it back on. The switches are saved with the edit and travel with the panel's settings when they're copied, pasted or synced. - [x] **Histogram:** clipping indicators, and you can drag across it to adjust Blacks, Shadows, Exposure, Highlights, or Whites. While the pointer is over the photo, the line under it shows the R, G and B percentages there, or its L\*a\*b\* values (relative to D50) with **Show L\*a\*b\* Values** in the histogram's right-click menu, the View menu or ⌘K, read from the render without the overlays. - [x] **Recipes** (Lightroom's presets), after Base Looks in the left column: 39 bundled recipes in eight groups, including camera-style ones built from Fujifilm-style recipe cards, 20 Mood recipes, and the border recipes of the Borders folder (see [Borders](#borders)). Hover to preview, click to apply, then adjust the recipe's Amount (0–200) at the top of the panel, drawn as the Develop panels' sliders are; a recipe's right-click menu has **Apply Base Look Only**, which previews its look alone while highlighted. Your own and installed recipes also have **Show in Finder**, which selects the recipe's file, and **Move to Trash** in place of Delete Recipe: every version of the recipe goes to the Trash, where it can be recovered, and photos edited with it keep their settings. A bundled folder hides from its right-click menu, as in **Hide “Night”**, and the panel header's right-click menu shows it again; Favorites, My Recipes, your own lists and Installed can't be hidden. A recipe that sets a Base Look still sets it, as a Lightroom preset that includes a profile does, and shows it on its row (the look's icon, such as a film's, or the Base Looks symbol) and names it in its tooltip. You can search recipes (Lightroom's words work; looks are searched in Base Looks), mark favorites, save the current edit as a recipe with a settings checklist (⇧⌘N), and import or export `.redrecipe` files. `.cube`, `.3dl` and HaldCLUT files import into Base Looks, from its + menu or dropped on either panel (LUTs made for camera log footage too, with their input space chosen on import, there and in the Recipe Lab). Lightroom develop presets (`.xmp`) import too, one, several or a folder at a time, by the menu or by dropping them on the panel, with a report of what came across exactly, approximately or not at all ([what maps](docs/recipes/lightroom-presets.md)). Snapshots are also available. - [x] **History** with full undo and redo. Each step shows an icon for what it did, and the value before and after ("Exposure 0.00 → +0.50"). Every time you open a photo a new session starts. The earlier sessions are kept with the photo (the last 20) and listed under the current one, and choosing one of their steps brings that edit back as a new step. - [x] **Camera-recipe controls** in the Effects panel: Dynamic Range, Color Chrome, Chrome FX Blue, and red and blue white-balance shift. - [x] **Viewing:** Fit, Fill, 1:1, and 2:1 zoom, click to zoom, pan, pinch, and a clipping overlay. Zooming out goes past Fit to a quarter of it, to see the photo as from a distance or on a small screen; the wheel and a pinch hold at Fit for a few steps first, so it's easy to stop there. **Sensor clipping** (`⌥J`) marks the photosites the camera clipped, in the colour of each clipped channel (black where all three did), whatever the edit has done since; the **colour-assessment view** (`⇧L`) puts the photo on middle grey inside a white frame (ISO 12646). **Before/After** (`\`) in three layouts, full frame, side by side and a diagonal split, cycled with `Y` and `⇧Y`; the original is rendered once and cached, so edits don't re-render it. - [x] **Themes:** Neutral greys by default, so nothing tints your judgment of color, plus a Redlamp theme and 20 dark and light families with a tint control, from the toolbar's Theme button or **Settings** (⌘,), which also has an About tab. The command palette follows the app's theme or takes one of its own. - [x] **Lightroom Classic's keyboard shortcuts**: 186 actions on 135 key bindings, from one registry that also drives the menus and an in-app ⌘/ reference (see [Keyboard shortcuts](#keyboard-shortcuts)). - [x] **Command palette** (⌘K): every action, with its shortcut shown beside it, every Develop slider, and pickers for white balance, treatment, Base Looks, recipes, Before / After, snapshots and history, all from the keyboard. - ↵ on a slider shrinks the palette to a slider bar over the photo: ← → step it (⇧ ×10, ⌥ finer), ↑ ↓ move to the next slider, and you can type a value or `x+0.3`. A run of presses is one history step. - Typing a name and a value, such as `exposure 0.7` or `temp 5600k`, sets it straight from the search. - Moving through a picker previews each choice on the photo; Esc goes back one level. - A hint bar always shows the keys that work right now, and each opening shows a tip. - ⌘F opens it for sliders only, searching by name or the words people use (Lightroom's older names too). - [x] **Sliders by hand:** ⌘-scroll over any slider adjusts it (Shift coarse, Option fine), and value fields accept arithmetic such as `x+10`. - [x] **Culling while you develop:** star ratings, pick/reject flags and color labels, shown on the filmstrip. There's also an Info overlay (`I`), Lights Out (`L`), full-screen preview (`F`), and Paste from Previous (`⌥⌘V` and the Previous button). - [x] **Copy, paste and sync settings, as Lightroom does:** Copy Settings… (`⇧⌘C`) opens a checklist of every setting and mask, remembered for next time; Paste (`⇧⌘V`) applies what was ticked, and recomputes the pasted AI masks for the photo. ⌘- and ⇧-click select several photos in the filmstrip: Sync… (`⇧⌘S`) and Paste reach all of them in the background, with Undo, and Auto Sync (`⌥⇧⌘A`) repeats every change. Right-click a photo in the filmstrip to copy its settings or paste onto it without opening it; on a selected photo, the menu has the same Copy, Paste and Sync items. - [x] Non-destructive edits, saved automatically to a sidecar file next to each photo (`IMG_1234.ARW.redlamp`). - [x] **Export dialog** (`⇧⌘E`): JPEG, HEIC, AVIF and JPEG XL (lossy, with quality and an optional file size limit) or PNG, TIFF and JPEG XL (lossless, with TIFF compression), 8, 10 or 16 bits, sRGB or Display P3. Resize by long edge, short edge, width and height, megapixels or percentage, keep all metadata, all but the location, or none (the first two also embed the edit recipe in the file's XMP, [format](docs/recipes/sidecar-format.md)), and choose the folder and file name. Built-in and saved presets, and Export with Previous (`⌥⇧⌘E`) repeats the last export without the dialog. - [x] **Report a Bug or Send Feedback** (the toolbar's Feedback button, the Help menu or the command palette, and Report… beside an error): files a GitHub issue for you, with no GitHub account needed, under an area picked from a list that mirrors the app (such as Masking › Objects), suggested from what you were doing. The report carries what you did in the last minutes, the open photo's camera and edit, and the Mac's details, and you see all of it before it's sent ([what it contains](#reporting-bugs-and-feedback)). Help › Your Reports lists what you've sent, with each issue's state and replies. - [x] **Test Your Camera** (Help menu or the command palette): the camera bench checks how your camera's raw files decode and compares Redlamp's rendering of each with the JPEG the camera saved inside it, on your Mac. It groups photos by camera and raw mode, picks a few of each, shows them side by side and asks one question, then sends only the measurements, which you see first, to add to the [cameras page](https://redlamp.app/cameras) ([how it works](docs/camera-bench.md)). `redlamp camera-bench` runs the same checks from the command line. - [x] **What's New:** after an update, the release's highlights open once, in the welcome window's look: the logo rises, the highlights are listed, and each has a page with a screenshot and a button that opens it, such as Test Your Camera…. **Help › What's New in Redlamp** shows the recent ones again. They come from redlamp.app, so they can be written after a release ships; when they can't be had, nothing opens and the next launch tries again. - [x] A headless `redlamp` command-line tool for rendering and export. Exports smaller than the photo are developed at full resolution and downscaled last, so sharpening, noise reduction and texture look the same at every size. ### Recipes and looks - [x] **One `.redrecipe` format** for presets, profiles and LUTs: an explicit list of setting groups, an optional Base Look pinned by content hash, immutable versions, and namespaced ids ready for sharing ([format](docs/recipes/recipe-format.md), [JSON Schema](docs/recipes/recipe-format.schema.json)). - [x] **Camera recipe cards:** Fujifilm-style recipes (film simulation, dynamic range, highlight and shadow tone, color, Color Chrome, white balance shift, grain) are a recipe dialect you can type in as the card lists them ([mapping](docs/recipes/camera-card-mapping.md)). - [x] **Fujifilm's published LUTs.** Download Fujifilm's film-simulation LUTs from [its LUT page](https://www.fujifilm-x.com/global/support/download/lut/) (**Get Fujifilm's LUTs…** in the Base Looks panel's + menu opens it) and drop the unzipped folder on the Base Looks panel: Redlamp recognises each file, reads it in the F-Log, F-Log2 or F-Log2 C space it names, and imports one look per simulation (ten from the GFX ETERNA 55 pack) into its **Fujifilm LUTs** folder, for any camera's raws. Fujifilm's terms allow personal use only, so the looks stay on your Mac and exported recipes carry only a reference to them ([details](docs/recipes/recipe-format.md#fujifilms-published-luts)). - [x] **Measured film looks.** The profiler fits a look to cameras' own JPEGs of the same raw files: Fujifilm raws carry the camera's rendering inside. On photos the fit never saw: | Base Look | Like | Measured from | ΔE to the camera (lower is closer) | | --- | --- | --- | --- | | Standard v3 | Provia | 120 photos, 50 bodies | 3.26 (Redlamp Color: 5.38) | | Vivid Slide v2 | Velvia | 10 bodies | 3.39 (4.45) | | Chrome v3 | Classic Chrome | 18 photos, 5 bodies | 4.61 (5.72) | | Soft Slide v2 | Astia | 5 photos, 3 bodies, provisional | 4.57 (12.84) | The others are hand-designed until there's data for them ([look development](docs/recipes/look-development.md#measured-base-looks-the-profiler)). Looks keep Redlamp's own names. - [x] **Film simulations:** 36 looks from 30 stocks, built physically from the manufacturers' datasheets, including pushed, overexposed, bleach-bypass and cross-processed variants, with halation, bloom and film grain, a **Film Looks** window and each film's icon in the Base Looks panel ([details](#film-simulations)). - [x] **Look-development tools:** lint (neutral axis, skin hue, monotonic lightness, banding, clipping) on a synthetic chart, golden renders per recipe version, style fingerprints and a fitter, and the **Recipe Lab** in the [component harness](#component-harness). - [x] **An agent recipe studio** ([docs](docs/recipes/agent-studio.md)): curator, colorist and critic agents work through `redlamp mcp` on briefs drawn from public-domain references. People approve the briefs and pick the winners in the Recipe Lab, and the critics are only trusted after they agree with human picks on held-out pairs. ### In progress - **Focus stacking:** lens corrections before alignment, halo handling, vendor focus-bracketing tags for detection, and baking a stack to DNG. - **Remove, Heal and Clone** (`Q`): click the photo to add a spot. **Remove** fills it from the photo around it, patch by patch, continuing edges that run into it (content-aware fill), and with Click picks set to Person or Object, a click removes the whole person or object, shaped by its mask. With Object, a box dragged around a thing or a stroke brushed over it removes it too, as the Drag menu says (Rectangle or Brush, the same choice as the Objects mask's), and a stroke over a part a pick left out, such as a cup's handle, adds it to that pick. **Find** outlines things named in words wherever they are in the photo (trash, litter, plastic bags, bottles, cans, cigarette butts, power lines, cables, signs, traffic cones, cars, people and birds, with OWLv2 from Settings › Models), and a click on one removes it the same way, or **Remove All** removes them all; Heal and Clone find their own source nearby; drag the spot or its source to move it, or its handle to resize it, and change Heal or Clone, Size, Feather and Opacity in the panel. Heal matches the source's texture to the light around the spot. Drag instead of clicking to brush a spot along a scratch, wire or twig. `H`, or **Show Spots** at the top of the panel, hides the spots, their outlines and pins, and shows them again, so a fill can be judged with nothing drawn over it; the selected spot stays selected, with its fills still to choose from. **Remove Dust** finds the soft, colourless specks sensor dust leaves on smooth areas (sky, walls, water) and heals them in one step; with several photos selected, it heals the specks found in the same place on the sensor in two or more of them (frames showing the same scene around a speck, as from a tripod, count as one), in all of them (one Undo puts the others back), and **Visualize Spots** shows the photo's edges in white so the rest stand out. Spots are saved with the edit, paste with Copy Settings, and `redlamp render --remove x,y,radius`, `--heal` or `--clone` (or `--remove-brush` and the others through several points) adds one from the command line, as `--remove-dust 50` heals the dust found and `--remove-found car` removes what's found by name. - **Tools not yet working:** the Red Eye tool shows what is coming and when. ### Measured performance Measured on an Apple M1 Ultra with a Release build. Every figure since 29 September, the benchmark harness's runs, and what's got faster or slower are at [redlamp.app/performance](https://redlamp.app/performance), from [`docs/performance/history.jsonl`](docs/performance/history.jsonl); `scripts/perf-record.sh` records a run. The card at the top of this README is drawn from the same history by `scripts/perf-card.py`, each figure from its latest quiet record, and CI fails when the card falls behind the history. Each release's download and installed size is recorded from its zip on GitHub (`scripts/perf-history.py release`). 0.3.4 is a 30.4 MB download and 67.5 MB installed; the AI models download only when a feature first needs them. 0.2.5 added Generative Remove and its MLX frameworks and grew to 115.6 MB installed; 0.2.6 ships stripped of debugging symbols, with LibRaw built hidden so unused code is dropped and the decode service sharing the app's frameworks (AUD-11), and is smaller than 0.2.4 was. 0.2.7 ships its 69 Base Look tables compressed, each read when a render first uses it (AUD-11), and is 17% smaller installed than 0.2.6. 0.3.0 adds the library and is 17.8 MB larger installed than 0.2.9, 10.3 MB of it the library's own framework and 6.1 MB the interface's; its size budget was raised to 64,000 KB, and ARC-18 looks for savings to bring the app back under 60,000 KB. 0.3.1 adds JPEG XL export's encoder (libjxl, about 2 MB) and is still 1.8 MB smaller installed than 0.3.0, its Base Look tables shipped as binary differences under LZMA and MLX's core exporting only its C API (ARC-18). 0.3.2 is 1.0 MB larger installed than 0.3.1, 0.6 MB of it the interface's framework and 0.2 MB the recipes'. 0.3.3 is 3.0 MB larger installed than 0.3.2, 1.4 MB of it the interface's framework and 0.5 MB the library's, and its size budget was raised to 66,000 KB. 0.3.4 is 2.1 MB larger installed than 0.3.3, 1.1 MB of it the interface's framework, 0.7 MB the library's and 0.2 MB the document's, and its size budget was raised to 68,000 KB. The release check fails a bundle with an Intel slice, debugging symbols or more than its size budget (`scripts/check-release-bundle.sh`). | Operation | Time | | --- | --- | | Open a 24–26 MP raw file (decode, GPU upload, demosaic, pyramid) | 70–250 ms | | Interactive render at Fit (every adjustment, fused) | 0.6–3 ms | | Interactive render at Fit with two gradient masks | ~1.3 ms | | Interactive render at 1:1 (full 26 MP frame) | ~13 ms | | Full-resolution export render (24–26 MP) | ~45 ms | | Full-resolution export render with noise reduction (24 MP, tiled) | ~100 ms | | Focus stack of 25 × 17 MP Canon CR3 frames (decode, align, depth map, fuse) | ~8 s | | Focus stack of 109 × 4 MP JPEG frames | ~15 s | | Reopen a merged focus stack from its cache | ~0.1 s | | Detail stage on a 1:1 region (about 10 MP of pyramid texels), GPU time: noise reduction, Texture and Clarity | ~5 ms, ~1 ms | | Detail stage for a 2560 × 1600 view at 1:1 of a 24 MP frame, GPU time: noise reduction alone (Luminance 50); default sharpening, first render; while dragging Radius; while dragging Amount, Detail or Masking (cached analysis); while dragging Luminance | ~3.6 ms, ~7.2 ms, ~5.5 ms, ~2.2 ms, ~4.3 ms | The detail stage holds about 1.3 GB of GPU memory at 1:1 on a 24 MP photo and 2.3 GB on a 60 MP one, with noise reduction and sharpening on (3.1 GB and 7.5 GB before the [memory audit](docs/research/research-tracker.md), AUD-03); large views render in tiles within its budget, and nothing is kept once rendering stops for half a second. Folders and the filmstrip on 50,000 photos in 500 folders (`scripts/make-folder-fixture.sh`, then `--folders-perf`), measured while the Mac was busy with other work (load average about 18): | Operation | Time | | --- | --- | | First photos in the filmstrip, Show Photos in Subfolders on | 14 ms | | All 50,000 photos listed (500 folders, in parallel, in order) | 209 ms | | The visible thumbnails, decoded from the raw files | 33 ms | | Background warming from the raw files | 705 a second | | Thumbnails from the disk cache | 6,210 a second | | Main thread while listing, decoding and warming (p99) | 0.15 ms | | Main thread while scrolling the filmstrip end to end (p99) | 1.4 ms | | Peak memory, 152 MB before opening | 317 MB (531 MB before the [memory budgets](docs/plans/2026-10-02-folders-design.md#memory-budgets)); 207 MB idle after a memory-pressure trim | Dragging a slider at 120 events a second (`scripts/perf-sweep.sh`), with every panel open: | Main thread during the drag | Iteration 2 | Off-main rendering | AppKit panels | | --- | --- | --- | --- | | Time busy | 100% | ~54% | ~34% | | Typical run-loop iteration (median) | — | 2.3 ms | 0.17 ms | | Slowest 5% of iterations | 157 ms | ~8 ms | ~5 ms | | Slowest 1% of iterations | — | ~13 ms | ~8 ms | With both side panels in AppKit, most of what remains is Core Animation committing the redrawn layers and the engine's frames arriving; SwiftUI is down to about 2% of the main thread. ### Known limitations - Highlights and Shadows are edge-aware for new edits (process version 7): each region moves by its brightness and keeps the texture inside it. Edits made before keep the per-pixel version, and they haven't yet been compared against Lightroom's own exports. - Redlamp's exposure for Fujifilm raws differs from the camera's by up to ±0.9 EV depending on the body; the profiler removes it when measuring looks, and the engine fix is tracked (TON-14). - Non-DNG raws use a single-illuminant Adobe-derived matrix (LibRaw's). DNGs interpolate their two calibrations by white balance, and since process 4 apply their embedded profile's HueSatMap, but the Temperature and Tint model still converts with one matrix. The profile's look (LookTable and tone curve) is offered as a Base Look under "In This Photo", Apple ProRAW's look comes with its gain table map, Apple's local tone mapping, so it renders the way the iPhone does. Importing `.dcp` files is deferred. - Landscape masks (mountains, water, vegetation, ground, architecture, snow) and people parts beyond the face (body skin, clothes, and hair without an iPhone matte) come from SAM 3, under Meta's SAM License; a model trained on data Redlamp has rights to, which would replace it, doesn't exist yet ([plan](docs/plans/2026-10-01-masking-plan.md#m8-trained-heads-msk-12-msk-13-only-if-m7-says-so)). - Objects (Segment Anything 2.1), Depth Range and Sky (Depth Anything V2 Small and 3) use open models trained partly on data Redlamp couldn't use itself, offered to everyone by the owner's decisions (tracker DEC-24, DEC-02). Vision's own tap-to-segment arrives with macOS 27. - AI mask edges are solved per pixel when the mask is made, at up to 4096 px on the long side, so on larger photos they're slightly soft at 100%. For new edits (process version 13), masks coarser than that (iPhone mattes, face parts, masks made before edges were solved per pixel) are refined again where the photo is drawn, at its resolution (a guided filter, freedom-to-operate pending as DEC-05); where the photo has no edge for such a mask's to follow, it keeps its own, which is soft at full size. - The app is not sandboxed yet (required later for the Mac App Store), but photos and focus-stack frames decode in a sandboxed service with no file access (`RedlampDecoder.xpc`, sent each file's bytes), never in the app, so a damaged file can't crash the editor while it decodes. These reads still parse files in the app itself: filmstrip thumbnails (a raw's embedded preview, through LibRaw, or ImageIO), the Portrait mattes and depth a photo carries, focus-stack detection, the metadata an export copies from its source, an imported HALD look, and the Camera Bench window (Help › Test Your Camera…). iPad and iPhone come in Phase 5. - Sidecars are read and written under file coordination, so iCloud Drive syncs them safely and conflicting copies merge (the newest edit wins, the others become snapshots, and the rating, flag and label each come from the newest copy that set them). A photo that is open doesn't reload when another Mac changes its edit, but its next save merges the two edits instead of writing over the other Mac's. - Albums added from Apple Photos, kept in Photos or copied into a folder, bring each photo's favourite as a pick, its dates and its original name. What Redlamp keeps of photos kept in Photos, their edits among it, is on this Mac only, so Redlamp on another Mac doesn't see it. Photos' ratings, captions and keywords need macOS 27 and a build made with the macOS 27 SDK; builds are made with the macOS 26.5 SDK for now, so they don't come across yet, even on macOS 27. Titles, people and pets, and memories stay in Photos, since Apple's Photos framework doesn't give them. - Generative Remove has been tested only on Macs with 16 GB of memory or more. Macs with less are offered it with a note that it hasn't been tested on them, where it may be slow or not work (RM-15). - Nikon's High Efficiency NEFs (HE and HE\*) open from the Z 9, Z 8, Z f, Z 6III, Z5 II and Z50 II, through Redlamp's fork of LibRaw (CAM-12, CAM-30); other bodies' HE files, the ZR's among them, are refused until one of their samples is verified. The Z5 II's and Z50 II's NEFs, HE or lossless, open without a colour matrix (CAM-21). **Fixed in iteration 2:** - Phase One IIQ files develop with the back's black levels subtracted and its calibration applied; they had a magenta cast. - Hasselblad FFF files (Phocus's format) open as raws. - White balance now works for linear DNGs such as iPhone ProRAW. - The Navigator outlines the zoomed viewport. - The loading placeholder now shows while a photo decodes. - Dragging a slider no longer stutters. Every change used to re-render every panel and wait on the canvas's drawable on the main thread. ## Film simulations Redlamp's film looks are **physical simulations**, built from the data in each manufacturer's own datasheet: characteristic curves, spectral sensitivities and dye spectra, digitised into [`research/film-data/`](research/film-data/). Most film presets are tuned by eye.