Skip to content

RapidReady v0.5.2

Choose a tag to compare

@on370 on370 released this 18 Oct 19:40
· 28 commits to main since this release

RapidReady Release Notes (v0.5.0 – v0.5.2)


[0.5.2] – 2026-10-18 (Build 015E)

Performance, stability, and polish release restoring blazing-fast speculative RAM pre-caching with live buffer indicators, synchronizing thumbnail and inspector orientations across all camera portrait orientations (GitHub Issue #2), providing edge-to-edge format-filling Loupe rendering, concurrency-governed full-resolution streaming, canonical volume path normalization, cross-platform Windows compilation hardening, and sanitized EXIF camera body metadata.

Added & Restored

  • Cross-Platform & Windows Build Hardening (metadata_resolver.rs, thumbnail.rs, lib.rs):
    • RFC 3484 (unsafe_extern_blocks) Compliance: Updated Win32 API extern block in metadata_resolver.rs to unsafe extern "system" and macOS bindings in lib.rs to unsafe extern "C", ensuring error-free compilation on modern Rust toolchains on Windows.
    • Compiler Warning Elimination: Scoped macOS-specific ImageIO variables in thumbnail.rs to #[cfg(target_os = "macos")], eliminating compiler warnings across non-macOS platforms.
  • Viewport Scalability & Large-Display Grid Optimization (lib.rs, thumbnail.rs, GridThumbnailItem.tsx):
    • Scalable 256-Request Sequence Window: In lib.rs, expanded the proven protocol handler lookahead cancellation window from 48 to 256. Prevents high-density grid viewports (e.g. 13x13 to 18x15 = 169–270 tiles) on large displays from prematurely aborting visible images with HTTP 499 while reliably dropping requests when the user scrolls past.
    • Post-Semaphore Fast-Cache Re-check: In lib.rs, requests re-check get_cached_preview_jpeg_fast immediately after acquiring a semaphore permit. If an image was already cached by a concurrent request or background worker during the wait, it is served instantly in 0ms without touching the NAS.
    • Realtime Progress Tracking During Viewport Loading: Implemented wait_while_viewport_active_with_poll in thumbnail.rs. While background workers yield decoding priority to interactive viewport requests, they now poll the active viewport cache every 200ms, immediately retiring items cached by rr-image:// and firing on_progress live. The info dialog counter advances smoothly in real time instead of freezing.
    • Resilient Grid Retry Backoff: In GridThumbnailItem.tsx, increased retry attempts from 6 to 25 with a throttled backoff (Math.min(1500, 350 * (retryCount + 1))), ensuring heavy RAW folders on slow network shares never abandon visible tiles.
  • Prevent Global ChunkCache Wipe & Isolated Invalidation (chunk_cache.rs, commands.rs, libraryStore.ts):
    • Targeted Rebuild Invalidation: Removed global chunk_cache.clear_cache() from rebuild_archive_catalog. Rebuilding a single catalog now targets exclusively that archive's cache keys via remove_entries_for_keys, completely protecting all other SSD and NAS archives from accidental cache eviction.
    • Explicit Cache Reset Sync: Hardened clear_disk_cache to execute reset_all_fully_indexed_flags() across archive_meta, ensuring catalog metadata stays 100% in sync whenever the user manually clears the disk cache.
    • Cooperative Viewport Throttling in Delta-Sync: In sync_archive_delta, added cooperative pauses (wait_while_viewport_active) every 64 directory entries, prioritizing visible Grid and Loupe thumbnail requests.
    • De-prioritized Delta-Sync Launch: Delayed background delta reconciliation on archive load by 2 seconds in libraryStore.ts, giving initial viewport tiles unrestricted SSD/network throughput.
    • Grid Streaming Chunk Deduplication: Hardened appendImageChunk in libraryStore.ts with identity-map deduplication, completely eliminating duplicate tiles during streaming scans.
    • Legacy Black RAW Chunk Invalidation: Added is_legacy_black_raw_chunk to automatically heal corrupt/all-black 544×720 fallback thumbnails on read, replacing them on-the-fly with authentic camera previews.
  • Speculative RAM Viewport Caching & Live Visual Buffer Indicators (thumbnail.rs, LibraryGrid.tsx, LoupeViewer.tsx):
    • L1 RAM Pre-Warming Architecture: Introduced is_thumbnail_ram_cached in thumbnail.rs to clearly differentiate between the high-speed in-memory L1 LRU cache (THUMBNAIL_CACHE) and the persistent on-disk L2 chunk cache (chunk_cache.rs).
    • Local SSD-to-RAM Streaming: In warm_thumbnail_cache_with_progress, pre-cached thumbnails resident on SSD in the chunk cache are proactively and asynchronously streamed into L1 RAM in < 0.5 ms without any SMB/NAS network I/O, guaranteeing instant 60 FPS scrolling and zero-latency grid browsing.
    • Grid View Lookahead Restored: Removed the erroneous isFullyIndexed gate in LibraryGrid.tsx, re-enabling automatic lookahead preloading (+3 rows in scroll direction, 1 row behind) during 150 ms scroll-settle pauses for fully indexed archives.
    • Live RAM Buffer Bubbles Restored: Re-enabled floating dark-glassmorphism buffer count badges indicating cached thumbnails in RAM (▲ top / ▼ bottom in Grid View; ◀ left / ▶ right in Loupe/Filmstrip View).
    • Optimized Full-Res Loupe Warmup: Restricted scale 100 Loupe warmup to the immediate next 1–2 photos in the culling direction, eliminating network bandwidth saturation when culling high-resolution RAW archives over NAS shares.
  • Older TIFF RAW Thumbnail Extraction (Canon Digic II / Olympus ORF) (thumbnail.rs):
    • 16-Bit SHORT Compression Tag Parsing: Resolved an issue where older camera firmwares (such as Canon EOS 350D / Digic II and early Olympus/TIFF models) left uninitialized stack memory in the upper 16 bits of TIFF Tag 0x0103 (Compression). Previously read as a 32-bit integer, this resulted in erroneous values (e.g. 4292804614 instead of 6), causing the valid 1536×1024 JPEG preview in IFD0 to be discarded and rendering an empty tile in Grid View while Loupe View rendered correctly.
    • In-Buffer Candidate Validation: Ensured candidate thumbnail streams within the header slice are strictly verified to begin with standard JPEG markers (FF D8) and discard non-viewable Bayer sensor streams (SOF3 / 0xC3).
    • Full Compatibility: Fix operates purely in the in-memory extraction pipeline with 100% backward compatibility for all existing archive catalogs and chunk caches.
  • Thumbnail & Inspector Orientation Synchronization (GitHub Issue #2) (thumbnail.rs):
    • Consistent Orientation Pipeline: Resolved an issue where portrait photos with EXIF orientation 6 or 8 without manual .rrdata rotation sidecars diverged between Grid thumbnails (unrotated 0°) and the Inspector/Loupe view (rotated 90°).
    • Slow-Path Metadata Preservation: Ensured that on the slow thumbnail generation path, effective EXIF orientation is preserved and re-injected via inject_orientation_into_jpeg when downscaling large preview JPEGs (e.g. Canon CR2 5 MB previews).
    • macOS ImageIO Direct-Store Orientation Injection: Corrected macOS extract_thumbnail_from_data behavior by injecting effective orientation tags into downscaled thumbnails, ensuring perfect parity between Grid tiles, Filmstrip thumbnails, and Loupe view.
    • Automated Regression Test: Added test_issue_2_thumb_and_inspector_orientation_consistency to verify identical orientation output across Grid thumbnails and Inspector previews.
  • Edge-to-Edge Format-Filling Loupe Viewer (ZoomableImage.tsx):
    • Updated non-zoomed photo viewport styling to width: 100%, height: 100% with object-contain, ensuring standard 3:2 camera photos properly utilize the full display viewport area without artificial letterboxing or vertical borders.
  • Canonical Volume Path Normalization (archive_catalog.rs, lib.rs):
    • Hardened normalize_canonical_path on macOS to strip leading double slashes (//Volumes/...), preventing path mismatches between SQLite catalog lookup, chunk cache key hashing, and webview image protocol requests.
  • Full-Res Viewport Semaphore & Request Pruning (lib.rs):
    • Added FULLRES_SEMAPHORE (2 concurrent permits) to prevent concurrent 30–50 MB RAW preview reads from saturating network sockets during rapid arrow key navigation.
    • Proactively discards stale requests in the protocol handler when requests fall >48 images behind the active viewport.
  • Camera Body & Lens Model Sanitization (metadata_resolver.rs):
    • Added robust string sanitization for camera make, body model, and lens tags, stripping garbage control characters, unprintable ASCII bytes, stray quotes, and dangling punctuation.
  • Thumbnail Placeholder & Grid Polish (GridThumbnailItem.tsx, FilmstripThumbnailItem.tsx, LibraryGrid.tsx):
    • Implemented #161619 placeholder styling with smooth opacity fade-in transition and empty alt="" attributes.
    • Decoupled setGridScrollTop from synchronous onScroll into a 150 ms idle debounce, eliminating micro-stutters during high-speed trackpad scrolling.
  • Natural Top-to-Bottom Indexing Queue Order (thumbnail.rs):
    • Sorted the background thumbnail queue so .pop() extracts items in natural top-to-bottom reading order, ensuring visible top rows are indexed first.
  • Progress Counter 100% Clamp (ArchiveScanBanner.tsx):
    • Clamped the archive scanning percentage to 99% until every file (including videos and complex media) is fully indexed, eliminating the confusing pause at 100% before completion.

[0.5.1] – 2026-10-16 (Build 013B)

Maintenance and compatibility release adding native Fujifilm RAW (.raf) header parsing, a universal fallback safety net for all camera RAW formats (preventing blank grid tiles on exotic/proprietary containers), fast Panasonic Lumix (.rw2) and Olympus (.orf) tag support, and responsive UI layout fixes for the archive scanning progress banner.

Fixed & Improved

  • Universal RAW Preview Fallback Safety Net (thumbnail.rs):
    • Two-Tier Preview Architecture: In get_preview_jpeg_with_orient_and_hints, if fast header-slice extraction yields no preview (e.g. Sigma X3F FOVb container, deeply nested Olympus ORF preview, or rare exotic RAW variants), RapidReady automatically falls back to full-stream embedded JPEG scanning (extract_largest_embedded_jpeg), downscales the preview in-memory to 720px, and stores it in the local SQLite chunk cache.
    • Zero Blank Tiles: Ensures that 100% of camera RAW files across all supported manufacturers render sharp thumbnails in Grid View, even without bespoke container parsers.
    • Fast-Path Camera Tags: Added native single-read header extraction for Panasonic Lumix RW2 (0x002E/0x002F JpgFromRaw) and Olympus/OM System ORF (0x0280 PreviewImage + IIRO/IIRS capture date magic in date_resolver.rs).
  • Fujifilm RAW (.raf) Grid Thumbnail Generation & Header Parsing (thumbnail.rs, date_resolver.rs, metadata_resolver.rs):
    • Native RAF Container Parsing: Added dedicated header parser recognizing FUJIFILMCCD-RAW magic and extracting the embedded JPEG preview offset (offset 84) and length (offset 88) directly from the directory table in a single request without requiring a slow 40 MB stream scan.
    • Grid View Downscaling & Chunk Caching: Integrates seamlessly into the in-memory downscaling pipeline: large ~5 MB preview JPEGs are resized in-memory to 720px in ~20 ms for compact chunk cache storage (~80–120 KB), while Loupe View and 100% Zoom strictly preserve the uncompressed full-sensor preview.
    • Capture Date & Metadata Resolution: Enabled native capture date resolution and full EXIF extraction (camera make, model, lens, exposure parameters) for Fujifilm RAF files directly from the embedded APP1 stream.
  • Archive Scan Banner Statistics Bubble Layout & Overflow (GitHub Issue #1) (ArchiveScanBanner.tsx):
    • Bubble Alignment: Realigned the floating performance and throughput statistics card from centered (left-1/2) to left-0 with arrow pointer at ml-7, ensuring the bubble expands into the visible center view rather than overflowing under the left folder tree pane on narrow windows.
    • Container Width Clamping: Constrained scan banner width to max-w-full instead of viewport-relative limits, preventing banner overflow beyond the center container boundaries.
    • Interactive Hover Target Expansion: Unified the phase pill badge, the (?) help icon, and the photo progress counter into an interactive hover trigger group, displaying the live performance statistics card when hovering over any of these elements in both scanning and paused states.
  • Archive Cache Status Indicator (LibraryLeftSidebar.tsx): Added a subtle lightning icon (Zap) inside the active archive selector in the left tree sidebar indicating whether an archive is fully cached (100% offline-ready) or currently indexing in the background, complete with informative hover tooltips.

[0.5.0] – 2026-10-14 (Build 0135)

Major milestone release introducing a persistent local disk cache inspired by Google Picasa and Adobe Lightroom (packaged binary chunk container cache with SQLite indexing for 60 FPS offline-first grid navigation across 100,000+ images), network-aware in-process header extraction for NAS/SMB storage, high-resolution Canon CR2 preview extraction with differentiated in-memory downscaling, zero-latency Loupe View viewport debouncing, and high-throughput Phase 2 I/O smoothing for fast NVMe SSDs.

Added

  • Persistent Local Disk Cache (Chunk Container & SQLite Catalog Architecture - Phase 2.1 & 2.2):
    • Picasa-Inspired Binary Chunk Containers (chunk_cache.rs): Thumbnails are packed sequentially into large 64 MB rolling binary blobs (chunk_XXXX.bin) stored on the local system NVMe (~/Library/Caches/de.rapidready.app/ / %LOCALAPPDATA%\RapidReady\Cache\). Completely eliminates APFS/NTFS filesystem fragmentation, inode exhaustion, and random-read seek penalties across 100,000+ files.
    • Single-Seek $O(1)$ Byte-Range Access: Retrieving any cached thumbnail requires exactly one lseek + read system call, delivering sub-millisecond retrieval times.
    • Relational SQLite Index (archive_catalog.sqlite): Maps canonical paths, file sizes, mtimes, orientations, and scales to chunk offsets and byte counts with WAL mode for high-concurrency read/write throughput.
    • 100% Offline-First Browsing: Once an archive is indexed, all grid scrolling, search, and preview browsing are served 100% from local NVMe storage at 60 FPS without touching remote NAS/SMB shares.
    • Automatic Incremental Delta Sync (reconcile_archive_delta): Background discovery scans detect added, modified (mtime/size change), or deleted files and update chunk entries incrementally without full re-indexing.
  • Canon CR2 High-Resolution Preview & Differentiated In-Memory Downscaling (thumbnail.rs):
    • Hardened TIFF Strip Parser: Validates Compression == 6 || 7 tags, safely discarding uncompressed raw Bayer sensor data (e.g. 860 KB IFD2 slice) and giant sensor streams (>8 MB).
    • Extended 8 MB Preview Ceiling: Successfully captures Canon CR2's full-sensor IFD0 preview (5472×3648, 2.5–5.5 MB) instead of falling back to the 160×120 micro-thumbnail.
    • Differentiated In-Memory Downscaling:
      • Previews $\le 1.5,\text{MB}$ (Sony ARW 504 KB, Canon CR3 400 KB, Ricoh DNG 54 KB) are direct-stored with 0 ms CPU overhead.
      • Previews $&gt; 1.5,\text{MB}$ (Canon CR2 full sensor) are downscaled in-memory via Apple ImageIO in ~20 ms to 720px thumbnails (~80–120 KB), keeping the local chunk cache compact (1 GB instead of 35 GB for 10,000 images) while keeping the grid razor-sharp.
      • Full sensor resolution is strictly preserved for Loupe View and 100% Zoom (scale >= 100).
  • Loupe View Viewport Debouncing & Network Request Cancellation (LoupeViewer.tsx, ZoomableImage.tsx):
    • 100 ms Viewport Debouncing: Rapid arrow navigation (<-- / -->) or fast double-clicking immediately jumps the filmstrip selection and bottom counter (0 ms feedback) while debouncing the heavy central viewport, skipping intermediate frames over slow NAS shares.
    • Proactive Request Abort: Unmounting images instantly cuts in-flight network connections (img.onload = null; img.src = ''; canceled = true;), preventing queue congestion on network mounts.

Changed & Improved

  • Phase 2 Throughput Smoothing & GUI Responsiveness (chunk_cache.rs, thumbnail.rs, commands.rs):
    • Removed Per-Thumbnail Disk Flushes: Eliminated synchronous fsync after each individual 50 KB thumbnail write in chunk_cache.rs, deferring flushes to 64 MB chunk boundary rollover and leveraging the OS page cache for butter-smooth NVMe write performance.
    • Paced IPC Event Delivery: Replaced unthrottled burst reporting (done % 10 == 0) with a paced 150 ms (~6.6 Hz) reporting interval, completely eliminating React main-thread starvation and UI freezing on fast NVMe SSDs.
    • Cooperative CPU Scheduling: Worker threads yield execution (std::thread::yield_now()) to ensure interactive UI responsiveness during heavy background indexing.
    • Accurate Live Transfer Rates: Fixed speed calculation by transmitting true accumulated byte counters (processed_bytes), accurately displaying real MB/s throughput in the scan progress card.
  • Grid View Format Badge Contrast & Legibility (LibraryGrid.tsx, LoupeViewer.tsx):
    • Refined background translucency and typography for format pills (JPG, RAW, VID), ensuring crisp, high-contrast readability against both light and dark photo backgrounds.