#! /bin/bash
# vim: set filetype=sh:

# recomp-jpg: Recompresses JPEG files to a specified quality level, only
# keeping the new version if it is actually *smaller*.

# Copyright (C) 2004-2012 by Brian Lindholm.  This file is part of the
# littleutils utility set.
#
# The recomp-jpg utility is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option) any later
# version.
#
# The recomp-jpg utility is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# the littleutils.  If not, see <https://www.gnu.org/licenses/>.

# get a valid temporary directory and set up traps
TMPWILD=`tempname -w recomp-jpg_$$` || exit 99
trap 'rm -f ${TMPWILD} ; exit 1' 1 2 3 13 15
trap 'rm -f ${TMPWILD} ; exit 0' 0

# get command-line options
ARITHMETIC=n
MARKERS=none
TARGQUAL=85
VERBOSE=y
while getopts ahqt: opts
do
  case $opts in
    a) ARITHMETIC=y ;;
    h) echo 'recomp-jpg 1.2.3'
       echo 'usage: recomp-jpg [-a(rithmetic)] [-h(elp)] [-q(uiet)]'
       echo '         [-t target_quality] JPEG_filename ...'
       exit 0 ;;
    q) VERBOSE=n ;;
    t) TARGQUAL=${OPTARG} ;;
    *) echo 'recomp-jpg 1.2.3'
       echo 'usage: recomp-jpg [-a(rithmetic)] [-h(elp)] [-q(uiet)]'
       echo '         [-t target_quality] JPEG_filename ...'
       exit 1 ;;
  esac
done
shift `expr ${OPTIND} - 1`

# run through files
while [ $# -gt 0 ]; do

  # make sure we can read and modify file
  if [ ! -f "$1" -o ! -r "$1" -o ! -w "$1" ]; then
    echo "recomp-jpg error: $1 is not a writeable non-directory file"
    shift; continue
  fi

  # determine current sampling scheme
  SAMPLING=`imagsize "$1" | perl -n -e '/samp=(\S+)\s/ ; print "$1"'`
  if [ "X$SAMPLING" = 'Xnone' ]; then
    echo "recomp-jpg error: $1 does not appear to be a JPEG file"
    shift; continue
  fi

  # recompress the file to a new JPEG file
  TMPJPG=`tempname -s .jpg recomp-jpg_$$` || exit 99
  djpeg -dct float -bmp "$1" | cjpeg -dct float -quality ${TARGQUAL} \
    -sample ${SAMPLING} > ${TMPJPG}
  OUT1="$?"
  if [ "$OUT1" -ne 0 -a "$OUT1" -ne 2 ]; then
    echo "recomp-jpg error: $1 is a bad jpg file: [cd]jpeg rc = ${OUT1}"
    rm -f ${TMPJPG}
    shift; continue
  fi

  # optimize and check that the new file is smaller by at least 5%
  if [ "$ARITHMETIC" = 'y' ]; then
    opt-jpg -a -q ${TMPJPG}
  else
    opt-jpg -q ${TMPJPG}
  fi
  S0=`filesize "$1"`
  S1=$((`filesize "$TMPJPG"`*20/19))
  if [ "$S1" -lt "$S0" ]; then
    cp ${TMPJPG} "$1"
    if [ "$VERBOSE" = 'y' ]; then
      echo "$1: ${S0} vs. ${S1}"
    fi
  else
    if [ "$VERBOSE" = 'y' ]; then
      echo "$1: unchanged"
    fi
  fi

  # clean up afterwards
  rm -f ${TMPJPG}
  shift

done
rm -f ${TMPWILD}
