#!/bin/sh

echo "+-----------------------------------------------------------------+"
echo "| Filter the image                                                |"
echo "+-----------------------------------------------------------------+"

# Default parameters:
DEC=FALSE		# don't use decimation of QMF filter
SYMM=FALSE		# don't use symmetric extension
ALL_MCF_PARS=''		# no extra parameters to mcf
DEC_FACT=1		# no decimation
NONLIN="tanh"		# nonlinearity
SCALE=TRUE		# do scaling to full dynamic range

# Temporary files:
PAD_IMG_FILE=`tempnam`
TMP_FEATURE_FILE=`tempnam`

clean ()
{
  rm -f $PAD_IMG_FILE
}


print_usage ()
{
  # Print usage
  echo "filter"
  echo "\tOptions:"
  echo "\t  -U		-- print usage"
  echo "\t  -sn ..	-- filter structure number"
  echo "\t  -f @@@  	-- filter name"
  echo "\t 		   Farro: Farrokhnia's (90) method"
  echo "\t 		   Gabor: Gabor filter with structure given by -sn "
  echo "\t 		   f..@:  FIR QMF PR filters"
  echo "\t 		   i..: IIR QMF PR filters"
  echo "\t 		   w..: Wavelet QMF PR filters"
  echo "\t  -dec @@   	-- decimate the filter output? (TRUE or FALSE)"
  echo "\t  -scale @@ 	-- scale to full dynamic range? (TRUE or FALSE)"
  echo "\t            	   No scaling only implemented with decimated QMF"
  echo "\t  -nonlin @@	-- nonlinearity (tanh/abs/sqr, default is tanh)"
  echo "\t            	   abs/sqr only implemented with decimated QMF"
  echo "\t  -symm @@   	-- symmetrically extend prior to filtering?"
  echo "\t  -if @@  	-- input image file"
  echo "\t  -ff @@  	-- output feature file"
  echo "\t  -sf @@  	-- output statistics file"
  exit 1
}



filter ()
{
  if [ ${FILTER} = Gabor ] ; then
    gabor_struct 
  elif [ ${FILTER} = Farro ] ; then
    farro 
  elif [ ${DEC} = TRUE ] ; then
    qmf_bank_dec
  else
    qmf_bank
  fi
}



power2_pad ()
{
  # Pads an image with the symmetric extension to have dimensions of 
  # power of two
  TMP_FILE1=`tempnam`
  TMP_FILE2=`tempnam`
  ROWS=`hsize -rows $IMAGE_FILE`
  COLS=`hsize -cols $IMAGE_FILE`
  if [ $SYMM = TRUE ]; then
    # Use at least 8 pixels symmetric extension in each direction
    NEW_ROWS=`calc "power(2,ceil(ln(${ROWS}+16,0.00001)/ln(2,0.00001)))"`
    NEW_COLS=`calc "power(2,ceil(ln(${COLS}+16,0.00001)/ln(2,0.00001)))"`
  else
    # Do not use more symmetric extension than necessary
    NEW_ROWS=`calc "power(2,ceil(ln(${ROWS},0.00001)/ln(2,0.00001)))"`
    NEW_COLS=`calc "power(2,ceil(ln(${COLS},0.00001)/ln(2,0.00001)))"`
  fi
  pad_x1=`calc "round(( $NEW_ROWS - $ROWS )/2)"`
  pad_y1=`calc "round(( $NEW_COLS - $COLS )/2)"`
  pad_x2=`calc " $ROWS + $pad_x1 "`
  pad_y2=`calc " $COLS + $pad_y1 "`
  b_marg=`calc " $NEW_ROWS - $ROWS - $pad_x1 "`
  r_marg=`calc " $NEW_COLS - $COLS - $pad_y1 "`
  t_marg=`calc " $NEW_ROWS - $pad_x2 "`
  l_marg=`calc " $NEW_COLS - $pad_y2 "`
  ext_x2=`calc " $NEW_ROWS - 2 * $b_marg "`
  ext_y2=`calc " $NEW_COLS - 2 * $r_marg "`

  if [ $ROWS -eq $NEW_ROWS -a $COLS -eq $NEW_COLS -a $SYMM = FALSE ] ; then
    cp $IMAGE_FILE $PAD_IMG_FILE
  else
    echo "Power of two padding -- symmetric extension"
    genframe -s $NEW_ROWS $NEW_COLS | \
	padimage   -s $pad_x1 $pad_y1 $IMAGE_FILE - > $TMP_FILE1
    # Order (compass directions): S, N, E, W
    extract -p $ext_x2 0 -s $b_marg $NEW_COLS $TMP_FILE1 | \
	rotate180 | reflect | \
	padimage -s $pad_x2 0 - $TMP_FILE1 > $TMP_FILE2
    extract -p $t_marg 0 -s $t_marg $NEW_COLS $TMP_FILE2 | \
	rotate180 | reflect | \
	padimage -s 0 0 - $TMP_FILE2 > $TMP_FILE1
    extract -p 0 $ext_y2 -s $NEW_ROWS $r_marg $TMP_FILE1 | \
	reflect | \
	padimage -s 0 $pad_y2 - $TMP_FILE1 > $TMP_FILE2
    extract -p 0 $l_marg -s $NEW_ROWS $l_marg $TMP_FILE2 | \
	reflect | \
	padimage -s 0 0 - $TMP_FILE2 > $TMP_FILE1
    mv $TMP_FILE1 $PAD_IMG_FILE
    rm -f $TMP_FILE1 $TMP_FILE2
  fi
} 



