<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RawCull</title><link>https://rawcull.netlify.app/</link><description>Recent content on RawCull</description><generator>Hugo</generator><language>en</language><atom:link href="https://rawcull.netlify.app/index.xml" rel="self" type="application/rss+xml"/><item><title>Swift Concurrency in RawCull</title><link>https://rawcull.netlify.app/blog/2026/03/26/swift-concurrency-in-rawcull/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/26/swift-concurrency-in-rawcull/</guid><description>&lt;h1 id="swift-concurrency-in-rawcull"&gt;Swift Concurrency in RawCull&lt;a class="td-heading-self-link" href="#swift-concurrency-in-rawcull" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A summarized document about Concurrency in RawCull.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1--why-concurrency-matters-in-rawcull"&gt;1 Why Concurrency Matters in RawCull&lt;a class="td-heading-self-link" href="#1--why-concurrency-matters-in-rawcull" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;RawCull is a macOS photo-culling application that works with Sony A1 ARW raw files. A single RAW file from the A1 can be 50–80 MB. When you open a folder with hundreds of shots, the app must scan metadata, extract embedded JPEG previews, decode thumbnails, and manage a multi-gigabyte in-memory cache — all while keeping the UI perfectly fluid and responsive at 60 fps. Without concurrency that would be impossible.&lt;/p&gt;</description></item><item><title>Sharpness Scoring</title><link>https://rawcull.netlify.app/blog/2026/03/25/sharpness-scoring/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/25/sharpness-scoring/</guid><description>&lt;h1 id="updated-sharpness-scoring-in-rawcull"&gt;Updated Sharpness Scoring in RawCull&lt;a class="td-heading-self-link" href="#updated-sharpness-scoring-in-rawcull" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This document describes how RawCull computes sharpness scores, what each parameter does, and a boundary-value test procedure for validating parameter behaviour. This applies to version 1.3.7 of RawCull&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="how-the-scoring-pipeline-works"&gt;How the Scoring Pipeline Works&lt;a class="td-heading-self-link" href="#how-the-scoring-pipeline-works" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 A([ARW File]) --&amp;gt; B[Thumbnail decode\nthumbnailMaxPixelSize]
 A --&amp;gt; C[Saliency detection\nApple Vision]

 B --&amp;gt; D[Gaussian pre-blur\npreBlurRadius × isoFactor × resFactor]
 D --&amp;gt; E[Laplacian Metal kernel\nfocusLaplacian]
 E --&amp;gt; F[Amplify\nenergyMultiplier]
 F --&amp;gt; G[Border suppression\nborderInsetFraction]
 G --&amp;gt; H[Render to Float32 buffer]

 H --&amp;gt; I[Full-frame samples\nborder-inset region]
 C --&amp;gt;|bounding box ≥ 3% area| J[Salient-region samples\nVision bounding box]
 H --&amp;gt; J

 I --&amp;gt; K[p95 winsorized tail score\nfull-frame f]
 J --&amp;gt; L[p95 winsorized tail score\nsubject s]

 K --&amp;gt; M{Fusion}
 L --&amp;gt; M
 C --&amp;gt;|area| M

 M --&amp;gt; N[finalScore]
 N --&amp;gt; O([Badge: score / maxScore × 100])

 style A fill:#2d2d2d,color:#fff
 style O fill:#2d2d2d,color:#fff&lt;/pre&gt;
