This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

RawCull Documentation

System Requirements

  • macOS Tahoe and later
  • Apple Silicon (M-series) only

The release on GitHub may be more current than the release on the Apple App Store. The builds on both platforms are identical, and the GitHub release is signed and notarized by Apple.

Security & Privacy: RawCull is digitally signed and notarized by Apple to protect against tampering. It runs as a sandboxed application, ensuring your data and system remain secure.

Welcome to RawCull

RawCull is a comprehensive, native macOS application developed utilizing Swift and SwiftUI for macOS Tahoe. Specifically designed for photographers, it streamlines the photo culling process, facilitating users in swiftly identifying and retaining only their most exceptional photographs. RawCull is compatible with ARW files for Sony ILCE-1, ILCE-1M2 (Sony A1), and ILCE-7M5 (Sony A7V5).

ARW body compatibility diagnostic

The following Sony bodies successfully extract EXIF, focus points, sharpness, and saliency, except for the ILCE-7RM5, which failed to extract saliency on one of its three files. The ILCE-1M2 is the only body tested across all three Sony RAW size variants (S/M/L). All files use compressed RAW, and every body achieves full-resolution L-size output, ranging from 12.4 MP (ILCE-1M2 S-crop) to 60.2 MP (ILCE-7RM5). The ILCE-7M5 and ILCE-7RM5 are the next bodies to focus on, but I depend on test ARW files to properly test them before officially concluding support for these two bodies.

Camera BodyEXIFFocusPtSharpnessSaliencyRAW TypesDimensions
ILCE-1M2Compressed4320 × 2880 (12.4 MP, S), 5616 × 3744 (21.0 MP, M), 8640 × 5760 (49.8 MP, L)
ILCE-1Compressed8640 × 5760 (49.8 MP, L)
ILCE-7M5Compressed7008 × 4672 (32.7 MP, L)
ILCE-7RM5Compressed9504 × 6336 (60.2 MP, L)
ILCE-9M3Compressed6000 × 4000 (24.0 MP, L)

Key Features

RawCull has no editing capabilities — it is purpose-built for viewing, selecting, and copying photos.

  • High Performance: Developed natively with Swift and SwiftUI, optimized for Apple Silicon-based Macs, utilizing only Apple’s official Swift and SwiftUI frameworks, eliminating the need for third-party libraries
  • Small application: The DMG file is about 3 MB in size
  • User-Friendly Interface: Intuitive controls designed for efficient culling workflows
  • Privacy-First: All data remains on your Mac, eliminating cloud synchronization and data collection
  • Security: Digitally signed and notarized by Apple, it is also a sandboxed application, providing enhanced security
  • Free and Open Source: Available under the MIT license
  • Non-Destructive: It only reads ARW files, creating and storing thumbnails separately in the sandbox
  • Developed using official Apple Frameworks only: latest Swift version, strict concurrency checking enabled, no third-party libraries which may break the app

The actual copy of ARW files from source to destination is non-destructive. It utilizes the default /usr/bin/rsync as part of macOS. Prior to the actual copy of files, a --dry-run parameter can be employed to simulate the files that will be copied to the destination.

Installation

RawCull is available for download on the Apple App Store or from the GitHub Repository.

For security, please verify the SHA-256 hash after downloading if installed from GitHub. Current updates and release notes are available in the changelog.

1 - Security & Privacy

Security & Privacy

RawCull is built from the ground up with macOS security and user privacy as first-class concerns. The following is a precise and detailed account of every security mechanism the application employs, derived directly from the source code and project configuration.


App Sandbox

RawCull runs inside the macOS App Sandbox (com.apple.security.app-sandbox = true), enforced by the operating system. The entitlements file contains only this single declaration — no additional entitlements are granted. This means:

  • The app cannot access any file or folder without explicit user consent
  • The app cannot launch arbitrary processes outside its declared capabilities
  • The app cannot read or write to system directories or other applications’ data
  • Network access is blocked at the OS level (no network entitlements are declared)

File: RawCull.entitlements


Code Signing & Notarization

RawCull is digitally signed with an Apple Developer certificate (Team ID 93M47F4H9T) and notarized by Apple. This means:

  • Apple has scanned the binary for known malware
  • The code signature guarantees the binary has not been tampered with since signing
  • macOS Gatekeeper verifies the signature and notarization ticket on first launch
  • Swift symbols are stripped from the release build (stripSwiftSymbols = true) to reduce the binary’s attack surface

