#! /bin/bash
# Last edited on 2009-12-23 23:51:12 by stolfi

usage="$0 [ -show ] [ -crop DX DY NX NY ] [ -portrait | -logo | -landscape | -size NX NY | -aspect AX AY ] FILE..."

# Converts a bunch of original images 
# to "p-raw.ppm.gz" files of a specified aspect ratio, and puts them 
# in the same directory as the ".tiff" files.

# The pictures are automatically cropped and scaled to the
# specified size and shape.

# For correct scaling, the input images should be scanned 
# with the linear ("raw monitor") calibration.

# !!! TO DO: use ".png" as the intermediate format instead of ".ppm.gz".

# Set program paths:

tooldir="$0"; tooldir="${tooldir%/*}"

getdims="${STOLFIHOME}/bin/get-pnm-dimensions"
# pbmbin="${STOLFIHOME}/pkg/netpbm-1mar1994-1/PUB/${PLATFORM}/bin"
pbmbin="/usr/bin"

show=0

aspx=5
aspy=7
nx= 
ny= 

cropdx= 
cropdy= 
cropnx= 
cropny= 

# if [[ "/-foo" =~ '^/-' ]]; then echo 'WORKS' 1>&2; fi
# exit 0

while [[ ( $# -ge 1 ) && ( "/$1" =~ '^/-' ) ]]; do
  if [[ "/$1" == "/-show" ]]; then
    show=1;
    shift;
  elif [[ "/$1" == "/-portrait" ]]; then
    aspx=5; aspy=7;
    nx=280; ny=392;
    shift;
  elif [[ "/$1" == "/-logo" ]]; then
    aspx=1; aspy=1;
    nx=400; ny=400;
    shift;
  elif [[ "/$1" == "/-landscape" ]]; then
    aspx=7; aspy=5;
    nx=630; ny=450;
    shift;
  elif [[ ( "/$1" == "/-crop" ) && ( $# -ge 5 ) ]]; then
    cropdx="$2"; cropdy="$3";
    cropnx="$4"; cropny="$5";
    shift; shift; shift; shift; shift;
  elif [[ ( "/$1" == "/-size" ) && ( $# -ge 3 ) ]]; then
    nx="$2";    ny="$3";
    # Reduce ${nx}, ${ny} to relatively prime ratio:
    tx=${nx}; 
    ty=${ny};
    while [[ ${ty} -gt 0 ]]; do
      tr=$(( ${tx} - ( ( ${tx} / ${ty} ) * ${ty} ) ))
      tx=${ty}
      ty=${tr}
    done
    gcd=${tx}
    echo "gcd(${nx},${ny}) = ${gcd}" 1>&2
    aspx=$(( ${nx} / ${gcd} ))
    aspy=$(( ${ny} / ${gcd} ))
    echo "aspect ratio ${aspx}:${aspy}" 1>&2
    shift; shift; shift
  elif [[ ( "/$1" == "/-aspect" ) && ( $# -ge 3 ) ]]; then
    aspx="$2"; aspy="$3";
    shift; shift; shift
  else
    echo "usage: ${usage}" 1>&2
    exit 1
  fi
done

if [[ $# -lt 1 ]]; then
  echo "usage: ${usage}" 1>&2
  exit 1
fi

files=( "$@" )

echo "files = ( ${files[@]} )"

for forig in "${files[@]}"; do
  if [[ ! -s ${forig} ]]; then
    echo "${forig} not found"'\!' 1>&2; continue
  fi
  name=${forig##*/}
  fdir=${forig%/*}
  fraw=${fdir}/p-raw.ppm
  if [[ -s ${fraw}.gz ]]; then
    /bin/mv ${fraw}.gz ${fraw}.gz~
    echo "renamed ${fraw}.gz to ${fraw}.gz~" 1>&2
  fi
  if [[ ".${forig:e}" == ".ppm" ]]; then
    fppm="${forig}"
  else
    fppm="/tmp/$$.ppm"
    echo "converting ${forig} to ${fppm}..." 1>&2 
    convert ${forig} ${fppm}
  fi

  # echo "determining the cropping and scaling parameters..." 1>&2
  fxy=( `cat ${fppm} | ${getdims}` )
  if [[ ! -z "${cropnx}" ]]; then
    # Start with the user-specified cropping:
    skipx=${cropdx}
    skipy=${cropdy}
    bignx=${cropnx}
    bigny=${cropny}
    if [[ $(( ${skipx} + ${bignx} )) -gt ${fxy[0]} ]]; then
       echo "crop region too wide" 1>&2;  exit 1
    fi
    if [[ $(( ${skipy} + ${bigny} )) -gt ${fxy[1]} ]]; then
       echo "crop region too tall" 1>&2;  exit 1
    fi
  else
    # No user-specified cropping:
    skipx=0
    skipy=0
    bignx=${fxy[0]}
    bigny=${fxy[1]}
  fi

  # Adjust cropping to specified aspect ratio:
  rx=$(( ${bignx} * ${aspy} ))
  ry=$(( ${bigny} * ${aspx}  ))
  if [[ ${rx} -lt ${ry} ]]; then
    nrel=$(( ${bignx} / ${aspx} ))
  else 
    nrel=$(( ${bigny} / ${aspy} ))
  fi
  cutx=$(( ${nrel} * ${aspx} ))
  cuty=$(( ${nrel} * ${aspy} ))
  skipx=$((  ( ( ${bignx} - ${cutx} ) / 2 ) + ${skipx} ))
  skipy=$((  ( ( ${bigny} - ${cuty} ) / 2 ) + ${skipy} ))

  echo "converting ${fppm} to ${fraw}.gz..." 1>&2
  if [[ ! -z "${nx}" ]]; then
    nxy="${nx}x${ny}"
    echo "cropping from ${fxy[0]}x${fxy[1]} to ${cutx}x${cuty} and scaling to ${nxy}" 1>&2
    scalecmd=( ${pbmbin}/pnmscale -xsize ${nx} )
  else
    nxy= 
    echo "cropping from ${fxy[0]}x${fxy[1]} to ${cutx}x${cuty}" 1>&2
    scalecmd=( /bin/cat )
  fi

  cat ${fppm} \
  | ${pbmbin}/pnmcut ${skipx} ${skipy} ${cutx} ${cuty} \
  | ${scalecmd[@]} \
  | gzip > ${fraw}.gz
  
  if [[ ${show} -gt 0 ]]; then
    display -title "${fdir##*/}" ${fraw}.gz ${forig}
  fi

  if [[ -r /tmp/$$.ppm ]]; then
    /bin/rm -f /tmp/$$.ppm
  fi
done