&lt;p&gt;Each ARW file goes through the following stages in detail:&lt;/p&gt;</description></item><item><title>Threads</title><link>https://rawcull.netlify.app/blog/2026/03/25/threads/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/25/threads/</guid><description>&lt;h1 id="concurrency-monitoring--scanfiles"&gt;Concurrency Monitoring — ScanFiles&lt;a class="td-heading-self-link" href="#concurrency-monitoring--scanfiles" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="analysis"&gt;Analysis&lt;a class="td-heading-self-link" href="#analysis" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="the-cooperative-thread-pool"&gt;The cooperative thread pool&lt;a class="td-heading-self-link" href="#the-cooperative-thread-pool" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Swift&amp;rsquo;s runtime manages a pool of threads capped at roughly the number of CPU cores. Apple Silicon M-series typically has 8–12 performance cores. The output shows a peak of ~10–11 concurrent tasks, which matches this ceiling. This is intentional — the runtime will not spin up 21 threads for 21 tasks because context-switching that many threads would cost more than the parallelism gains.&lt;/p&gt;</description></item><item><title>Security &amp; Privacy</title><link>https://rawcull.netlify.app/docs/security/</link><pubDate>Mon, 23 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/docs/security/</guid><description>&lt;h2 id="security--privacy"&gt;Security &amp;amp; Privacy&lt;a class="td-heading-self-link" href="#security--privacy" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="app-sandbox"&gt;App Sandbox&lt;a class="td-heading-self-link" href="#app-sandbox" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;RawCull runs inside the &lt;strong&gt;macOS App Sandbox&lt;/strong&gt; (&lt;code&gt;com.apple.security.app-sandbox = true&lt;/code&gt;), enforced by the operating system. The entitlements file contains only this single declaration — no additional entitlements are granted. This means:&lt;/p&gt;</description></item><item><title>Memory Cache</title><link>https://rawcull.netlify.app/blog/2026/03/17/memory-cache/</link><pubDate>Tue, 17 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/17/memory-cache/</guid><description>&lt;h1 id="cache-system--rawcull"&gt;Cache System — RawCull&lt;a class="td-heading-self-link" href="#cache-system--rawcull" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;RawCull uses a three-layer cache to avoid repeated RAW decoding. Decoding an ARW file on demand is expensive — the three-layer approach ensures that most requests are served from RAM or disk rather than from source.&lt;/p&gt;
&lt;p&gt;Layers (fastest to slowest):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Memory cache&lt;/strong&gt; — &lt;code&gt;NSCache&amp;lt;NSURL, DiscardableThumbnail&amp;gt;&lt;/code&gt; in RAM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Disk cache&lt;/strong&gt; — JPEG files on disk in &lt;code&gt;~/Library/Caches/no.blogspot.RawCull/Thumbnails/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Source decode&lt;/strong&gt; — &lt;code&gt;CGImageSourceCreateThumbnailAtIndex&lt;/code&gt; from the ARW file&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The same cache stack is shared by two paths: the bulk preload flow (&lt;code&gt;ScanAndCreateThumbnails&lt;/code&gt;) and on-demand per-file requests (&lt;code&gt;RequestThumbnail&lt;/code&gt;).&lt;/p&gt;</description></item><item><title>Thumbnails</title><link>https://rawcull.netlify.app/blog/2026/03/17/thumbnails/</link><pubDate>Tue, 17 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/17/thumbnails/</guid><description>&lt;h1 id="thumbnails-and-previews--rawcull"&gt;Thumbnails and Previews — RawCull&lt;a class="td-heading-self-link" href="#thumbnails-and-previews--rawcull" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;RawCull handles Sony ARW files through two distinct image paths:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Generated thumbnails&lt;/strong&gt; — fast, sized-down previews for browsing and culling, extracted with ImageIO and cached in RAM and on disk&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embedded JPEG previews&lt;/strong&gt; — full-resolution embedded JPEGs extracted from the ARW binary for high-quality inspection and export&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Both paths integrate with the shared three-layer cache system: RAM → disk → source decode.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-thumbnail-sizes-and-settings"&gt;1. Thumbnail Sizes and Settings&lt;a class="td-heading-self-link" href="#1-thumbnail-sizes-and-settings" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All thumbnail dimensions are configurable via &lt;code&gt;SettingsViewModel&lt;/code&gt; and persisted to &lt;code&gt;~/Library/Application Support/RawCull/settings.json&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Culling Photos</title><link>https://rawcull.netlify.app/docs/culling/</link><pubDate>Sun, 01 Feb 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/docs/culling/</guid><description>&lt;blockquote&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;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 &lt;a href="https://rawcull.netlify.app/docs/focuspeaking/"&gt;Focus Peaking&lt;/a&gt; and &lt;a href="https://rawcull.netlify.app/docs/focuspoints/"&gt;Focus Points&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="persistent-marking-and-session-recovery"&gt;Persistent Marking and Session Recovery&lt;a class="td-heading-self-link" href="#persistent-marking-and-session-recovery" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;</description></item><item><title>Sharpness Scoring</title><link>https://rawcull.netlify.app/docs/sharpness/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/docs/sharpness/</guid><description>&lt;h1 id="sharpness-scoring"&gt;Sharpness Scoring&lt;a class="td-heading-self-link" href="#sharpness-scoring" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;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. This page explains what the score means, how to run it, and how to interpret the results.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="td-heading-self-link" href="#overview" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you click &lt;strong&gt;Sharpness&lt;/strong&gt;, RawCull analyses each RAW file using a multi-step pipeline:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A small thumbnail is extracted directly from the ARW file — fast, no full RAW decode needed.&lt;/li&gt;
&lt;li&gt;Apple Vision locates the main subject in the frame and, when classification is enabled, identifies what that subject is (bird, person, animal, etc.). A salient region is accepted when it covers more than 3 % of the frame &lt;strong&gt;or&lt;/strong&gt; when Vision&amp;rsquo;s confidence is ≥ 0.9 — the high-confidence path means a small but clearly identifiable subject (a bird on a stick, a distant raptor) is never discarded for being too small.&lt;/li&gt;
&lt;li&gt;A Gaussian pre-blur smooths the image to suppress high-ISO noise before edge detection. The radius adapts automatically: it scales proportionally with √(ISO/400) to compensate for noise at high ISO values, and with √(imageWidth/512) to maintain consistent spatial-frequency selectivity on larger images. Both factors are capped at 3×.&lt;/li&gt;
&lt;li&gt;A Laplacian edge-detection kernel measures per-pixel sharpness energy across the entire frame. The outer 4 % of each border is excluded from the full-frame score to prevent Gaussian edge artifacts from inflating the result.&lt;/li&gt;
&lt;li&gt;The edge response is amplified, then scored with a &lt;strong&gt;robust tail score&lt;/strong&gt; — the mean of values above the 95th percentile, clipped at the 99.5th — so a single sharp feather edge cannot carry a blurry frame.&lt;/li&gt;
&lt;li&gt;Two scores are computed separately: one for the full frame (minus the border strip) and one for the salient subject region. They are fused as &lt;strong&gt;25 % full-frame + 75 % subject region&lt;/strong&gt;. If no salient region is found, the full-frame score is used directly. A small proportional bonus is applied for subjects that fill more of the frame.&lt;/li&gt;
&lt;li&gt;All scores are normalised against the p90 of the catalog: that anchor becomes &lt;strong&gt;100&lt;/strong&gt;, and every other frame is expressed as a percentage of it. Using p90 rather than the maximum prevents a single noise spike from collapsing the rest of the scale.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Because scores are &lt;strong&gt;relative to your catalog&lt;/strong&gt;, a score of 60 does not mean the image is soft — it means it is 60 % as sharp as the sharpest typical frame in that session. Opening a catalog of sharper images will recalibrate the scale.&lt;/p&gt;</description></item><item><title>Focus Peaking</title><link>https://rawcull.netlify.app/docs/focuspeaking/</link><pubDate>Wed, 11 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/docs/focuspeaking/</guid><description>&lt;h1 id="focus-peaking-the-laplacian-of-gaussian-method"&gt;Focus Peaking: The Laplacian of Gaussian Method&lt;a class="td-heading-self-link" href="#focus-peaking-the-laplacian-of-gaussian-method" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; 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 &lt;em&gt;the image in main view&lt;/em&gt;. In the Settings menu, &lt;em&gt;Thumbnails tab&lt;/em&gt;, &lt;strong&gt;disable&lt;/strong&gt; the &amp;ldquo;Use Thumbnail for Zoom&amp;rdquo; to use JPGs as base for Focus Peak.&lt;/p&gt;</description></item><item><title>Settings</title><link>https://rawcull.netlify.app/docs/settings/</link><pubDate>Fri, 20 Feb 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/docs/settings/</guid><description>&lt;h2 id="settings-view"&gt;Settings view&lt;a class="td-heading-self-link" href="#settings-view" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;RawCull provides settings to customize your culling experience and optimize performance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cache Management&lt;/strong&gt;: Control thumbnail cache location and size to balance performance with disk space usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Thumbnail Quality&lt;/strong&gt;: Adjust thumbnail generation settings to optimize preview quality and loading speed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory Settings&lt;/strong&gt;: Configure memory allocation for handling large photo catalogs efficiently&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Access these settings via &lt;em&gt;RawCull → Settings&lt;/em&gt; to fine-tune RawCull for your specific needs and system configuration. The cache statistics present the memory hit-rate when viewing photos.&lt;/p&gt;</description></item><item><title>Focus Points</title><link>https://rawcull.netlify.app/docs/focuspoints/</link><pubDate>Mon, 02 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/docs/focuspoints/</guid><description>&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Focus Point off:&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://rawcull.netlify.app/images/focuspoints/focuspointbefore.png"
 alt="RawCull scanning photo library"&gt;