Build configuration: exportOptions.plist


File System Access — Security-Scoped Bookmarks

Because the app is sandboxed, it cannot freely read the file system. All folder and file access follows Apple’s security-scoped bookmark model:

  1. User-initiated selection: The user selects a source folder or destination folder via the standard macOS file picker (fileImporter). macOS grants the app a temporary, user-approved URL.

  2. Bookmark creation: Immediately after selection, the app serializes the approved URL into a persistent security-scoped bookmark using:

    try url.bookmarkData(options: .withSecurityScope, ...)
    

    The bookmark data is stored in UserDefaults under the keys sourceBookmark and destBookmark.

  3. Bookmark resolution on subsequent launches: On the next launch, the app reads the stored bookmark data and resolves it back to a URL:

    URL(resolvingBookmarkData: bookmarkData, options: .withSecurityScope, ...)
    

    A staleness flag (bookmarkDataIsStale) is checked — if the folder was moved, the user is prompted to re-select.

  4. Access lifecycle: Every file operation that requires access to an out-of-sandbox URL calls:

    url.startAccessingSecurityScopedResource()
    // ... file operations ...
    url.stopAccessingSecurityScopedResource()
    

    The defer pattern is used in actors to guarantee cleanup even on errors. The main view model also tracks all active security-scoped URLs in a Set<URL> and releases all of them in deinit.

Files involved:

  • RawCull/Views/CopyFiles/OpencatalogView.swift — initial user selection and bookmark creation
  • RawCull/Model/ParametersRsync/ExecuteCopyFiles.swift — bookmark resolution for rsync operations
  • RawCull/Actors/ScanFiles.swift — scoped access during directory scanning
  • RawCull/Model/ViewModels/RawCullViewModel.swift — lifecycle tracking and cleanup

See also: Security-Scoped URLs — Technical Deep Dive


File Operations — What RawCull Does and Does Not Do

OperationStatusNotes
Read ARW source filesRead-onlyMetadata and embedded JPEG extraction only
Write to source folderNeverRawCull never modifies source files
Copy files to destinationYesVia /usr/bin/rsync — append-only, non-destructive
Delete filesNeverNo delete or overwrite operations
Write saved selectionsYessavedfiles.json in the user’s Documents folder
Write thumbnail cacheYesJPEG thumbnails in ~/Library/Caches/no.blogspot.RawCull/Thumbnails/
Write rsync filter listYescopyfilelist.txt in the user’s Documents folder

All writes to the Documents folder and cache directory use atomic file writes (Data.write(to:options:.atomic)) to prevent partial writes corrupting stored data.


Process Execution — rsync

RawCull uses /usr/bin/rsync (Apple’s system-provided rsync binary) to copy selected files from source to destination. Key security properties of this integration:

  • Fixed binary path: The rsync binary path is hardcoded to /usr/bin/rsync — it is never resolved from a user-supplied path or environment variable
  • Argument list, not shell string: Arguments are passed as a Swift [String] array to the process API, not as a shell command string. This eliminates any risk of shell injection
  • Controlled environment: The process is launched with a minimal, explicitly specified environment
  • No elevated privileges: rsync runs as the current user — no sudo, no setuid, no privilege escalation
  • Dry-run support: A --dry-run (simulate) mode is supported, allowing users to preview what will be copied before committing
  • Streaming output: Process output is captured line-by-line and parsed by the ParseRsyncOutput package — no raw shell output is ever executed or evaluated
  • Non-destructive: rsync arguments never include --delete or --remove-source-files — source files are never deleted

rsync-related SPM packages used:

  • RsyncProcessStreaming — process lifecycle management
  • RsyncArguments — argument construction
  • ParseRsyncOutput — output parsing
  • RsyncAnalyse — transfer statistics

Data Storage & Persistence

RawCull stores only the following data locally on the user’s Mac. No data ever leaves the device.

DataLocationFormatPurpose
Security-scoped bookmarksUserDefaults (sourceBookmark, destBookmark)Binary bookmark dataPersistent folder access across launches
File ratings and tags~/Documents/savedfiles.jsonJSONUser’s culling decisions
Rsync include list~/Documents/copyfilelist.txtPlain textFilter list for rsync
Thumbnail cache~/Library/Caches/no.blogspot.RawCull/Thumbnails/JPEGPerformance cache
App preferencesUserDefaults (standard domain)Key-valueApplication settings

