The problem#

After an event, the photos are delivered but the RAW files stay. Drives fill up. Backups grow. Buying another disk postpones the same problem.

Exporting JPEGs saves space but gives up the RAW editing workflow. I wanted smaller files that still open in Lightroom with white balance, exposure and camera profiles available.

What I built#

Squeeze pairs a native Swift macOS app with a Rust encoder that writes JPEG XL inside DNG 1.7. Drop in photos, review the estimate and convert. Adobe DNG Converter provides a fallback when the built-in engine cannot decode a file.

The output stays editable in Lightroom and Adobe Camera Raw. This is lossy compression, not a claim that every original sensor value survives. The point is to preserve a useful editing workflow while reducing storage.

Squeeze conversion in progress with pause, stop and per-file details
Conversion progress stays visible, with pause, stop and file details. This UI capture is not a speed benchmark.

Results#

62–95%smaller in tests across 5 camera brands
502.7 MB → 30.3 MB9-photo event · 1 min 49 s
Untouchedoriginals never modified

The five-brand test used one sample each from Canon, Nikon, Panasonic, Sony and Fuji. It is a measured range, not a promise for every camera or photo. The nine-photo Fuji X-T5 event result includes denoising with DxO DeepPRIME 3 before shrinking.

Canon EOS R5 photo split between the before reference and compressed output
Canon EOS R5 comparison: before on the left, compressed output on the right. This sample went from 30.4 MB to 1.6 MB.

Engineering decisions#

  • Measure against a reference. The Rust encoder matches Adobe's reference byte-for-byte on the measured mosaic outputs. That is a specific encoding check, not a claim that lossy compression equals the original RAW.
  • Fall back per file. Nikon NEF files the engine cannot decode automatically use Adobe DNG Converter. Without Adobe installed, the app reports the failure plainly.
  • Leave originals alone. Squeeze never modifies them. Moving originals to Trash is a separate action, only on request.
The trade-off: shrinking is lossy and irreversible. Keep originals for workflows that need them, including denoising before conversion. Do not assume every RAW editor supports the output.
Squeeze completion screen with separate Show in Finder and Move Originals to Trash actions
Finishing a conversion does not remove the originals. Trash is an explicit choice.

Why this matters to a client or employer#

This is end-to-end product work: a real storage problem, low-level image encoding, a native app and App Store packaging. Squeeze passed Apple review and is live on the Mac App Store.

For a client, it shows I can build beyond the demo and handle the awkward files and safety decisions. For an engineering team, it shows I can connect systems code to a usable product and explain what the measurements do — and do not — prove.