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

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

static char copyright[] = "Copyright 1993, Center for Computer Vision and Visualization,\nUniversity of Florida.  All rights reserved.\n";

static char FloatDI_rcsid[] = "$Id: FloatDI.c,v 1.4 1994/01/07 15:10:00 thoth Exp $";

//
// $Log: FloatDI.c,v $
// Revision 1.4  1994/01/07  15:10:00  thoth
// Image class is now CoreImage and named image types are
// Image<P,T>.
//
// Revision 1.3  1993/11/17  18:16:48  thoth
// IPSIter is now PSIter<IntPoint>.
// restriction functions now go in the individual image implementation modules.
// pseudo-division is now avaliable.
//
// Revision 1.2  1993/10/05  19:33:08  thoth
// Move to new Closure naming convention.
//
// Revision 1.1  1993/09/15  12:52:30  thoth
// Initial revision
//
// Revision 1.4  93/06/10  17:24:05  thoth
// instantiations for IAAIO
// 
// Revision 1.3  93/05/27  11:36:24  thoth
// Copyright Notices
// 
// Revision 1.2  93/05/26  17:00:34  thoth
// instantiate all the compositions.
// 
// Revision 1.1  93/04/17  18:59:16  thoth
// Initial revision
// 


#include	"FloatDI.h"
#include	"VectorI.h"
#include	"ConstI.h"
#include	"ClosureI.h"
#include	"ErrorI.h"
#include	"ImageIter.h"
#include	"PSIter.h"

#include	<math.h>
#include	<fstream.h>

//
//
//

#include "restrict.h"

IA_BaseImage<IA_Point<int>,float> *restrict_toD(const IA_BaseImage<IA_Point<int>, float> *im, const IA_Set<IA_Point<int> > &ips) {
    return restrictD_toD(im, ips);
}


//
// below are included the implementations of every image-image
// and image-scalar operation we could think of for float images.
//

template <class T>
inline T max(T a, T b)
{
    return (a<b)?b:a;
}

template <class T>
inline T min(T a, T b)
{
    return (a<b)?a:b;
}

template <class T>
inline T sqr(T v)
{
    return v*v;
}

inline float pseudo_div(float a, float b)
{
    return (b==0) ? 0 : (a/b);
}

inline float pseudo_inv(float b)
{
    return (b==0) ? 0 : (1/b);
}

#include "FloatImageOps.c"

//
//
//

#if 0

class blah : public IA_ClosureI<IA_IntPoint,float> {
  public:
    blah() 
    :IA_ClosureI<IA_IntPoint,float>(IA_IntPointSet()) {}
    ostream &print_this(ostream &o) const { return o;}
    float operator()(const IA_IntPoint &) const { return 0; }
    IA_ClosureI<IA_IntPoint,float>* clone_self() const { return 0; }
};
static void dummy001()
{
    IA_IntPoint		ip;
    IA_IntPointSet	ps;
    IA_Image<IA_IntPoint,float>	i1;
    IA_Image<IA_IntPoint,float>
	i2(i1),
	i3(ps,0.0),
	i4(ps, (float*)0, 0, 1),
	i5(ps, (float*)0, 0),
	i6(blah()),
	// i7(ps, (float(*)(const IA_IntPoint&))0),
	i10(IA_CoreImage<IA_IntPoint,float>());
    i1 = i1.restrict(i2.range());
    i1 = i1.xlated(ip);
    (IA_CoreImage<IA_IntPoint,float>&)i1 = 2;
    (void)i1.type();
    i1[ip] = i1(ip);
    i1 = i1.restrict(i2.domain());
    (void)i1.extend(i2);
    (void)i1.reduce((float (*)(const float&,const float&)) 0, 0);
    (void)i1.reduce((float (*)( float, float)) 0, 0);
    cout << (IA_CoreImage<IA_IntPoint,float>&)i1;

//     IA_Image<IA_IntPoint,float>::read_IAA("");
//     IA_Image<IA_IntPoint,float>::read_IAA("","");
// 
//     i1.write_IAA("");
//     i1.write_IAA("","");

    IA_IVIter<IA_IntPoint,float>	iter1(i1), iter2;
    IA_IPIter<IA_IntPoint,float>	iter3(i2), iter4;
    iter1 = iter2;
    iter3 = iter4;

    compose(i1, (IA_IntPoint(*)(const IA_IntPoint&))0);
    compose(i1, *(IA_Closure<IA_IntPoint, IA_IntPoint>*)0);
    compose((float(*)(float))0, i1);
    compose((double(*)(double))0, (IA_CoreImage<IA_IntPoint,float>&)i1);
    compose((u_char(*)(float))0, i1, (u_char*)0);

    IA_ValueSet<float>	vs(i1.range());
    // I shouldn\'t have to do the following two lines
    // vs.value_type_compare(0,0);
}
#endif