No data is written to iCloud Drive, Dropbox, or any networked location.

The thumbnail cache is automatically pruned: files older than 30 days are removed on each launch. Cache filenames are derived from source file paths using an MD5 hash (see Cryptography section below).


Cryptography

RawCull imports Apple’s CryptoKit framework exclusively to compute MD5 hashes for naming cached thumbnail files:

import CryptoKit

let digest = Insecure.MD5.hash(data: Data(sourceURL.standardized.path.utf8))
let hash = digest.map { String(format: "%02x", $0) }.joined()
// Result: a filename like "a1b2c3d4...jpg"

MD5 is used here solely as a deterministic, fast, content-addressable key for the on-disk cache — not for any security or integrity purpose. No passwords, credentials, or sensitive data are hashed or encrypted.

RawCull does not use the Keychain. It does not perform any encryption of user data.


Network Access

RawCull has no network access. No network entitlements are declared in the sandbox, so the OS prevents any outbound connections at the system level. Specifically:

  • No URLSession or URLRequest calls exist anywhere in the codebase
  • No telemetry, analytics, or crash reporting frameworks are included
  • No update checking or license verification calls are made
  • No third-party SDKs with network components are included
  • The app functions entirely offline

Privacy Manifest

RawCull includes a PrivacyInfo.xcprivacy manifest as required by Apple for App Store distribution. The declared privacy properties are:

PropertyValue
NSPrivacyTrackingfalse — no tracking
NSPrivacyTrackingDomainsEmpty — no tracking domains
NSPrivacyAccessedAPIType: File APIReason 3B52A1FF.1 — accessing files the user has opened
NSPrivacyAccessedAPIType: Disk SpaceReason E174B746.1 — managing the thumbnail cache

No camera, microphone, location, contacts, calendar, health, or Photos library access is declared or used.


Permissions — What RawCull Never Requests

RawCull does not request and will never request the following permissions:

  • Camera or microphone access
  • Location services
  • Contacts, Calendar, or Reminders access
  • Photos library access
  • Full Disk Access
  • Network access (inbound or outbound)
  • iCloud or CloudKit access
  • Bluetooth or USB device access
  • Screen recording or accessibility permissions

Third-Party Dependencies

RawCull uses the following Swift Package Manager dependencies:

PackagePurposeNetwork?Executable code?
RsyncProcessStreamingProcess lifecycle for rsyncNoNo — manages Foundation.Process
RsyncArgumentsBuilds rsync argument arraysNoNo — pure argument construction
ParseRsyncOutputParses rsync output linesNoNo — pure string parsing
RsyncAnalyseAnalyses rsync transfer statisticsNoNo — pure data analysis
DecodeEncodeGenericGeneric JSON Codable helpersNoNo — pure value types

All packages are authored by Thomas Evensen. No third-party analytics, advertising, or telemetry libraries are included.


Concurrency & Memory Safety

RawCull targets Swift 6 (.swift-version pinned to 6.0.3) with strict concurrency checking enabled. Security-relevant implications:

  • File scanning and thumbnail generation run in Swift Actors, providing compile-time data-race safety
  • UI state is confined to @MainActor, ensuring UI updates happen only on the main thread
  • Memory pressure is handled via NSCache in the SharedMemoryCache actor — thumbnails are automatically discarded when the system is under memory pressure
  • All security-scoped URL tracking uses actor-isolated state, preventing concurrent access/release races

Summary

Security PropertyStatus
App Sandbox✅ Enabled — minimal entitlements
Code Signed✅ Apple Developer certificate
Notarized✅ Apple notarization
Network access✅ None — offline only
Telemetry / analytics✅ None
Security-scoped file access✅ Properly implemented with lifecycle management
Atomic file writes✅ Used for all local data persistence
Process injection risk✅ None — argument list, fixed binary path
Keychain / encryption✅ Not needed — no secrets handled
Privacy manifest✅ Accurate and complete
Data leaving the device✅ Never
Swift 6 concurrency✅ Strict checking enabled

Your photos, culling decisions, and file paths remain entirely on your Mac, under your control, at all times.

2 - Culling Photos

RawCull is not a tool for image editing; it is solely intended for selecting and copying selected images for editing by dedicated software such as DxO PL, Lightroom, and others.

A photo culling application is specialized software designed to assist photographers in efficiently reviewing, organizing, and selecting the most suitable images from a photo shoot. RawCull supports Focus Peaking and Focus Points.

