#!/bin/bash
# For lazy people like Tilmann Bitterberg (bitterberg@gmx.de)
#
# Sun Jun  9 10:12:37 UTC 2002
#
# I want to transcode a 640x480 video to 384x288 but don't use the slow
# (but high quality) -Z zoom option and I am too lazy to figure out the
# correct -B values myself so I do
# $ ./zoomto.sh 640x480 384x288
#  -B 6,8
#
# The script also calculates fitting -j options if the input size is not a
# multiple of 32
# $ ./zoomto 643x480 384x288
# -j 0,2,0,1 -B 6,8
# respectivly for -Y if output size is not a multiple of 32
#
# If your input size is a multiple of desired output the script now outputs
# a -r option since its faster than -B
# $ ./zoomto.sh 768x512 256x256
#  -r 2,3
#
# The -j and -Y options generated always align to the nearest n*32
# boundary. This means they can be negative (adding black bars). A full
# featured example:
# $ ./scripts/zoomto.sh 703x512 642x475
#  -j 0,-1,0,0 -B 1,2 -Y -3,1,-2,1


usage() {
  echo "Calculates -B or -X values for transcode";
  echo "The first wxh is input size. 2nd is output";
  echo "third is multiple factor 32 [*], 16 or 8";
  echo "Usage: $0 wxh wxh ";
  exit 1
}

if [ $# -lt 2 ]; then
  usage 1>&2
fi


calcall () {

insize=$1
outsize=$2
inw=`echo $insize | sed 's,x.*,,'`
inh=`echo $insize | sed 's,.*x,,'`
outw=`echo $outsize | sed 's,x.*,,'`
outh=`echo $outsize | sed 's,.*x,,'`
originw=$inw
originh=$inh
origoutw=$outw
origouth=$outh
temparg=0

if test -z $3; then
  multiple=32
else
  multiple=$3
fi
multiple2=`expr $multiple / 2`

# do we need to scale up or down?
if test $inw -lt $outw; then
  commandBw="-X"
else
  commandBw="-B"
fi

if test $inh -lt $outh; then
  commandBh="-X"
else
  commandBh="-B"
fi

buildj() {
  op="+"; invop="-"
  lef=`expr $1 % $multiple`

  if [ $lef -ge $multiple2 ]; then
    lef=`expr $lef - $multiple`
    op="-"; invop="+"
  fi

  hlef=`expr $lef % 2`
  if [ $hlef -eq 0 ]; then 
    lef=`expr $lef / 2`
    rig=$lef
  else 
    lef=`expr $lef / 2 $op 1`
    rig=`expr $lef $invop 1`
  fi

  op="+"; invop="-"
  top=`expr $2 % $multiple`

  if [ $top -ge $multiple2 ]; then
    top=`expr $top - $multiple`
    op="-"; invop="+"
  fi

  htop=`expr $top % 2`
  if [ $htop -eq 0 ]; then 
    top=`expr $top / 2`
    bot=$top
  else 
    top=`expr $top / 2 $op 1`
    bot=`expr $top $invop 1`
  fi
  
  if [ x"$3" = x"Y" ]; then
    top=`expr 0 - $top`
    bot=`expr 0 - $bot`
    lef=`expr 0 - $lef`
    rig=`expr 0 - $rig`
    tempw=`expr $1 + $lef + $rig`
    temph=`expr $2 + $top + $bot`
  else
    tempw=`expr $1 - $lef - $rig`
    temph=`expr $2 - $top - $bot`
  fi

  temparg="${top},${lef},${bot},${rig}"
  unset top bot lef rig
}

calcB () {
  a=`expr $1 / $multiple - $3 / $multiple`
  b=`expr $2 / $multiple - $4 / $multiple`
  if [ $a -lt 0 ]; then a=`expr 0 - $a`; fi
  if [ $b -lt 0 ]; then b=`expr 0 - $b`; fi
  # Syntax: h,w
  temparg="${b},${a}"
  unset a b
}

unset argj commandj
buildj $inw $inh j
if [ x"$temparg" != x"0,0,0,0" ]; then
  argj=$temparg
  inw=$tempw
  inh=$temph
  commandj="-j"
fi

unset argY commandY
buildj $outw $outh Y
if [ x"$temparg" != x"0,0,0,0" ]; then
  argY=$temparg
  outw=$tempw
  outh=$temph
  commandY="-Y"
fi

unset argr
if [ `expr $originw % $origoutw` -eq 0 ] && [ `expr $originh % $origouth` -eq 0 ]; then
  argr="`expr $originh / $origouth`,`expr $originw / $origoutw`"
fi

calcB $inw $inh $outw $outh
argB=$temparg

if [ x"$commandBw" = x"$commandBh" ]; then
  commandB="${commandBw} ${argB},${multiple}";
else
  if [ x"$commandBh" = x"-X" ]; then
    commandB="-X `echo $argB | sed s/,.*//`,0,${multiple}"
    commandB="${commandB} ${commandBw} 0,`echo $argB | sed s/.*,//`,${multiple}"
  fi
  if [ x"$commandBh" = x"-B" ]; then
    commandB="-B `echo $argB | sed s/,.*//`,0,${multiple}"
    commandB="${commandB} ${commandBw} 0,`echo $argB | sed s/.*,//`,${multiple}"
  fi
fi

#filter out noops
commandB="`echo $commandB|sed 's/-X 0,0//;s/-B 0,0//;s/-r 1,1//'`"

if [ ! -z $argr ]; then
  commandB="-r ${argr}"
  echo $commandB
  #exit 0
fi

echo "Multiples of $multiple: $commandj $argj $commandB $commandY $argY"
}

calcall $1 $2 32
calcall $1 $2 16
calcall $1 $2 8

exit 0
