2021-05-17
My camera writes photos in the High Efficiency Image File Format (HEIF) but darktable doesnโt yet support reading them. As a stopgap Iโve scripted a wrapper around darktable that converts them to a supported format.
To use it I right-click on a HEIF file and choose Open withโฆ โ darktable (HEIF). A progress bar displays while files are converted, then darktable opens.
To discourage long-term reliance upon interim files and reduce clutter in the photo store, the outputs are kept in /tmp
and symlinked into the photo store. Temporary files needed during the conversion are written only to /dev/shm
to avoid unnecessary writes to persistent storage.
#!/usr/bin/env bash
set -Eeuxo pipefail
# Parameters
heifs=( "$@" )
# Start progress bar
steps_per_heif='3'
total_steps="$(( steps_per_heif * "${#heifs[@]}" ))"
task() { echo "# $1" >&3; }
progress() { echo "$(( $1 * 100 / total_steps ))" >&3; }
exec 3> >(zenity --width 600 --progress --percentage=0 --auto-close)
# For each HEIF file
links=()
for i in "${!heifs[@]}"; do heif="${heifs[$i]}"
task "Extracting ${heif##*/}"
progress "$(( steps_per_heif * i ))"
# Ensure TIFF
tiff="/tmp/heif-darktable$heif.tif"
if [[ ! -f "$tiff" ]]; then
# Extract image
y4m="$(mktemp --tmpdir=/dev/shm --suffix=.y4m)"; trap 'rm -f "$y4m"' EXIT
heif-convert "$heif" "$y4m"
# Encode as TIFF
progress "$(( steps_per_heif * i + 1 ))"
working="$(mktemp -u --tmpdir=/dev/shm --suffix=.tif)"; trap 'rm -f "$working"' EXIT
ffmpeg -i "$y4m" -c:v 'ppm' -f 'image2pipe' - | convert ppm:- "$working" && rm "$y4m"
# Transfer metadata
progress "$(( steps_per_heif * i + 2 ))"
exiftool -overwrite_original -TagsFromFile "$heif" -Orientation= "$working"
mv "$working" "$tiff"
fi
# Ensure symlink
link="$heif.tif"
[[ -L "$link" ]] || ln -s "$tiff" "$link"
# Collect links
links+=("$link")
done
# Stop progress bar
exec 3>&-
# Become darktable
exec darktable "${links[@]}"