&lt;/figure&gt;

&lt;p&gt;Focus Point on:&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://rawcull.netlify.app/images/focuspoints/focuspointapplied.png"
 alt="RawCull scanning photo library"&gt;
&lt;/figure&gt;

&lt;p&gt;Both the Focus Point and the Focus Peak can be applied simultaneously.&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://rawcull.netlify.app/images/focuspoints/focuspointandmaskapplied.png"
 alt="RawCull scanning photo library"&gt;
&lt;/figure&gt;

&lt;figure&gt;&lt;img src="https://rawcull.netlify.app/images/focuspoints/mainfocuspointandmaskapplied.png"
 alt="RawCull scanning photo library"&gt;
&lt;/figure&gt;</description></item><item><title>Version 1.4.0</title><link>https://rawcull.netlify.app/blog/2026/04/07/version-1.4.0/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/04/07/version-1.4.0/</guid><description>&lt;h3 id="version-140---april-7-2026"&gt;Version 1.4.0 - April 7, 2026&lt;a class="td-heading-self-link" href="#version-140---april-7-2026" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;RawCull supports a broader range of Sony FullFrame camera bodies. See table below for what is tested now.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="rawcull-changes-summary-v135--v140"&gt;RawCull Changes Summary (v1.3.5 → v1.4.0)&lt;a class="td-heading-self-link" href="#rawcull-changes-summary-v135--v140" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sharpness scoring was significantly upgraded&lt;/strong&gt;: added saliency-aware scoring, optional subject classification, subject-based filtering, configurable scoring parameters, and improved normalization/progress handling.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;New UI controls and views&lt;/strong&gt; were added around scoring and stats:
&lt;ul&gt;
&lt;li&gt;new &lt;strong&gt;Scoring Parameters&lt;/strong&gt; sheet&lt;/li&gt;
&lt;li&gt;new &lt;strong&gt;Scan Summary/Statistics&lt;/strong&gt; sheet&lt;/li&gt;
&lt;li&gt;toolbar toggles for &lt;strong&gt;score badge&lt;/strong&gt; and &lt;strong&gt;saliency badge&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;expanded culling/rating status display (including per-star counts).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EXIF/metadata support expanded&lt;/strong&gt;: now includes RAW compression type, size class (L/M/S), and pixel dimensions; these are surfaced in inspector UI.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sony compatibility work&lt;/strong&gt;: maker-note parser now supports more Sony bodies and adds robust diagnostics/full-file fallback for focus metadata extraction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance/state management improvements&lt;/strong&gt;: rating/tag caching for O(1) lookups, better cancellation behavior in scoring, memory warning refinements (soft/full), and various cleanup/refactors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Persistence/settings updates&lt;/strong&gt;: settings now store badge visibility toggles and decode safely with defaults.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing expanded&lt;/strong&gt; with a large new ARW body compatibility diagnostic test suite plus concurrency/sendability test adjustments.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="arw-body-compatibility-diagnostic"&gt;ARW body compatibility diagnostic&lt;a class="td-heading-self-link" href="#arw-body-compatibility-diagnostic" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;</description></item><item><title>Version 1.4.1</title><link>https://rawcull.netlify.app/blog/2026/04/07/version-1.4.1/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/04/07/version-1.4.1/</guid><description>&lt;h3 id="version-141---april-7-2026"&gt;Version 1.4.1 - April 7, 2026&lt;a class="td-heading-self-link" href="#version-141---april-7-2026" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;RawCull supports a broader range of Sony FullFrame camera bodies. See table below for what is tested now.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="rawcull-changes-summary-v140--v141"&gt;RawCull Changes Summary (v1.4.0 → v1.4.1)&lt;a class="td-heading-self-link" href="#rawcull-changes-summary-v140--v141" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Version 1.4.1 solves an issue with Sony A7V (ILCE-7M5) Compressed ARW file.&lt;/p&gt;
&lt;h3 id="arw-body-compatibility-diagnostic"&gt;ARW body compatibility diagnostic&lt;a class="td-heading-self-link" href="#arw-body-compatibility-diagnostic" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;</description></item><item><title>Version 1.3.5</title><link>https://rawcull.netlify.app/blog/2026/04/04/version-1.3.5/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/04/04/version-1.3.5/</guid><description>&lt;h3 id="version-135---april-4-2026"&gt;Version 1.3.5 - April 4, 2026&lt;a class="td-heading-self-link" href="#version-135---april-4-2026" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;April 4, 2026:
It has been observed that RawCull supports a broader range of Sony FullFrame camera bodies. I have conducted tests on ARW files for the Sony A7RV and the newly released Sony A7V. After Easter, I plan to acquire additional full-frame ARW files from Sony A bodies to conduct further tests. Upon the completion of these tests, I will compile a comprehensive list of the Sony bodies that RawCull supports.&lt;/p&gt;</description></item><item><title>Version 1.3.3</title><link>https://rawcull.netlify.app/blog/2026/04/02/version-1.3.3/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/04/02/version-1.3.3/</guid><description>&lt;h3 id="version-133---april-2-2026"&gt;Version 1.3.3 - April 2, 2026&lt;a class="td-heading-self-link" href="#version-133---april-2-2026" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;RawCull is developed for culling Sony A1 mkI and mkII ARW files. However, I have recently tested RawCull on Sony 7RV and the new Sony 7V, and it appears that all functions are functioning correctly on these models as well.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this release, RawCull supports culling by color. Please refer to the Culling section in the documentation for further details. Additionally, updates have been made to the Focus Mask and pre-calibration in Sharpness Scoring.&lt;/p&gt;</description></item><item><title>Version 1.2.8</title><link>https://rawcull.netlify.app/blog/2026/03/30/version-1.2.8/</link><pubDate>Mon, 30 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/30/version-1.2.8/</guid><description>&lt;h3 id="version-128---march-30-2026"&gt;Version 1.2.8 - March 30, 2026&lt;a class="td-heading-self-link" href="#version-128---march-30-2026" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;RawCull is developed for culling Sony A1 mkI and mkII ARW files. However, I have recently tested RawCull on Sony 7RV and the new Sony 7V, and it appears that all functions are functioning correctly on these models as well.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Code cleanup and several minor bugs were resolved. Additionally, a focus issue was addressed, eliminating the need for two clicks on either vertical or horizontal thumbnail row before utilizing arrow keys for navigation and tagging. Now, a single click suffices to achieve the desired focus. Furthermore, the tag command was modified to a single keypress of &lt;code&gt;t&lt;/code&gt;, enabling tagging or detagging functionality.&lt;/p&gt;</description></item><item><title>Scan and Thumbnial Pipeline</title><link>https://rawcull.netlify.app/blog/2026/03/25/scan-and-thumbnial-pipeline/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/25/scan-and-thumbnial-pipeline/</guid><description>&lt;h1 id="rawcull--scan-and-thumbnail-pipeline"&gt;RawCull — Scan and Thumbnail Pipeline&lt;a class="td-heading-self-link" href="#rawcull--scan-and-thumbnail-pipeline" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This document describes the complete execution flow from the moment a user opens
a catalog folder to the point where all thumbnails are visible in the grid.
It covers the actors involved, the data flow between them, the concurrency
model, five performance bugs that were found and fixed, and the measured results
on a real catalog of 809 Sony A1 ARW files stored on an external 800 MB/s SSD.&lt;/p&gt;</description></item><item><title>Sony MakerNote Parser</title><link>https://rawcull.netlify.app/blog/2026/03/25/sony-makernote-parser/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/25/sony-makernote-parser/</guid><description>&lt;h1 id="sony-makernote-parser--focus-point-extraction"&gt;Sony MakerNote Parser — Focus Point Extraction&lt;a class="td-heading-self-link" href="#sony-makernote-parser--focus-point-extraction" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Files covered:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RawCull/Enum/SonyMakerNoteParser.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Model/ViewModels/FocusPointsModel.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Actors/ScanFiles.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Views/FocusPoints/FocusOverlayView.swift&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="td-heading-self-link" href="#overview" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;RawCull extracts autofocus (AF) focus point coordinates directly from Sony ARW
raw files without requiring any external tools such as &lt;code&gt;exiftool&lt;/code&gt;. The parser
targets the Sony A1 (ILCE-1) and A1 Mark II (ILCE-1M2) cameras.&lt;/p&gt;
&lt;p&gt;The focus location is stored inside the Sony proprietary MakerNote block
embedded in the EXIF data of every ARW file. The &lt;code&gt;SonyMakerNoteParser&lt;/code&gt; struct
navigates the binary TIFF structure to locate and decode this data.&lt;/p&gt;</description></item><item><title>Concurrency model</title><link>https://rawcull.netlify.app/blog/2026/03/17/concurrency-model/</link><pubDate>Tue, 17 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/17/concurrency-model/</guid><description>&lt;h1 id="concurrency-model--rawcull"&gt;Concurrency Model — RawCull&lt;a class="td-heading-self-link" href="#concurrency-model--rawcull" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Files covered:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RawCull/Model/ViewModels/RawCullViewModel.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Views/RawCullSidebarMainView/extension+RawCullView.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Actors/ScanFiles.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Actors/ScanAndCreateThumbnails.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Actors/ExtractAndSaveJPGs.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Actors/ThumbnailLoader.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Actors/RequestThumbnail.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Actors/SharedMemoryCache.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Actors/DiskCacheManager.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Actors/SaveJPGImage.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Enum/SonyThumbnailExtractor.swift&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RawCull/Enum/JPGSonyARWExtractor.swift&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="td-heading-self-link" href="#overview" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;RawCull uses Swift structured concurrency (&lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt;, &lt;code&gt;Task&lt;/code&gt;, &lt;code&gt;TaskGroup&lt;/code&gt;, and &lt;code&gt;actor&lt;/code&gt;) across four primary flows:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Flow&lt;/th&gt;
 &lt;th&gt;Entry point&lt;/th&gt;
 &lt;th&gt;Core actor(s)&lt;/th&gt;
 &lt;th&gt;Purpose&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Catalog scan&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;RawCullViewModel.handleSourceChange(url:)&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ScanFiles&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Scan ARW files, extract metadata, load focus points&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Thumbnail preload&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;RawCullViewModel.handleSourceChange(url:)&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ScanAndCreateThumbnails&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Bulk-populate the thumbnail cache for a selected catalog&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;JPG extraction&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;extension+RawCullView.extractAllJPGS()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ExtractAndSaveJPGs&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Extract embedded JPEG previews and save to disk&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;On-demand thumbnails&lt;/td&gt;
 &lt;td&gt;UI grid + detail views&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ThumbnailLoader&lt;/code&gt;, &lt;code&gt;RequestThumbnail&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Rate-limited, cached per-file thumbnail retrieval&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The two long-running operations (thumbnail preload and JPG extraction) share a &lt;strong&gt;two-level task pattern&lt;/strong&gt;:&lt;/p&gt;</description></item><item><title>Synchronous Code</title><link>https://rawcull.netlify.app/blog/2026/02/19/synchronous-code/</link><pubDate>Thu, 19 Feb 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/02/19/synchronous-code/</guid><description>&lt;h1 id="a-guide-to-handling-heavy-synchronous-code-in-swift-concurrency"&gt;A Guide to Handling Heavy Synchronous Code in Swift Concurrency&lt;a class="td-heading-self-link" href="#a-guide-to-handling-heavy-synchronous-code-in-swift-concurrency" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This post explains why CPU-intensive synchronous code (such as image decoding via ImageIO) must be dispatched off the Swift Concurrency thread pool, and shows the correct patterns RawCull uses to do so.&lt;/p&gt;
