/*---------------------------------------------------------------------------*/
// Baseline Wavelet Transform Coder Construction Kit
//
// Geoff Davis
// gdavis@cs.dartmouth.edu
// http://www.cs.dartmouth.edu/~gdavis
//
// Copyright 1996 Geoff Davis 9/11/96
//
// Permission is granted to use this software for research purposes as
// long as this notice stays attached to this software.
//
/*---------------------------------------------------------------------------*/
/**
 *
 * Originally this was wavelet.hh from Geoff Davis' Wavelet construction kit.
 * This version has been adapted to my classes resulting in small changes
 * to names and formatting etc. I also removed the class Wavelet which looks
 * different in my code!
 *
 * $Date$
 * $Revision$
 *
 */
#ifndef FILTER_HH__
#define FILTER_HH__

/** 
 * @addtogroup Wave 
 * @{ */

#include "WImage/miscdefs.h"

#ifndef NULL
#define NULL 0
#endif

/*---------------------------------------------------------------------------*/

class FilterSet;

class Filter 
{
  friend class FilterSet;

public:
  Filter (void) { m_coeffs = NULL; m_size = 0; m_firstIndex = 0; }
  Filter (int m_size, int firstIndex = 0, coeff *coeffs = NULL)
  { init (m_size, firstIndex, coeffs); }
  Filter (const Filter &filter) { m_coeffs = NULL; copy (filter); }
  ~Filter (void);
  
  void init (int m_size, int filterFirst, coeff *coeffs);
  void dump (void);
  inline coeff at (int index) { return m_coeffs[index]; }
  inline int fsize (void) { return m_size; }
  inline int first (void) { return m_firstIndex; }

protected:
  int m_size;
  int m_firstIndex;
  void copy (const Filter &filter);
  coeff *m_coeffs;
  inline void tof (int index, coeff value) 
  { m_coeffs[index-m_firstIndex] = value; }
  inline coeff atf (int index) { return m_coeffs[index-m_firstIndex]; }

};

/*---------------------------------------------------------------------------*/

/**
 *
 * Originally this was wavelet.hh from Geoff Davis' Wavelet construction kit.
 * This version has been adapted to my classes resulting in small changes
 * to names and formatting etc. I also removed the class Wavelet which looks
 * different in my code!
 */
class FilterSet 
{
public:
  FilterSet (void) { m_symmetric = 0; m_analysisLow = m_analysisHigh =
		m_synthesisLow = m_synthesisHigh = NULL; }
  FilterSet (bool symmetric, 
	     coeff *anLow, int anLowSize, int anLowFirst,  
	     coeff *synLow = NULL, int synLowSize = 0, int
	     synLowFirst = 0);
  FilterSet (const FilterSet &filterset);
  ~FilterSet (void);

  inline Filter &alow (void) { return *m_analysisLow; }
  inline Filter &ahigh (void) { return *m_analysisHigh; }
  inline Filter &slow (void) { return *m_synthesisLow; }
  inline Filter &shigh (void) { return *m_synthesisHigh; }
  inline bool issym (void) { return m_symmetric; }

  void dump (void);
  void init (bool symmetric, 
	     coeff *anLow, int anLowSize, int anLowFirst, 
	     coeff *synLow, int synLowSize, int synLowFirst);

  /** Return a FilterSet from a String. 
   * @exception invalid_argument
   * the filter in the string was not found
   * @return 
   * a reference to the filter set
   */
  static FilterSet &filterFromString (char *str);
  static const char *filterToString (FilterSet &filter);
  
protected:
  bool m_symmetric;
  Filter *m_analysisLow;
  Filter *m_analysisHigh;
  Filter *m_synthesisLow;
  Filter *m_synthesisHigh;
  void copy (const FilterSet& filterset);
};

/*---------------------------------------------------------------------------*/

extern FilterSet Haar, Daub4, Daub6, Daub8, Antonini, 
  Brislawn, Villa1, Villa2, Villa3, Villa4, Villa5, Villa6, 
  Odegard;
/* Adelson, Brislawn2, don't produce sufficient precision */
/*---------------------------------------------------------------------------*/
/** @} */
#endif
/*---------------------------------------------------------------------------*/