remove_pad ()
{
  if [ $ROWS -ne $NEW_ROWS -o $COLS -ne $NEW_COLS ] ; then
    echo "Remove padding"
    if [ $DEC = TRUE ] ; then
      dec2seq -fs -sn $STRUCT $FEATURE_FILE | \
	extract -p $pad_x1 $pad_y1 -s $ROWS $COLS  | \
	htof | seq2dec -sn $STRUCT > $TMP_FEATURE_FILE
    else
      extract -p $pad_x1 $pad_x2 -s $ROWS $COLS $FEATURE_FILE > $TMP_FEATURE_FILE
    fi
    mv $TMP_FEATURE_FILE $FEATURE_FILE
  fi
}



farro ()
{
  mcf ${MCF_PAR} < $PAD_IMG_FILE > $FEATURE_FILE
}


gabor_struct ()
{
  if [ ${DEC} = TRUE ] ; then
    echo Decimated Gabor filter is currently not implemented
    exit 1
  else
    mcf -sn ${STRUCT} ${MCF_PAR} < $PAD_IMG_FILE > $FEATURE_FILE
  fi
}


qmf_bank ()
{
  qmf -analysis -f $FILTER -sn $STRUCT $PAD_IMG_FILE | \
      tanh | blurr -sn ${STRUCT} > $FEATURE_FILE
}



qmf_bank_dec ()
{
  DEC_FACT=`mindec -sn ${STRUCT}`
  if [ ${SCALE} = TRUE ] ; then
    SCALE_CMD="dscale -sn $STRUCT "
  else
    SCALE_CMD="cat"
  fi
  if [ $NONLIN = tanh ] ; then
    NONLIN_CMD="tanh -sn ${STRUCT}"
  elif [ $NONLIN = abs ] ; then
    NONLIN_CMD="abspix"
  elif [ $NONLIN = sqr ] ; then
    NONLIN_CMD="scale -q 1"
  fi
  qmf -d -analysis -f "${FILTER}" -sn ${STRUCT} $PAD_IMG_FILE | \
   $NONLIN_CMD | blurr -d -sn ${STRUCT} | \
   $SCALE_CMD > $FEATURE_FILE
}



summary ()
{
  echo "	Decimation			${DEC}"       >  ${STAT_FILE}
  echo "	Filter                          ${FILTER}"    >> ${STAT_FILE}
  echo "	Filter structure                ${STRUCT}"    >> ${STAT_FILE}
}


# M A I N   P R O G R A M


until [ "$#" -eq "0"  ]; do
  case "${1}" in
    -U		) shift; print_usage ;;
    -tcs	) shift; TCS="${1}"; shift;;
    -sn		) shift; STRUCT="${1}"; shift;;
    -f		) shift; FILTER="${1}"; shift;;
    -symm	) shift; if [ "${1}" = "TRUE" -o "${1}" = "FALSE" ] ; then
			   SYMM=${1}; shift ;
			 else
			   SYMM=TRUE
			 fi;;
    -dec	) shift; if [ "${1}" = "TRUE" -o "${1}" = "FALSE" ] ; then
			   DEC=${1}; shift ;
			 else
			   DEC=TRUE
			 fi;;
    -scale	) shift; if [ "${1}" = "TRUE" -o "${1}" = "FALSE" ] ; then
			   SCALE=${1}; shift ;
			 else
			   SCALE=TRUE
			 fi;;
    -nonlin	) shift; NONLIN=${1}; shift;;
    -if		) shift; IMAGE_FILE=${1}; shift;;
    -ff		) shift; FEATURE_FILE=${1}; shift;;
    -sf		) shift; STAT_FILE=${1}; shift;;
    *		) shift; print_usage ;;
  esac
done

power2_pad
filter
remove_pad
summary
clean