Persistent Marking and Session Recovery

RawCull automatically saves your marking decisions as you work, allowing you to pause and resume your culling session at any time. Your marks, ratings, and review status are saved to disk, so if you need to continue later, simply reopen the same folder and your progress will be restored.

Thumbnail Performance

Thumbnails are generated and kept in memory during your session for fast navigation. RawCull also maintains a disk cache of thumbnails for previously reviewed catalogs, enabling instant loading when you return to the same folder in the future.

Two-Phase Culling Workflow

RawCull supports an optional two-phase culling approach that separates the initial triage from the final star rating.

Please be mindful that when using the keyboard to rate, RawCull will automatically advance to the next thumbnail.

Phase 1 — Pick and Reject

Use P and X to do a fast first pass through all images:

  • P marks an image as a keeper (rating 0, shown as P in the stats bar)
  • X marks an image as rejected (rating −1, shown in red)

The header bar shows live counts — ✕ rejected, P kept, and the number of unrated images — so you always know where you stand. Click the unrated count to filter and show only images you have not yet triaged.

Phase 2 — Star Rating

Once you have worked through the pick/reject pass, filter to keepers using the P pill in the rating filter row. You can then apply star ratings 25 to your selected images. Only images with a rating of 2 or higher are copied to the final catalog.

Sharpness-assisted classification

After running Sharpness Scoring, you can auto-classify the entire catalog in one step. Select a threshold percentage (20–80 %) from the Threshold picker and press Apply. Images scoring at or above the threshold are marked as keepers (P); images below are marked as rejected (X). You can then review and adjust before proceeding to star rating.

Keyboard

Use these keyboard shortcuts for efficient culling:

ActionKey
Pick / keep (rating 0)p
Reject (rating −1)x
Default tag (rating 3, green)t
Clear rating / untag0
Set rating 22
Set rating 33
Set rating 44
Set rating 55
Move to next or
Move to previous or
Zoom in+
Zoom out-

No images are deleted from the temporary catalog. Only images with a rating of 2 or higher may be copied to the final catalog for images. A rating of 1 marks an image as rejected, keeping it visible but excluded from the copy step.

The tagging commands also works in Zoom views.

Icons in the toolbar

Hover the mouse over an icon to see a help message. Icons from left to right:

  • copy tagged files
  • show all thumbnails in a grid
  • show all tagged thumbnails
  • switch between horizontal and vertical thumbnail view
  • show saved files
  • hide the inspector

Rating filter pills

The grid view header contains a row of coloured pills for filtering and sorting thumbnails by rating:

PillFilters to
Rejected images (rating −1)
2-star images
3-star images
4-star images
5-star images
PKeepers (rating 0) — excludes rejected

Tap a pill to activate the filter; tap it again or press ✕ to return to the full view. Filtering is non-destructive and does not affect saved ratings.

Step 1: Select Your Temporary Catalog

After copying images from your camera to a temporary catalog on your Mac, select that folder in RawCull. The application scans all images and generates previews for quick review. This process reads your photo metadata and creates a visual index of all images in the selected directory.

RawCull scanning photo library

By default, the Sidebar is hidden. To access new catalogs, toggle the Sidebar via View → Show Sidebar. The Sidebar offers only one option: selecting new catalogs for scanning.

RawCull scanning photo library

During scanning, you can monitor progress as the application indexes your images. Depending on the size of your library, this may take a few moments.

Step 2: Post-Scan Display

Once scanning completes, RawCull displays your full photo library with a thumbnail grid and preview controls ready for culling.

The inspector can be hidden by toggling the hide/show icon on the toolbar.

Vertical and horizontal view of thumbnails

Choose your preferred layout for the thumbnails. At this point, you can:

  • Navigate through images using arrow keys or click navigation
  • View the current image in the main preview area
  • Rate images using keys 05, or press t to apply the default tag (rating 3, green)
  • Use p and x for the two-phase pick/reject pass
RawCull library after scanning
RawCull library after scanning

You may also zoom in on details by using the + and - buttons. The image is either a 1024 px or 2048 px thumbnail, and for optimal results, a double-click on the image will extract the JPG file from the ARW format. This is particularly useful for viewing and focusing on specific areas. See Zoom view.

RawCull library after scanning

Zoom view

