#!/bin/sh
#
# Convert a time series of Canon Raw images to JPEG, maintaining a consistent
# exposure value between frames. Requires both exiv2 and UFRaw to be installed,
# and in your $PATH.
#
# Instructions:
# 1. Throw your files in the working directory, named *.CR2.
#    These images should be taken in sequence, and equally spaced in time.
# 2. Adjust INITIAL= and FINAL= to represent exposure correction required
#    for the first and final frames. These numbers represent exposure
#    compensation - a value of 1 will make the frame lighter by one stop,
#    and a value of -1 will make the frame darker by one stop.
# 3. This script is written for a 4-core machine; please adjust the delay
#    at the bottom of the loop if your machine is too slow to keep up with
#    the image conversion, or waits between sets of images. Yes, it's a hack.
# 
FILES="*.CR2"

NUM=$(ls -- ${FILES} | wc -l)
INITIAL=0
FINAL=0.5
UFRAW=/usr/bin/ufraw-batch
EXIV2=/usr/bin/exiv2
PARALLELISM=4
DELAY=20

if [ ! -x "$UFRAW" ]; then
  echo UFRaw is not installed at $UFRAW. Please install UFRaw and try again. >&2
  exit 1
fi

if [ ! -x "$EXIV2" ]; then
  echo exiv2 is not installed at $EXIV2. Please install exiv2 and try again. >&2
  exit 1
fi


echo Processing ${NUM} files...

get_exposure () {
    "${EXIV2}" -p v "$1" 2>/dev/null | awk '/ExposureTime/ { split($6, expo, "/"); exposure = expo[1] / expo[2] }; /FNumber/ { split($6, f, "/"); fno = f[1] / f[2]; }; END { ev = log(fno * fno / exposure) / log(2); print ev }'
}

for f in $FILES; do
    if [ \! -f "${f}" ]; then
      echo $f is not a file. >&2
      exit 1
    fi
done

INIT_EV=$(get_exposure "$(ls -- $FILES | sort | head -1)")
LAST_EV=$(get_exposure "$(ls -- $FILES | sort | tail -1)")
DELTA_EV=$( echo scale=10\; \( $LAST_EV - $FINAL \) - \( $INIT_EV - $INITIAL \) | bc )
STEP_EV=$( echo scale=10\; $DELTA_EV / $NUM | bc )
N=0

echo Spreading ${DELTA_EV} across ${NUM} images, $STEP_EV per image.

for i in ${FILES}; do
    PHOTO_EV=$(get_exposure "${i}")
    ADJUST_EV=$( echo scale=10\; $PHOTO_EV - \( $INIT_EV + $STEP_EV '*' $N \) | bc )
    TARGET_EV=$( echo scale=10\; $PHOTO_EV - $ADJUST_EV | bc )

    echo "${N}\t${i}\t${PHOTO_EV}\tAdj by ${ADJUST_EV}\tto ${TARGET_EV}";
    "${UFRAW}" --compression=100 --temperature=5800 --green=0.931 --clip=film --shrink=2 --exposure="${ADJUST_EV}" --out-type=jpg --out-depth=8 --out-path=out/ "${i}" &
    N=$((N+1))

    if [ $((N % PARALLELISM)) == 0 ]; then sleep ${DELAY}; fi
done

