// Emacs: -*- C++ -*-

//
//	Copyright 1993, Center for Computer Vision and Visualization,
//	University of Florida.  All rights reserved.
//


//
// $Log: AuxDDTempl.h,v $
// Revision 1.4  1994/07/25  17:26:39  thoth
// Name sanitization
//
// Revision 1.3  1994/04/15  13:15:11  thoth
// Flesh out the rest of the generic convolutions.
//
// Revision 1.2  1994/03/30  13:49:45  thoth
// generic convolutions will now compile.
//
// Revision 1.1  1994/03/22  16:08:28  thoth
// Initial revision
//

#ifndef AuxDDTempl_h_
#define AuxDDTempl_h_

#include "DDTempl.h"

//
// generic backward image-template convolution
//

#if 1
// without this declaration, CFront cores
template <class R, class S, class T>
IA_Image<IA_Point<int>,R>
backw_generic_inv_core(IA_Point<int> src_infimum,
		    IA_Point<int> src_width,
		    const T *src_data, // length is prod(src_width)
		    const IA_CoreImage<IA_Point<int>,S> &templ,
		    IA_Set<IA_Point<int> > dest_ps,
		    R (*circle)(T,S),
		    R (*gamma)(R,R),
		    R gamma_zero,
		    const S*);

// let's see if this prototype fixes things...
template <class R, class S, class T>
IA_Image<IA_Point<int>, R>
backw_generic_inv(const IA_CoreImage<IA_Point<int>, T> &img,
		  const IA_CoreImage<IA_Point<int>, S> &invtempl,
		  const IA_Set<IA_Point<int> > &dest_ps,
		  R (*circle)(T,S),
		  R (*gamma)(R,R),
		  R gamma_zero,
		  T ring_zero,
		  const S*);
#endif

template <class R, class S, class T>
IA_Image<IA_Point<int>, R> generic_product
(const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_DDTemplate< IA_Image<IA_Point<int>, S> > &tmpl,
 const IA_Set<IA_Point<int> > &dst,
 R (*circle)(T,S),
 R (*gamma)(R,R),
 R gamma_zero,
 T ring_zero,
 const S*);

template <class T>
inline IA_Image<IA_Point<int>, T> generic_product
(const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_DDTemplate< IA_Image<IA_Point<int>, T> > &tmpl,
 const IA_Set<IA_Point<int> > &dst,
 T (*circle)(T,T),
 T (*gamma)(T,T),
 T gamma_zero,
 T ring_zero) {
    return generic_product(img, tmpl, dst,
			   circle, gamma, gamma_zero, ring_zero, (T*)0);
}

//
//
//

template <class R, class S, class T>
IA_Image<IA_Point<int>,R>
forw_generic_inv_core(IA_Point<int> src_infimum,
		    IA_Point<int> src_width,
		    const T *src_data, // length is prod(src_width)
		    const IA_CoreImage<IA_Point<int>,S> &templ,
		    IA_Set<IA_Point<int> > dest_ps,
		    R (*circle)(T,S),
		    R (*gamma)(R,R),
		    R gamma_zero,
		    const S*)

template <class R, class S, class T>
IA_Image<IA_Point<int>, R>
forw_generic_inv(const IA_CoreImage<IA_Point<int>, T> &img,
		  const IA_CoreImage<IA_Point<int>, S> &invtempl,
		  const IA_Set<IA_Point<int> > &dest_ps,
		  R (*circle)(T,S),
		  R (*gamma)(R,R),
		  R gamma_zero,
		  T ring_zero,
		  const S*)

template <class R, class S, class T>
IA_Image<IA_Point<int>, R> generic_product
(const IA_DDTemplate< IA_Image<IA_Point<int>, S> > &tmpl,
 const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_Set<IA_Point<int> > &dst,
 R (*circle)(T,S),
 R (*gamma)(R,R),
 R gamma_zero,
 T ring_zero,
 const S*);

template <class T>
inline IA_Image<IA_Point<int>, T> generic_product
(const IA_DDTemplate< IA_Image<IA_Point<int>, T> > &tmpl,
 const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_Set<IA_Point<int> > &dst,
 T (*circle)(T,T),
 T (*gamma)(T,T),
 T gamma_zero,
 T ring_zero) {
    return generic_product(tmpl, img, dst,
			   circle, gamma, gamma_zero, ring_zero, (T*)0);
}


//
// generic backward image-template convolution
//


template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>,R>
backw_Generic_inv_core(IA_Point<int> src_infimum,
		       IA_Point<int> src_width,
		       const T *src_data,
		       const IA_CoreImage<IA_Point<int>,S> &templ,
		       IA_Set<IA_Point<int> > dest_ps,
		       R (*circle)(T,S),
		       Q (*Gamma)(R*,unsigned),
		       const Q*,
		       const R*,
		       const S*);

// let's see if this prototype fixes things...
template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>, R>
backw_Generic_inv(const IA_CoreImage<IA_Point<int>, T> &img,
		  const IA_CoreImage<IA_Point<int>, S> &invtempl,
		  const IA_Set<IA_Point<int> > &dest_ps,
		  R (*circle)(T,S),
		  Q (*Gamma)(R*,unsigned),
		  T ring_zero,
		  const Q*,
		  const R*,
		  const S*);

template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>, Q> generic_product
(const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_DDTemplate< IA_Image<IA_Point<int>, S> > &tmpl,
 const IA_Set<IA_Point<int> > &dst,
 R (*circle)(T,S),
 Q (*Gamma)(R*, unsigned count),
 T ring_zero,
 const Q*,
 const R*,
 const S* );