A double-click on an image zooms in, using either an extracted JPG or a generated thumbnail. See Settings for details. Utilize the plus (+) and minus (-) keys to zoom in or out on an image, whether it is a thumbnail or an extracted JPG file.

Culling by Grid View

A double-click on an image in grid view also opens a zoom view.

Shows all thumbnails in a grid view. Use the number keys 05, p, x, or t to rate images, and arrow keys to navigate. Thumbnails are colour-coded by their rating for quick visual triage.

RawCull library after scanning

The rating filter pills in the grid header let you narrow down which images are shown. Select any pill to display only images at that rating — for example, the P pill shows only your keepers, while the red pill shows only rejected images. Selecting P also includes all scored images.

RawCull library after scanning

Show only rejected images.

RawCull library after scanning

Shows only tagged images.

RawCull library after scanning

Step 3: Copy tagged images

Only photos with a rating of 2 or higher are copied to the final catalog. Keepers (rating 0), unrated (rating 0), and rejected (rating −1) images remain in the temporary catalog and are not copied to your editing workflow.

Detailed view without zoom

3 - Sharpness Scoring

Sharpness Scoring

RawCull can automatically rank every image in a catalog by sharpness, so the sharpest frames rise to the top and out-of-focus or motion-blurred shots sink to the bottom.


Overview

When you click Sharpness, RawCull analyses each RAW file:

  • A small thumbnail is extracted from the ARW file — no full RAW decode needed.
  • Apple Vision locates the main subject. The final score weights 75 % subject region + 25 % full frame. If no salient region is detected, the full-frame score is used.
  • A Laplacian edge-detection kernel measures per-pixel sharpness energy. High-ISO noise is suppressed by a pre-blur whose radius scales automatically with ISO and image resolution.
  • Scores are catalog-relative: the p90 of the session is anchored at 100, so every other frame is expressed as a percentage of it. A score of 60 means the frame is 60 % as sharp as the sharpest typical shot in that session.

Running a Sharpness Score

The Score Sharpness button appears in the grid toolbar. The toolbar function for showing the grid view is:

  • show all thumbnails in a grid
RawCull startup screen
  1. Open a catalog and wait for thumbnails to finish generating.
  2. Click Score Sharpness (scope icon) in the toolbar above the grid.
  3. A Scoring… label replaces the button while analysis runs (up to six images concurrently).
  4. When complete, a coloured score badge appears on every thumbnail and the grid re-sorts sharpest-first.
RawCull startup screen

Click Re-score to run again after adjusting Focus Mask Controls or switching the aperture filter.


Reading the Score Badge

ColourNormalised scoreMeaning
Green65 – 100Sharp — well-focused, fine detail visible
Yellow35 – 64Acceptable — slightly soft or minor motion blur
Red0 – 34Soft — missed focus, camera shake, or significant motion blur

The number in the badge is the normalised score (0–100).


Sorting by Sharpness

After scoring, the grid sorts sharpest-first automatically. Toggle this off and back on with the Sharpness button in the toolbar. The same toggle is available in the sidebar for list views.


Filtering by Aperture

The Aperture picker restricts scoring and sorting to one shooting style:

FilterAperture rangeTypical use
AllAll imagesDefault — no filtering
Wide (≤ f/5.6)f/1.4 – f/5.6Birds, wildlife, portraits
Landscape (≥ f/8)f/8 and aboveTripod landscape, architecture, macro

Changing the filter immediately re-filters the grid and re-applies the sharpness sort within the filtered set.


Auto-Calibration from Burst

Calibration runs automatically when you click Score Sharpness. It analyses the current catalog to derive the best Threshold and Laplacian strength values for that session, then applies them to the Focus Mask Controls sliders. Pre-blur, Erosion radius, and Dilation radius are not changed.

Calibration requires at least 5 scoreable images. You can still adjust any slider manually after calibration.


The Focus Mask Overlay

RawCull startup screen
Focus Mask on a sharp frame: tight red glow on feather edges.

RawCull startup screen
Focus Mask on a soft frame: faint, diffuse glow, no sharp edge lines.

Enable the Focus Mask overlay in the zoom window controls to see the same edge-detection output that drives the score, painted in red. Tight, bright lines = high score; faint glow = low score.

Focus Mask Controls

