//
//	Copyright 1993, Center for Computer Vision and Visualization,
//	University of Florida.  All rights reserved.
//
//
// $Log: nbh-ops.desc,v $
// Revision 1.3  1994/05/08  19:42:50  thoth
// Automatic neighborhood reductions require change in spec file.
//
// Revision 1.2  1994/04/15  13:19:55  thoth
// removed neighborhood_ prefix from reductions.
//
// Revision 1.1  1994/01/31  16:50:30  thoth
// Initial revision
//
//
// Things that frob Bit images
//
//"C#define NEED_SPARE
// Not really, one of the other reductions below defines the spare for us.
// neighborhood int sum IA_Bit zero=0
friend IA_Image<IA_Point<int>,int> sum(const IA_CoreImage<IA_Point<int>,IA_Bit> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> sum(const IA_CoreImage<IA_Point<int>,IA_Bit> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return sum(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,int> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,IA_Bit> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,IA_Bit> &img) {
    return sum(nbh, img, img.domain());
}

//"C#undef NEED_SPARE
// neighborhood IA_Bit max IA_Bit zero=0
friend IA_Image<IA_Point<int>,IA_Bit> max(const IA_CoreImage<IA_Point<int>,IA_Bit> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,IA_Bit> max(const IA_CoreImage<IA_Point<int>,IA_Bit> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return max(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,IA_Bit> max(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,IA_Bit> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,IA_Bit> max(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,IA_Bit> &img) {
    return max(nbh, img, img.domain());
}

// neighborhood IA_Bit min IA_Bit zero=1
friend IA_Image<IA_Point<int>,IA_Bit> min(const IA_CoreImage<IA_Point<int>,IA_Bit> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,IA_Bit> min(const IA_CoreImage<IA_Point<int>,IA_Bit> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return min(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,IA_Bit> min(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,IA_Bit> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,IA_Bit> min(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,IA_Bit> &img) {
    return min(nbh, img, img.domain());
}

//
// Things that frob unsigned char images
//
// neighborhood int sum u_char zero=0
friend IA_Image<IA_Point<int>,int> sum(const IA_CoreImage<IA_Point<int>,u_char> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> sum(const IA_CoreImage<IA_Point<int>,u_char> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return sum(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,int> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,u_char> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,u_char> &img) {
    return sum(nbh, img, img.domain());
}

// neighborhood u_char max u_char zero=0
friend IA_Image<IA_Point<int>,u_char> max(const IA_CoreImage<IA_Point<int>,u_char> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,u_char> max(const IA_CoreImage<IA_Point<int>,u_char> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return max(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,u_char> max(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,u_char> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,u_char> max(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,u_char> &img) {
    return max(nbh, img, img.domain());
}

// neighborhood u_char min u_char zero=255
friend IA_Image<IA_Point<int>,u_char> min(const IA_CoreImage<IA_Point<int>,u_char> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,u_char> min(const IA_CoreImage<IA_Point<int>,u_char> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return min(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,u_char> min(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,u_char> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,u_char> min(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,u_char> &img) {
    return min(nbh, img, img.domain());
}

//
// Things that frob int images
//
// neighborhood int sum int zero=0
friend IA_Image<IA_Point<int>,int> sum(const IA_CoreImage<IA_Point<int>,int> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> sum(const IA_CoreImage<IA_Point<int>,int> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return sum(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,int> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,int> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,int> &img) {
    return sum(nbh, img, img.domain());
}

// neighborhood int product int zero=1
friend IA_Image<IA_Point<int>,int> product(const IA_CoreImage<IA_Point<int>,int> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> product(const IA_CoreImage<IA_Point<int>,int> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return product(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,int> product(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,int> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> product(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,int> &img) {
    return product(nbh, img, img.domain());
}

// neighborhood int max int zero=-MAXINT
friend IA_Image<IA_Point<int>,int> max(const IA_CoreImage<IA_Point<int>,int> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> max(const IA_CoreImage<IA_Point<int>,int> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return max(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,int> max(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,int> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> max(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,int> &img) {
    return max(nbh, img, img.domain());
}

// neighborhood int min int zero=MAXINT
friend IA_Image<IA_Point<int>,int> min(const IA_CoreImage<IA_Point<int>,int> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> min(const IA_CoreImage<IA_Point<int>,int> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return min(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,int> min(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,int> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,int> min(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,int> &img) {
    return min(nbh, img, img.domain());
}

//
// Things that frob float images
//
// neighborhood float sum float zero=0
friend IA_Image<IA_Point<int>,float> sum(const IA_CoreImage<IA_Point<int>,float> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,float> sum(const IA_CoreImage<IA_Point<int>,float> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return sum(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,float> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,float> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,float> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,float> &img) {
    return sum(nbh, img, img.domain());
}

// neighborhood float product float zero=1
friend IA_Image<IA_Point<int>,float> product(const IA_CoreImage<IA_Point<int>,float> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,float> product(const IA_CoreImage<IA_Point<int>,float> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return product(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,float> product(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,float> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,float> product(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,float> &img) {
    return product(nbh, img, img.domain());
}

// neighborhood float max float zero=-infinity()
friend IA_Image<IA_Point<int>,float> max(const IA_CoreImage<IA_Point<int>,float> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,float> max(const IA_CoreImage<IA_Point<int>,float> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return max(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,float> max(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,float> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,float> max(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,float> &img) {
    return max(nbh, img, img.domain());
}

// neighborhood float min float zero=infinity()
friend IA_Image<IA_Point<int>,float> min(const IA_CoreImage<IA_Point<int>,float> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,float> min(const IA_CoreImage<IA_Point<int>,float> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return min(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,float> min(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,float> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,float> min(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,float> &img) {
    return min(nbh, img, img.domain());
}

//
// Things that frob complex images
//
// neighborhood complex sum complex zero=0
friend IA_Image<IA_Point<int>,complex> sum(const IA_CoreImage<IA_Point<int>,complex> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,complex> sum(const IA_CoreImage<IA_Point<int>,complex> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return sum(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,complex> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,complex> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,complex> sum(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,complex> &img) {
    return sum(nbh, img, img.domain());
}

// neighborhood complex product complex zero=1
friend IA_Image<IA_Point<int>,complex> product(const IA_CoreImage<IA_Point<int>,complex> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,complex> product(const IA_CoreImage<IA_Point<int>,complex> &img,
		const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh) {
    return product(img, nbh, img.domain());
}

friend IA_Image<IA_Point<int>,complex> product(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,complex> &img,
		IA_Set<IA_Point<int> > dest_ps);

inline friend IA_Image<IA_Point<int>,complex> product(const IA_Neighborhood<IA_Point<int>,IA_Point<int> > &nbh,
		const IA_CoreImage<IA_Point<int>,complex> &img) {
    return product(nbh, img, img.domain());
}