&lt;h2 id="dispatchqueueglobalqos--qos-levels-compared"&gt;&lt;code&gt;DispatchQueue.global(qos:)&lt;/code&gt; — QoS Levels Compared&lt;a class="td-heading-self-link" href="#dispatchqueueglobalqos--qos-levels-compared" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The key difference is &lt;strong&gt;priority and resource allocation&lt;/strong&gt; by the system.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="userinitiated"&gt;&lt;code&gt;.userInitiated&lt;/code&gt;&lt;a class="td-heading-self-link" href="#userinitiated" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Priority:&lt;/strong&gt; High (just below &lt;code&gt;.userInteractive&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Work the &lt;strong&gt;user directly triggered&lt;/strong&gt; and is actively waiting for — e.g., loading a document they tapped, parsing data to display a screen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expected duration:&lt;/strong&gt; Near-instantaneous to a few seconds&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System behavior:&lt;/strong&gt; Gets &lt;strong&gt;more CPU time and higher thread priority&lt;/strong&gt; — the system treats this as urgent&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Energy impact:&lt;/strong&gt; Higher&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="utility"&gt;&lt;code&gt;.utility&lt;/code&gt;&lt;a class="td-heading-self-link" href="#utility" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Priority:&lt;/strong&gt; Low-medium&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Long-running work the user is &lt;strong&gt;aware of but not blocked by&lt;/strong&gt; — e.g., downloading files, importing data, periodic syncs, progress-bar tasks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expected duration:&lt;/strong&gt; Seconds to minutes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System behavior:&lt;/strong&gt; Balanced CPU/energy trade-off; the system &lt;strong&gt;throttles this more aggressively&lt;/strong&gt; under load or low battery&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Energy impact:&lt;/strong&gt; Lower (system may apply energy efficiency optimizations)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="quick-comparison"&gt;Quick Comparison&lt;a class="td-heading-self-link" href="#quick-comparison" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;code&gt;.userInitiated&lt;/code&gt;&lt;/th&gt;
 &lt;th&gt;&lt;code&gt;.utility&lt;/code&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Priority&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;High&lt;/td&gt;
 &lt;td&gt;Low-medium&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;User waiting?&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Yes, directly&lt;/td&gt;
 &lt;td&gt;Aware but not blocked&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Duration&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&amp;lt; a few seconds&lt;/td&gt;
 &lt;td&gt;Seconds to minutes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;CPU allocation&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Aggressive&lt;/td&gt;
 &lt;td&gt;Conservative&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Battery impact&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Higher&lt;/td&gt;
 &lt;td&gt;Lower&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Thread pool&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Higher-priority threads&lt;/td&gt;
 &lt;td&gt;Lower-priority threads&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="rule-of-thumb"&gt;Rule of thumb&lt;a class="td-heading-self-link" href="#rule-of-thumb" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-swift" data-lang="swift"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;// User tapped &amp;#34;Load&amp;#34; and is staring at a spinner → userInitiated&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;DispatchQueue&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;.&lt;/span&gt;&lt;span style="color:#000"&gt;global&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;(&lt;/span&gt;&lt;span style="color:#000"&gt;qos&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;.&lt;/span&gt;&lt;span style="color:#000"&gt;userInitiated&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;).&lt;/span&gt;&lt;span style="color:#000"&gt;async&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#204a87;font-weight:bold"&gt;let&lt;/span&gt; &lt;span style="color:#000"&gt;data&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;=&lt;/span&gt; &lt;span style="color:#000"&gt;loadCriticalData&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000;font-weight:bold"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;// Background sync / download with a progress bar → utility&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;DispatchQueue&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;.&lt;/span&gt;&lt;span style="color:#000"&gt;global&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;(&lt;/span&gt;&lt;span style="color:#000"&gt;qos&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;.&lt;/span&gt;&lt;span style="color:#000"&gt;utility&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;).&lt;/span&gt;&lt;span style="color:#000"&gt;async&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#000"&gt;downloadLargeFile&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000;font-weight:bold"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;If you use &lt;code&gt;.userInitiated&lt;/code&gt; for everything&lt;/strong&gt;, you waste battery and CPU on non-urgent work. &lt;strong&gt;If you use &lt;code&gt;.utility&lt;/code&gt; for user-blocking tasks&lt;/strong&gt;, the UI will feel sluggish because the system may deprioritize the work.&lt;/p&gt;</description></item><item><title>Security-Scoped URLs</title><link>https://rawcull.netlify.app/blog/2026/02/05/security-scoped-urls/</link><pubDate>Thu, 05 Feb 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/02/05/security-scoped-urls/</guid><description>&lt;p&gt;Security-scoped URLs are a cornerstone of macOS App Sandbox security. RawCull uses them to gain persistent, user-approved access to source and destination folders while remaining fully sandbox-compliant. This article walks through exactly how the implementation works, tracing the code from user interaction through to file operations.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="what-are-security-scoped-urls"&gt;What Are Security-Scoped URLs?&lt;a class="td-heading-self-link" href="#what-are-security-scoped-urls" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A security-scoped URL is a special file URL that carries a cryptographic capability granted by macOS, representing explicit user consent to access a specific file or folder. Without it, a sandboxed app cannot read or write anything outside its own container.&lt;/p&gt;</description></item><item><title>Compiling RawCull</title><link>https://rawcull.netlify.app/blog/2026/02/01/compiling-rawcull/</link><pubDate>Sun, 01 Feb 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/02/01/compiling-rawcull/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;a class="td-heading-self-link" href="#overview" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div class="alert alert-info" role="alert"&gt;
&lt;p&gt;There are three methods to compile RawCull: one without an Apple Developer account and two with an Apple Developer account. Regardless of the method used, it is straightforward to compile RawCull, as it is not dependent on any third-party code or library.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The easiest method is by using the included Makefile. The default make in &lt;code&gt;/usr/bin/make&lt;/code&gt; does the job.&lt;/p&gt;
&lt;h3 id="compile-by-make"&gt;Compile by make&lt;a class="td-heading-self-link" href="#compile-by-make" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you have an Apple Developer account, you should open the RawCull project and replace the &lt;code&gt;Signing &amp;amp; Capabilities&lt;/code&gt; section with your own Apple Developer ID before using &lt;code&gt;make&lt;/code&gt; and the procedure outlined below.&lt;/p&gt;</description></item><item><title>About</title><link>https://rawcull.netlify.app/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/about/</guid><description>&lt;section id="td-cover-block-0" class="row td-cover-block td-cover-block--height-auto js-td-cover td-overlay td-overlay--dark -bg-dark" &gt;
 &lt;div class="col-12"&gt;
 &lt;div class="container td-overlay__inner"&gt;
 &lt;div class="text-center"&gt;
 &lt;h1 class="display-1 mt-0 mt-md-5 pb-4"&gt;About RawCull&lt;/h1&gt;
 &lt;div class="pt-3 lead"&gt;
&lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
&lt;/section&gt;
&lt;div&gt;&lt;a id="td-block-1" class="td-anchor-no-extra-offset"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;section class="row td-box td-box--primary td-box--height-auto"&gt;
&lt;div class="col"&gt;
&lt;div class="container"&gt;
&lt;h2 id="about-rawcull"&gt;About RawCull&lt;a class="td-heading-self-link" href="#about-rawcull" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;If you have ideas, feedback, or suggestions about RawCull, please reach out to me at &lt;a href="mailto:thomeven@gmail.com"&gt;thomeven@gmail.com&lt;/a&gt;. I&amp;rsquo;d love to hear from you.&lt;/p&gt;
&lt;h3 id="background"&gt;Background&lt;a class="td-heading-self-link" href="#background" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I started RsyncOSX in August 2016 as a way to learn Swift, and after eight years of releases, it was archived in August 2024. RsyncUI, built with SwiftUI, began in late 2020 and continues to be actively developed. RawCull represents my latest venture into building specialized macOS applications with modern Swift technologies.&lt;/p&gt;</description></item></channel></rss>