ControlEffect
Pre-blur radiusBase Gaussian smoothing before edge detection. Scales automatically with ISO and resolution — increase for very noisy files.
ThresholdMinimum edge strength included in the mask — higher = only the sharpest edges
Erosion radiusMorphological erosion before dilation — removes isolated speckle noise
Dilation radiusMorphological dilation — expands edge regions to fill small gaps
Laplacian strengthAmplification of the raw edge response — increase to separate sharp and soft frames more aggressively
Feather radiusGaussian softening on the final mask edge — visual only, does not affect the score
Border insetFraction of the image dimension excluded from each edge (default 4 %) — prevents Gaussian artifacts from inflating the score
Salient weightHow much the subject-region score drives the result vs. the full-frame score (default 75 %)
Subject size factorSmall proportional bonus based on how much of the frame the subject fills (default 0.1)
Subject classificationRuns an extra Vision pass to label the subject category on each thumbnail. Disable for faster re-scores
Show raw LaplacianDisplays the unthresholded Laplacian output — useful for diagnosing tuning issues

Changes take effect on the next scoring run.


Understanding Low Scores

Motion blur — shutter speed too slow to freeze the subject. Focus Mask shows a diffuse halo rather than sharp lines.

Missed or soft focus — autofocus tracked the background or a wing tip. Focus Mask shows strong edges somewhere other than the subject centre.

Small or distant subject — if Vision cannot detect a salient region, the scorer falls back to the full frame, diluting the score with background. Reduce salient weight and re-score if distant subjects feel underrated.

High ISO noise — extreme noise can mimic sharp edges and temporarily inflate scores. Increase Pre-blur radius in Focus Mask Controls and re-score.


Tips

  • Score after culling for exposure — removing badly exposed frames keeps the normalised scale more meaningful.
  • Re-score with the aperture filter active — the 100 baseline anchors to the sharpest frame within that aperture range.
  • Use the Focus Mask to validate scores — open the zoom window and enable the overlay before discarding any borderline frame. Trust your eye on close calls.
  • Scores reset when you open a new catalog — each catalog has its own relative scale; scores across sessions are not comparable.

4 - Similarity

Similarity

RawCull can rank every image in a catalog by visual similarity to a chosen anchor image, so near-duplicate frames and series shot in similar conditions float to the top of the grid.


How It Works

Similarity ranking is powered by Apple’s Vision framework:

  • A 512 px thumbnail is extracted from each ARW file — no full RAW decode is needed.
  • VNGenerateImageFeaturePrintRequest produces a compact numerical embedding that describes the overall visual content of the image (colour, texture, composition).
  • When you select an anchor image, RawCull computes the distance between the anchor’s embedding and every other indexed image. A shorter distance means greater visual similarity.
  • If sharpness scoring has already run, subject labels from saliency analysis are used to apply a small penalty when two images depict different subject types. This keeps the visual embedding as the dominant signal while nudging images of the same subject type slightly higher.
  • The grid re-sorts in ascending distance order — most similar images appear first, directly after the anchor.

Using Similarity

  1. Open a catalog and wait for thumbnails to finish generating.
  2. Click Index for Similarity in the toolbar to build embeddings for all files. A progress indicator shows how many files have been processed and an estimated time remaining. Already-indexed files are skipped if you re-index.
  3. Select the image you want to use as the reference and click Find Similar (or the equivalent toolbar button). RawCull sets that image as the anchor and calculates distances to all other indexed images.
  4. The grid sorts by similarity automatically — the most visually similar frames appear immediately after the anchor.
  5. To return to normal sort order, toggle the similarity sort off in the toolbar or sidebar.

Indexing similarity completed.

RawCull

Sort images after similarity selected image.

RawCull

Tips

  • Run sharpness scoring first — if subject labels are available from the sharpness analysis pass, the subject-mismatch penalty improves the ranking of same-subject bursts.
  • Re-index after adding files — any file added to the catalog after the last index run will have no embedding and will not appear in similarity results. Run Index for Similarity again to include new files; already-indexed files are skipped automatically.
  • Use similarity alongside sharpness — a common workflow is to score sharpness first to find the sharpest frame in a burst, then use that frame as the anchor to group all related near-duplicates for quick review and culling.
  • The anchor image always scores zero distance — it is the reference point, so it appears at the top of the sorted list regardless of its sharpness score.

5 - Focus Peaking

Focus Peaking: The Laplacian of Gaussian Method

Note: To obtain the most optimal results in Focus Peak view (extract), it is recommended to extract the JPG file from the ARW file. While it is possible to view Focus Peek by creating thumbnails, the mask is more effective when applied to JPGs. To access Focus Peek, double-click on the image in main view. In the Settings menu, Thumbnails tab, disable the “Use Thumbnail for Zoom” to use JPGs as base for Focus Peak.

