#!/bin/sh set -euf dirminsize () { cleanup() { trap 'exit' INT HUP QUIT TERM EXIT rm -f "$tmpjxl7" "$tmpjxl8" "$tmpjxl9" "$tmpwebp" kill 0 } tmpwebp=$(mktemp -u -t webp2jxl_XXXX.webp) tmpjxl7=$(mktemp -u -t webp2jxl_XXXX.jxl) tmpjxl8=$(mktemp -u -t webp2jxl_XXXX.jxl) tmpjxl9=$(mktemp -u -t webp2jxl_XXXX.jxl) trap 'cleanup' INT HUP QUIT TERM EXIT ext="webp,png,jxl" depth="-maxdepth 1" while getopts ":e:r" OPT; do case "$OPT" in e) ext="$OPTARG" ;; r) depth="" ;; *) exit 1 ;; esac done shift $((OPTIND - 1)) exts=$(awk -F ',' -v OFS=' -o ' '{ for(i=1; i<=NF; i++) $i="-iname *." $i; print}' <<-EOF $ext EOF ) while IFS= read -r f; do [ -z "$f" ] && continue echo "$f" vips webpsave "$f" "$tmpwebp" --min-size --lossless & vips jxlsave "$f" "$tmpjxl7" --lossless --effort 7 & vips jxlsave "$f" "$tmpjxl8" --lossless --effort 8 & vips jxlsave "$f" "$tmpjxl9" --lossless --effort 9 & wait read -r _ outfile <<-EOF $(wc -c "$f" "$tmpwebp" "$tmpjxl7" "$tmpjxl8" "$tmpjxl9" | sort -n) EOF mv "$outfile" "${f%.*}.${outfile##*.}" || continue [ "${outfile##*.}" != "${f##*.}" ] && rm "$f" # remove if there are 2 done <<-EOF $(set -f; find "${1:-.}" -type f $depth $exts) EOF } jxld2q() { for n; do case "$n" in *.*) i=d; d="$n" ;; *) i=q; q="$n" ;; esac [ "$i" = q ] && d="$(printf '0.1 + (100 - %s) * 0.09\n' "$q" | bc)" [ "$i" = d ] && q="$(printf '100 - ((%s - 0.1) / 0.09)\n' "$d" | bc)" echo "distance = $d | quality = $q" done } cmd=$1; shift case "$cmd" in dirminsize) dirminsize "$@" ;; jxld2q) jxld2q "$@" ;; help|-h) cat >&2 <<-EOF available commands: * dirminsize - tries to losslessly squeeze out as much size as possible from every file in the directory by converting to webp/jxl with various efforts options: -r (recursive) -e * jxld2q $@ - convert to/from jxl distance/quality for each arg EOF ;; *) errecho "wrong command. use help or -h for help" ;; esac