template <class T>
inline IA_Image<IA_Point<int>, T> generic_product
(const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_DDTemplate< IA_Image<IA_Point<int>, T> > &tmpl,
 const IA_Set<IA_Point<int> > &dst,
 T (*circle)(T,T),
 T (*Gamma)(T*,unsigned),
 T ring_zero) {
    return generic_product(img, tmpl, dst,
			   circle, Gamma, ring_zero, (T*)0, (T*)0, (T*)0);
}

//
// generic backward image-template convolution
//


template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>,R>
backw_Generic_inv_core3(IA_Point<int> src_infimum,
		       IA_Point<int> src_width,
		       const T *src_data,
		       IA_Set<IA_Point<int> > src_ps,
		       const IA_CoreImage<IA_Point<int>,S> &templ,
		       IA_Set<IA_Point<int> > dest_ps,
		       R (*circle)(T,S),
		       Q (*Gamma)(R*,unsigned),
		       const Q*,
		       const R*,
		       const S*);

// let's see if this prototype fixes things...
template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>, R>
backw_Generic_inv3(const IA_CoreImage<IA_Point<int>, T> &img,
		  const IA_CoreImage<IA_Point<int>, S> &invtempl,
		  const IA_Set<IA_Point<int> > &dest_ps,
		  R (*circle)(T,S),
		  Q (*Gamma)(R*,unsigned),
		  const Q*,
		  const R*,
		  const S*);

template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>, Q> generic_product
(const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_DDTemplate< IA_Image<IA_Point<int>, S> > &tmpl,
 const IA_Set<IA_Point<int> > &dst,
 R (*circle)(T,S),
 Q (*Gamma)(R*, unsigned count),
 const Q*,
 const R*,
 const S* );

template <class T>
inline IA_Image<IA_Point<int>, T> generic_product
(const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_DDTemplate< IA_Image<IA_Point<int>, T> > &tmpl,
 const IA_Set<IA_Point<int> > &dst,
 T (*circle)(T,T),
 T (*Gamma)(T*,unsigned)) {
    return generic_product(img, tmpl, dst,
			   circle, Gamma, (T*)0, (T*)0, (T*)0);
}

//
//
//
template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>,R>
forw_Generic_inv_core(IA_Point<int> src_infimum,
		       IA_Point<int> src_width,
		       const T *src_data, // length is prod(src_width)
		       const IA_CoreImage<IA_Point<int>,S> &templ,
		       IA_Set<IA_Point<int> > dest_ps,
		       R (*circle)(T,S),
		       Q (*Gamma)(R*,unsigned),
		       const Q*,
		       const R*,
		       const S*);

template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>, R>
forw_Generic_inv(const IA_CoreImage<IA_Point<int>, T> &img,
		  const IA_CoreImage<IA_Point<int>, S> &invtempl,
		  const IA_Set<IA_Point<int> > &dest_ps,
		  R (*circle)(T,S),
		  Q (*Gamma)(R*,unsigned),
		  T ring_zero,
		  const Q*,
		  const R*,
		  const S*);

template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>, Q> generic_product
(const IA_DDTemplate< IA_Image<IA_Point<int>, S> > &tmpl,
 const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_Set<IA_Point<int> > &dst,
 R (*circle)(T,S),
 Q (*Gamma)(R*, unsigned count),
 T ring_zero,
 const Q*,
 const R*,
 const S* );

template <class T>
inline IA_Image<IA_Point<int>, T> generic_product
(const IA_DDTemplate< IA_Image<IA_Point<int>, T> > &tmpl,
 const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_Set<IA_Point<int> > &dst,
 T (*circle)(T,T),
 T (*Gamma)(T*,unsigned),
 T ring_zero) {
    return generic_product(tmpl, img, dst,
			   circle, Gamma, ring_zero, (T*)0, (T*)0, (T*)0);
}

//
//
//
template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>, R>
forw_Generic_inv3(const IA_CoreImage<IA_Point<int>, T> &img,
		  const IA_CoreImage<IA_Point<int>, S> &invtempl,
		  const IA_Set<IA_Point<int> > &dest_ps,
		  R (*circle)(T,S),
		  Q (*Gamma)(R*,unsigned),
		  const Q*,
		  const R*,
		  const S*);

template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>,R>
forw_Generic_inv_core3(IA_Point<int> src_infimum,
		       IA_Point<int> src_width,
		       const T *src_data, // length is prod(src_width)
		       IA_Set<IA_Point<int> > src_ps,
		       const IA_CoreImage<IA_Point<int>,S> &templ,
		       IA_Set<IA_Point<int> > dest_ps,
		       R (*circle)(T,S),
		       Q (*Gamma)(R*,unsigned),
		       const Q*,
		       const R*,
		       const S*);

template <class Q, class R, class S, class T>
IA_Image<IA_Point<int>, Q> generic_product
(const IA_DDTemplate< IA_Image<IA_Point<int>, S> > &tmpl,
 const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_Set<IA_Point<int> > &dst,
 R (*circle)(T,S),
 Q (*Gamma)(R*, unsigned count),
 const Q*,
 const R*,
 const S* );

template <class T>
inline IA_Image<IA_Point<int>, T> generic_product
(const IA_DDTemplate< IA_Image<IA_Point<int>, T> > &tmpl,
 const IA_CoreImage<IA_Point<int>, T> &img,
 const IA_Set<IA_Point<int> > &dst,
 T (*circle)(T,T),
 T (*Gamma)(T*,unsigned)) {
    return generic_product(tmpl, img, dst,
			   circle, Gamma, (T*)0, (T*)0, (T*)0);
}

#endif AuxDDTempl_h_