What Is Focus Peaking?

Focus peaking is a visual aid that highlights which areas of a photograph are in sharp focus. Rather than relying on your eye alone to judge sharpness, focus peaking overlays a red highlight on pixels where edge detail and contrast are strongest. Those highlighted pixels are the ones in sharpest focus — everything else stays unchanged.

The Focus Peak is computed by the GPU on your Mac, making it a fast process even when the mask is generated on the fly.

RawCull scanning photo library

Focus Peak off:

RawCull scanning photo library

Focus Peak on:

RawCull scanning photo library

Both the Focus Point and the Focus Peak can be applied simultaneously.

RawCull scanning photo library
RawCull scanning photo library

Why the Laplacian of Gaussian?

Several mathematical approaches can measure local sharpness, but the Laplacian of Gaussian (LoG) is one of the most effective for focus peaking because it combines two complementary operations.

The Gaussian blur is applied first, suppressing sensor noise and low-amplitude out-of-focus texture — water ripples, skin, smooth backgrounds — before sharpness detection runs. Without this step, the Laplacian would flag noise and soft texture as “sharp.”

The Laplacian then computes, for each pixel, how much its intensity differs from its immediate neighbours. In a blurry region those differences are small and smooth. At a sharply rendered edge they spike. The key insight is that the Laplacian measures second-order intensity change — it responds to genuine focus-induced contrast spikes rather than gradual gradients, which blurred regions produce even when they have visible texture.


The Kernel

Rather than the classic 4-neighbour approximation, RawCull uses a full 8-neighbour kernel computed on the GPU via Metal:

L = 8 × center − (N + S + E + W + NE + NW + SE + SW)

This 3×3 formulation is more isotropic than the 4-neighbour version — it responds equally to edges in all directions, including diagonals, which matters for natural subjects like feathers and fur.

The sharpness energy at each pixel is then computed as a luminance-weighted magnitude:

energy = |L.r| × 0.299 + |L.g| × 0.587 + |L.b| × 0.114

This preserves perceptual weighting — the green channel contributes most, matching human sensitivity to luminance detail.


Step-by-Step: How It Works

1. Downscale. The image is reduced to 1024 pixels wide before processing. The algorithm operates on pixel neighbourhoods, so full resolution is unnecessary and the performance gain is significant.

2. Pre-blur (Gaussian). A Gaussian blur is applied to the downscaled image. This suppresses out-of-focus texture and sensor noise before the Laplacian runs, preventing false highlights in blurred regions. The blur radius is adaptive: the base value set in the Focus Peak controls is scaled upward automatically — by up to 3× — based on the image’s ISO value (higher ISO → more noise → larger radius) and the image resolution (larger images → radius scaled by √(width/512) to maintain consistent edge selectivity). CIGaussianBlur accepts a maximum radius of 100; the effective radius is clamped to that limit.

3. Laplacian kernel (Metal GPU). The 8-neighbour kernel runs on every pixel in parallel on the GPU, computing the second-order derivative of brightness across all channels.

4. Energy and amplification. The per-pixel result is converted to a single luminance-weighted sharpness energy value and amplified. The amplification factor is user-adjustable.

5. Threshold. Any pixel below the threshold is discarded (black). Only genuinely sharp pixels survive. The threshold is the primary control — lower values highlight more of the image, higher values restrict highlights to only the sharpest edges.

6. Erosion. A morphological erosion pass removes isolated speckle pixels that survive the threshold but are too small to represent genuine edges. The erosion radius is quantised to the nearest whole pixel (a radius of 0 skips this pass). This cleans up the mask before it is expanded.

7. Dilation. Surviving pixels are expanded morphologically, turning scattered dots into solid readable regions without introducing false edges. The dilation radius is likewise quantised to whole pixels.

8. Border inset. The outer 4 % of each edge is zeroed out before the mask is composited. This matches the same inset used by the sharpness scorer and prevents Gaussian pre-blur edge artifacts — a thin blurry fringe that forms where the blur kernel reaches past the image border — from appearing as false focus highlights around the frame edge.

9. Red overlay. Surviving pixels are colourised red and composited over the original photograph using a screen blend mode. Black (non-sharp) areas are transparent in screen blending, so only the red sharpness regions show through over the photo.

