Releases: Redrum624/Vitrine
Releases · Redrum624/Vitrine
Release list
Vitrine v1.37.0
Changed
- Auto Tone Curve and Auto Color Balance are gone — Auto All is now a pure corrector. Why: the style-profile tone curve applied itself "sometimes" (it skipped low-contrast images), and the Adjust-menu "Auto Levels" item was mislabeled — it actually applied that same curve. Removed: the Tone Curve card's ⚡ Auto, the Color Balance card's ⚡ Auto, the "Auto Levels" menu item, the Auto All curve/color-balance components, and the now-signal-less "Styled" toolbar chip. The "Auto Color" menu item became "Auto White Balance" (that's all it still does). The Tone Curve panel's histogram-stretch Auto Levels/Contrast options are unaffected. Affects:
src/services/AutoAdjustService.ts,src/App.tsx, module components. - Auto All rebuilt: real corrections plus Auto Crop. It now composes the standalone Basic Adjustments auto (neutral-target exposure, highlights recovery, shadow lift, black-point clip-lift) with Auto White Balance — and on a photo you haven't cropped or rotated yet, it also auto-straightens (wedge-free, using the same inscribed-crop math as the Crop panel). Your existing framing is never touched. History records it as a single "Auto All" entry. Affects:
src/services/AutoAllService.ts(new),src/services/AutoAdjustService.ts.
Added
- "May be sideways?" hint. When a photo's content strongly suggests it's rotated 90° (dominant lines running the wrong way AND the bright sky-side sitting left or right — both signals must agree), a small dismissible chip offers a one-click lossless quarter-turn in the detected direction. It never rotates on its own, and photos with EXIF orientation are already auto-oriented at load as before. Affects:
src/services/SidewaysHintService.ts(new),src/App.tsx. - History now tells you what was edited. Entries read "Exposure +0.35", "Temperature 6500 → 4800", "Rotate 90°", "Straighten +2.0° ", "Crop 84%", "Noise Reduction on", "Basic Adjustments: 3 changes" — with old→new values, per-module counts, and curve/toggle edits no longer collapsing to a bare module name. Cause of the old vagueness: the label formatter discarded the previous value, showed only the first changed control, and skipped non-numeric changes entirely. Affects:
src/services/CheckpointService.ts,src/components/Panels/HistoryPanel.tsx.
Fixed
- The filmstrip keeps the active photo centered. Arrow keys, chevrons, and clicks now center the selected thumbnail (instant during rapid navigation, smooth otherwise); wheel-panning the strip never snaps back. Cause: the old scroll logic only acted when the thumb had fully left the visible strip. Affects:
src/components/Panels/ThumbnailPanel.tsx. - A RAW photo used as reference now renders at pane resolution. Cause: the reference pane loaded through the gallery-thumbnail path, which caps RAW embedded previews at a 512px box — a postage stamp in a half-window pane. The reference now requests up to 2560px from the embedded preview (sharp, correctly oriented); JPEG references are unchanged. Affects:
electron/main.cjs,electron/rawThumbPolicy.cjs(new),src/App.tsx.
SHA256 checksums
308333819317667490fb61207a83aae9949e12c91d19d9d64ed5e881f75d6e9a Vitrine Setup 1.37.0.exe
37427d5f567d96f540325ba926d57ba6ea299d08fd9f7d40741858110485f9b8 Vitrine 1.37.0 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256
Vitrine v1.36.0
Fixed
- Noise reduction was unusable above strength ~5. Cause: the slider's filter-strength mapping carried a base offset (h = 0.015 + slider×0.0012) — strength 0 already applied a full low-ISO denoise and 95% of the slider range smeared detail. New curve: zero means off, mid-slider ≈ the old "5", the top end is strong but not destructive; the CPU fallback now uses the identical curve, and the NR Auto button was re-tuned to keep its effective output. If you had parked the slider around 5, the same look now lives around 50. Affects:
src/shaders/nrCurve.ts(new),src/services/AdvancedDenoisingService.ts,src/modules/NoiseReductionModule.ts. - The Enhance sharpen (CAS) slider had the same defect: 62.5% of maximum sharpening at slider 0 — and slider 0 meant "off" on the AI route but "62.5%" on the standard route. Now 0 is truly off on both routes and the range is linear. Affects:
src/utils/enhanceOps.ts,src/utils/enhanceChain.ts,src/shaders/GpuPreviewPipeline.ts. - White Balance temperature shifted the tint. Cause: per-channel gains were derived from a display blackbody curve whose green component drifts against the red/blue axis — a warm move injected ≈+19 tint-units of green, 3200K injected ≈−45 (magenta). Green is now pinned: temperature moves strictly along blue↔amber, tint alone owns green↔magenta (CPU, worker, and GPU all share the one fixed function; ~400 lines of dead shader code deleted along the way). Saved non-6500K edits render slightly differently — correctly now. Affects:
src/modules/WhiteBalanceModule.ts,src/modules/utils/ColorUtils.ts. - The Basic Adjustments ⚡ Auto never touched highlights or shadows. Cause: the module has both sliders, but the standalone auto's output simply omitted them (Auto All drives them through a separate fold). Standalone Auto now pulls blown highlights down and lifts crushed shadows from the image's own statistics — while snow, beaches, and high-key scenes are explicitly protected (bright-pixel term gated on the 95th percentile). Auto All is unchanged. Affects:
src/services/AutoAdjustService.ts. - The Enhance panel could lie about its state. Persisted preferences could silently overwrite a photo's own saved enhance/NR settings on any panel remount; slider changes on an applied Sharpen didn't refresh the preview until an unrelated edit did; a refused bake (e.g. clicked while the photo was still developing) still marked itself "applied". All fixed: per-image state always wins over preferences, controls stage until first Apply then commit live like every other panel, only genuinely completed bakes count, and Reset now clears everything the panel shows as active. One asymmetry to know: toggling NR off on an applied enhance updates live, toggling it back on stages until Apply. Affects:
src/components/Modules/EnhanceModuleComponent.tsx,src/utils/enhancePrefsStorage.ts.
Changed
- Sharpening preview is now honest — judge it at 1:1. Cause: sharpen kernels were applied in pixel space at whatever resolution was being processed, so the fit-zoom preview showed ~5× stronger sharpening than the exported file ever had. Kernels now scale to the processing resolution with the export as the reference: exports are bit-identical to before, the fit-zoom preview is subtler (matching what the export actually looks like when zoomed out), and the 1:1 view matches the export exactly. Affects:
src/utils/enhanceOps.ts,src/services/ImageProcessingPipeline.ts,src/components/Panels/AdjustmentPanel.tsx.
SHA256 checksums
502d39b9c21dfa5489ad43102bfce40027c6f34df0454a9be2d905d02d15e010 Vitrine Setup 1.36.0.exe
516fee8cb551e43df051792a415a196c73db7094963f4e9346507a4129319c75 Vitrine 1.36.0 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256
Vitrine v1.35.0
Fixed
- The packaged app's image workers never worked — every heavy pass ran on the UI thread. Cause (two stacked): Vite never bundled the worker (the
new URL()/new Worker()split across two modules defeated its static detection, so the installed app shipped raw TypeScript as the worker file — dev-mode transpilation masked it, meaning the v1.29.0 "worker revival" only ever worked in dev), and Chromium blocks ALLfile://worker scripts anyway. Fix: the worker is now a compiled chunk booted from ablob:URL in the packaged app (dev unchanged), with contract tests pinning the whole arrangement. Verified live: pool init 189 ms, a ≥1MP pass through a real worker in 62 ms. Affects:src/workers/createPipelineWorker.ts(new),vite.config.ts,src/services/WebWorkerImageProcessor.ts. - Batch export was pathologically slow (75 JPEGs ≈ 1h30, ~72 s/photo). Causes: a stale "workers may differ" safety flag forced every export onto the single UI thread (workers were dead anyway — see above); the sharpen chain's Richardson-Lucy deconvolution paid per-pixel boundary clamps in its hottest loop; photos were decoded, processed, and encoded strictly one at a time. Fixes: exports route through the worker pool (with proof: outputs SHA256-identical to the old path), the blur inner loop is 3× faster bit-identically, and the batch pipelines decode-ahead and encode overlap. Measured live: 34.7 s → 18.1 s/photo on 20MP JPEGs with sharpening (steady-state ~16 s). Guardrails kept: noise-reduction exports stay on the main thread (their GPU path lives there), small exports (≤4096 px) keep their GPU passes, and the exposure stage still clamps after a vignetting correction. Affects:
src/services/MultiExportService.ts,src/services/exportRouting.ts(new),src/utils/enhanceOps.ts,src/utils/enhanceRestore.ts,src/services/ImageProcessingPipeline.ts,src/components/Dialogs/ExportDialog.tsx. - Motion deblur could bake corrupted regions into the photo and froze the UI. Causes: the NAFNet model deterministically garbles some bright/high-contrast windows (outputs at ±28 where valid data is 0–1) and nothing checked; independent 768 px windows with a 40 px feather disagree across long motion streaks (ghost seams); the finishing pass ran the whole frame on the UI thread; and the develop pass cached ~320 MB per module for nothing. Fixes: every tile output is sanity-checked (a garbled window keeps its original pixels and you're told how many were skipped), DirectML runs 1536 px windows with a 128 px feather, the finishing pass runs in the revived enhance worker (UI stays responsive), and bake develop passes no longer populate caches. Affects:
electron/aiDeblur.cjs,src/services/EnhanceService.ts,src/utils/createEnhanceWorker.ts(new),src/services/EnhanceWorkerClient.ts. - Switching photos during an Enhance/AI bake could write the previous photo's pixels, revert point, and saved edits onto the new photo. Cause: no identity re-check after the minutes-long develop + inference awaits, while the filmstrip stays clickable. Every bake now captures the target photo's identity up front and cleanly cancels (with a notice) if you've moved on; every bake result is also size- and sanity-validated before it may replace the working base — the v1.32.0 corruption class is now guarded at its highest-consequence write. A crashed or hung enhance worker now rejects cleanly (watchdog) instead of leaving the panel stuck busy. Affects:
src/services/EnhanceService.ts,src/services/EnhanceWorkerClient.ts,src/services/EditPersistenceService.ts. - AI upscale on a machine without GPU acceleration silently ran on the CPU — a 20MP ×2 upscale meant ~2,000 tiles and over an hour, uncancellable. The AI route is now available only when the model actually runs on DirectML; otherwise the deterministic (Lanczos) upscaler serves the same request at the same scale. Affects:
electron/aiUpscaler.cjs,src/services/EnhanceService.ts.
SHA256 checksums
81ed070f2acf24203e7d2b69948f5a7e3f1335ded4694bb1501e224431aa1b23 Vitrine Setup 1.35.0.exe
3d81ec05eb208f740602cbba668eca3d75493ba66f63b31645a6d99bdd0d932c Vitrine 1.35.0 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256
Vitrine v1.34.2
Fixed
- Starting a crop on a 90°-rotated photo snapped it back to the original rotation. Cause: the re-crop "show the full frame" suspension disabled the whole crop module — which now also owns the quarter-turn orientation. The suspension now zeroes only the crop rect (orientation, straighten angle, and flips keep applying), and a plain handle click restores the rect losslessly. Also fixed: the 'Original' aspect lock used the unrotated frame's ratio under 90°/270°, forcing landscape crops inside a portrait frame — it now follows the rotated frame. Affects:
src/components/Layout/Canvas.tsx,src/modules/CropModule.ts. - Straightening left the exposed non-photo wedges visible. The ±2°/±5° chips and Auto-Straighten never applied the auto-crop, and the slider only did with no existing crop. All straighten entry points now end wedge-free: the largest inscribed crop is applied (or intersected with your existing crop), orientation-aware. Affects:
src/components/Modules/CropModuleComponent.tsx.
Changed
- Before/After: the Before pane now shows the 90° rotation too. Comparing a rotated After against an unrotated Before was useless; the Before stays otherwise pristine (no crop/straighten/edits). Affects:
src/App.tsx.
SHA256 checksums
d81eeff89ac0a944582781e8545ca263492b2dc742604e79412b0b015fb3ef7a Vitrine Setup 1.34.2.exe
bdb5b7b5566e9bb4581a7ff40ffa3a714875e478395158dea85904599f2522e8 Vitrine 1.34.2 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256
Vitrine v1.34.1
Fixed
- Auto Basic Adjustments could darken a well-exposed photo (−0.5 stops, histogram dragged left). Cause: the v1.33.0 standalone exposure targeted the style-profile bucket medians — post-edit portfolio statistics (the dark bucket sits at ~0.07 median), so a decent photo classified into a dark-leaning bucket was yanked down at full gain. Fix: standalone exposure now targets a NEUTRAL median (0.40) with a dead zone and an asymmetric clamp — strong lifts for dark shots (up to +0.7), cautious ceiling on darkening (−0.35, and only for genuinely bright medians); style grading remains Auto All's job. Verified: well-exposed scene now gets a subtle refinement with zero darkening, the dark sunset still gets its clear lift. Affects:
src/services/AutoAdjustService.ts.
SHA256 checksums
cc92e3a295fb16ecb08ec9d21443d78f7391e291abf1bb438b74be8909708ae4 Vitrine Setup 1.34.1.exe
edb945f5724660f15d8e6d3adfaebcb0938cd735eab393ae8bbfa7fdd2bdc0e6 Vitrine 1.34.1 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256
Vitrine v1.34.0
Changed
- The Crop & Transform ±1° nudge arrows are now 90° rotation buttons. Each click rotates the photo a lossless quarter-turn (clockwise / counter-clockwise, pure pixel remap — no resampling), swapping the frame for portrait/landscape; four clicks return exactly to the original. Fine straightening still lives in the Rotation slider and the ±2°/±5° chips. The orientation persists with the photo's edits and applies before flips, straightening, and the crop rect. Also fixed along the way: on a freshly opened photo, panel-driven crop edits (rotation slider, flips, ratios) could silently not render until an app restart — the same adapter-enable gate as the v1.29.0 interactive-crop fix, now mirrored for panel edits too. Affects:
src/modules/CropModule.ts,src/modules/CropPipelineModule.ts,src/components/Modules/CropModuleComponent.tsx,src/components/Panels/AdjustmentPanel.tsx.
SHA256 checksums
04128492c0e45bc303d78613de9d8eb24fab43d7a412d3b76de6a474c80b94c2 Vitrine Setup 1.34.0.exe
8ac86baca23c2099432eb76b2df402e386b67c0490a99f8734df2476ff8cff99 Vitrine 1.34.0 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256
Vitrine v1.33.0
Changed
- The Basic Adjustments card's ⚡ Auto is much stronger. Cause of the old timidity: exposure was hardcoded to zero (correct inside Auto All, where the Exposure module owns it — but the card's own Auto never touches that module, so under/over-exposed photos got no exposure correction at all) and the remaining gains were whisper-level (brightness capped at 2.5% of its range). Standalone Auto now corrects exposure toward your style profile's target (up to ±0.7 stops) with proportionally stronger contrast/brightness/saturation moves; Auto All's composed look is unchanged (frozen at the original gentler numbers). Live-verified on two RAW scenes: clearly visible, balanced corrections without blowout. Affects:
src/services/AutoAdjustService.ts,src/components/Modules/BasicAdjustmentsModuleComponent.tsx.
SHA256 checksums
3e0faae45bba5953b0569afccec5e5fb69f871d2c703c8e5e171144ddaf26783 Vitrine Setup 1.33.0.exe
e7ff8b7989a131f627c1723761fc56912d0318befd508764e759a33aa5c3235e Vitrine 1.33.0 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256
Vitrine v1.32.0
Fixed
- Exports with Noise Reduction came out shredded (repeated strips at the top, black below). Cause: the CPU "wavelet" denoiser was an unfinished placeholder — its no-op transforms returned a quarter-resolution buffer, and auto-selection routed EVERY image above 1MP into it. Only exports were affected because previews always use the GPU denoiser; the CPU path runs when the image exceeds the single-pass GPU size cap. Fixes: full-resolution denoise now runs the SAME GPU NLM kernel in seam-free tiles (exports match the preview's look); the stub is an honest, logged identity; the module validates every output buffer; and the pipeline itself now skips any module whose output size lies (buffer-conservation guard) so this entire corruption class is dead. Affects:
src/services/AdvancedDenoisingService.ts,src/modules/NoiseReductionModule.ts,src/services/ImageProcessingPipeline.ts.
Changed
- Lens Corrections no longer has per-section enable checkboxes. A correction is active exactly when its values are non-neutral (amount ≠ 0, radius > 0, …) — sliders are always live, a small accent dot marks active sections, and neutral settings cost nothing. Affects:
src/components/Modules/LensCorrectionsModuleComponent.tsx.
Added
- Enhance settings are remembered. Sharpen/upscale toggles, scale, detail sliders, chroma clean, and the Noise Reduction toggle/strength persist across pictures and sessions (durable store, debounced). A photo's own saved enhance state always wins; prefs only seed a panel at factory defaults. Applying remains an explicit per-photo action. Affects:
src/utils/enhancePrefsStorage.ts(new),src/components/Modules/EnhanceModuleComponent.tsx.
SHA256 checksums
87472e7a6b7293f216ed82504a3386025596f5b6786775d0aed6a4e1dfdb1ad7 Vitrine Setup 1.32.0.exe
c0efcf24f6949fe272a3c78a4f902b4e7b53c1aeaf7881ac5e16dcf4a05ba04e Vitrine 1.32.0 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256
Vitrine v1.31.0
Added
- RAW Decode settings are remembered. The decode options you last chose (demosaic algorithm, highlight mode, Camera match) become the default for RAW files you haven't opened before — across pictures and across sessions. Committed whenever a re-decode you triggered in the RAW Decode panel succeeds; each already-opened photo still keeps its own saved per-image options, and batch exports of never-opened RAWs use the same defaults so they render exactly as opening them would. Stored in the main-process durable store — a renderer localStorage write was proven to vanish when the app quits soon after. Affects:
src/utils/rawDecodeDefaultsStorage.ts(new),src/services/RawImageService.ts,src/components/Layout/Canvas.tsx,src/services/ImageService.ts.
Fixed
- Changing the star filter snapped the filmstrip back to the beginning. Cause: the filtered list shrinks, the old scroll offset clamps toward zero, and nothing re-anchored. The strip now re-centers the current picture after a filter change — or, when the filter hides it, the nearest surviving photo in folder order. Affects:
src/components/Panels/ThumbnailPanel.tsx.
SHA256 checksums
7f03aa8a8d83db112b9ef3126d452439f1b735e4ea98bdde26217a69565df2df Vitrine Setup 1.31.0.exe
b0f876a61e8e69246f7fe95be3216183652b5562ddee41c6ae179197f4bdba4b Vitrine 1.31.0 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256
Vitrine v1.30.0
Fixed
- Exporting a cropped photo produced a shredded image (content squeezed into the top of the frame, black band at the bottom). Cause: with a crop active the pipeline returns a SMALLER buffer and reports the post-crop dimensions by mutating the processing context in place — but both export paths encoded that buffer with the ORIGINAL dimensions, so the encoder ran out of rows. Latent for months: until v1.29.0 fixed the crop adapter gate, interactive crops were pipeline no-ops and the export path never saw a crop-shrunk buffer. Fix: both single and multi export now read the post-crop context dims; regression tests pin the contract (including a pipeline-wide channel/length conservation suite). Affects:
src/components/Dialogs/ExportDialog.tsx,src/services/MultiExportService.ts.
Changed
- Exported filenames now use the
_VITsuffix (Vitrine) instead of the pre-rebrand_PEP(Photo Editor Pro), e.g.photo_VIT.jpg. Affects:src/utils/exportFilename.ts,src/services/ExportService.ts. - Single exports never overwrite an earlier export. If
photo_VIT.jpgalready exists the name auto-increments (photo_VIT_1.jpg,photo_VIT_2.jpg, …), matching the multi-export behaviour. Affects:src/services/ExportService.ts.
Added
- Export settings are remembered. The Export dialog restores the last-used format, quality, bit depth, color space, compression, sharpening, and output folder across sessions (per-image values like resize dimensions are never persisted). Affects:
src/utils/exportSettingsStorage.ts(new),src/components/Dialogs/ExportDialog.tsx. - Star-filtered thumbnails appear faster. Right after a folder's ratings load, the rated photos' thumbnails are prefetched in the background at idle priority (they are exactly what filters reveal), and the decode queue runs six-wide — so clicking a filter chip shows thumbnails near-instantly instead of decoding on demand. Affects:
src/App.tsx,src/utils/thumbnailScheduler.ts.
SHA256 checksums
41bc0b1d4e04c20f2459e35deb2afdff1184e5529ef4a441155d0230adf777fd Vitrine Setup 1.30.0.exe
5fa842fe8f0eeb6bf1ce936925133ec6aa3285e7e53916ebdd0e8e760a9014de Vitrine 1.30.0 portable.exe
Verify on Windows: CertUtil -hashfile "<downloaded file>" SHA256