10. Feather. A final Gaussian blur softens the edges of the red overlay, giving the mask a smooth, natural appearance rather than a hard pixelated boundary.


Tunable Parameters

RawCull exposes the following controls in the Focus Peak panel:

ControlEffect
Pre-blurBase Gaussian blur radius applied before edge detection. The effective radius is scaled automatically with the image’s ISO value and resolution — this control sets the baseline from which adaptive scaling is applied. Higher values suppress background texture and high-ISO noise more aggressively.
ThresholdPrimary sharpness cutoff. Raise to restrict highlights to only the sharpest edges; lower to highlight more of the image. Default 0.46.
Erosion radiusMorphological erosion applied after thresholding. Removes isolated speckle noise before dilation. Quantised to whole pixels — set to 0 to skip. Default 1 px.
Dilation radiusMorphological expansion applied after erosion. Widens edge regions into solid, readable patches — increase for small or fine-detailed subjects. Quantised to whole pixels — set to 0 to skip. Default 1 px.
AmplifyMultiplier applied to the raw sharpness signal. Higher values make weak edges more visible; too high reintroduces noise.
FeatherGaussian softening applied to the final mask edges. Visual only — does not affect the underlying score.
Show raw LaplacianReplaces the thresholded overlay with the unprocessed Laplacian output. Useful for diagnosing tuning or calibration issues.

A Reset button returns all values to their defaults.


Practical Considerations

Threshold tuning is the most important variable. Too low and nearly the entire image lights up. Too high and only the absolute sharpest micro-contrast registers. The default of 0.46 suits most sessions well; adjust up or down from there based on the scene.

Pre-blur is your noise lever — but it adapts automatically. The effective pre-blur radius is scaled by the image’s EXIF ISO value (√(ISO/400), capped at 3×) and by the image width (√(width/512), capped at 3×), so high-ISO files and larger images automatically receive more pre-smoothing without manual intervention. The slider sets the baseline; adjust it upward for scenes with particularly prominent out-of-focus texture — water, foliage, bokeh — or downward for very clean, low-ISO files where you want maximum edge sensitivity.

Subject texture matters. Smooth, low-contrast surfaces — clear sky, still water, skin — produce a weak Laplacian response even when perfectly focused, because there is little edge detail to detect. Focus peaking works best on subjects with natural texture: feathers, fur, foliage, fabric.

RAW vs JPG. The mask is more effective when applied to extracted JPGs rather than thumbnails. Thumbnails are heavily processed and downscaled before RawCull sees them, which reduces the fine edge detail the Laplacian depends on.


Summary

RawCull’s Focus Peaking runs a Laplacian of Gaussian pipeline entirely on the GPU via Metal. An ISO- and resolution-adaptive Gaussian pre-blur suppresses noise and out-of-focus texture; an 8-neighbour Laplacian kernel detects genuine sharpness spikes; thresholding followed by morphological erosion and dilation (both quantised to whole pixels) produces a clean, solid mask; a 4 % border inset removes pre-blur edge artifacts; a final feather pass softens the overlay edges; and screen blending composites the red overlay non-destructively over the original image. The result is a fast, accurate, and visually interpretable sharpness map that makes focus assessment immediate — particularly valuable when reviewing large numbers of action or wildlife shots where critical focus on a small moving subject is difficult to judge from the image alone.


6 - Settings

Settings view

RawCull provides settings to customize your culling experience and optimize performance:

  • Cache Management: Control thumbnail cache location and size to balance performance with disk space usage
  • Thumbnail Quality: Adjust thumbnail generation settings to optimize preview quality and loading speed
  • Memory Settings: Configure memory allocation for handling large photo catalogs efficiently

Access these settings via RawCull → Settings to fine-tune RawCull for your specific needs and system configuration. The cache statistics present the memory hit-rate when viewing photos.

RawCull startup screen
RawCull startup screen

The memory tab displays the memory utilized, the total memory capacity, and a memory-pressure warning.

RawCull startup screen

7 - Focus Points

RawCull facilitates native extraction of Focus Points from Sony A1 ARW files. Users have the option to activate or deactivate the Focus Points feature in both the primary thumbnail view and the extracted zoom views.

Focus Point off:

RawCull scanning photo library

Focus Point on:

RawCull scanning photo library

Both the Focus Point and the Focus Peak can be applied simultaneously.

RawCull scanning photo library
RawCull scanning photo library