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

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


//
// $Log: BitDI.h,v $
// Revision 1.8.1.3  1995/01/13  19:37:42  thoth
// CoreImage has been re-merged with Image.  All special stuff should be
// friends of FBI now.
//
// Revision 1.8.1.2  1995/01/09  17:52:46  thoth
// Outline functions shouldn't have inline qualifier.
//
// Revision 1.8.1.1  1994/12/28  15:44:03  thoth
// image I/O is now ROF.
//
// Revision 1.8  1994/09/15  19:36:59  jnw
// Added display function for IA_Image<IA_Point<int>, IA_Bit>
//
// Revision 1.7  1994/08/22  15:20:29  thoth
// DOS-inspired name rework.
//
// Revision 1.6  1994/07/25  17:30:14  thoth
// Name sanitization
//
// Revision 1.5  1994/03/30  13:51:17  thoth
// inline non-member functions to do image input.
//
// Revision 1.4  1994/01/31  15:39:11  thoth
// read and write PBM is now available.
// attempt to have I(bit) I(T) operations failed.
//
// Revision 1.3  1994/01/07  15:10:00  thoth
// Image class is now CoreImage and named image types are
// Image<P,T>.
//
// Revision 1.2  1993/12/29  16:53:13  thoth
// Bit Discrete Image now uses separate Bit type.
//
// Revision 1.1  1993/11/29  22:20:39  thoth
// Initial revision
//
//

#ifndef BitDI_h_
#define BitDI_h_

#include "Bit.h"
//#include "Image.h"

#define SUPPRESS_INCLUDE
#include "Image.h"
#undef SUPPRESS_INCLUDE

#include	<complex.h>	// for the complex conversion

#if 0
class IA_Image<IA_Point<int>,IA_Bit>: public IA_Image<IA_Point<int>, IA_Bit>
{
  public:
    IA_Image():IA_Image<IA_Point<int>, IA_Bit>() {}

    IA_Image(const IA_Image& im)
    :IA_Image<IA_Point<int>, IA_Bit>(im) {}

    IA_Image(IA_Set<IA_Point<int> > ps, int value)
    :IA_Image<IA_Point<int>, IA_Bit>(ps,(IA_Bit)value) {}

    IA_Image(IA_Set<IA_Point<int> > ps, IA_Bit *vp, unsigned sz,
			  int giveaway=0)
    :IA_Image<IA_Point<int>, IA_Bit>(ps, vp, sz, giveaway) {}

    IA_Image(IA_Set<IA_Point<int> > ps, const IA_Bit *vp, unsigned sz)
    :IA_Image<IA_Point<int>, IA_Bit>(ps, vp, sz) {}

    IA_Image(const IA_ClosureI<IA_Point<int>,IA_Bit> &img)
    :IA_Image<IA_Point<int>, IA_Bit>(img) {}

    IA_Image(IA_Set<IA_Point<int> > ps, IA_Bit (*f)(const IA_Point<int>&))
    :IA_Image<IA_Point<int>, IA_Bit>(ps,f) {}

    IA_Image( const IA_Image<IA_Point<int>, IA_Bit> &d)
    :IA_Image<IA_Point<int>, IA_Bit>(d) {}

    virtual ~IA_Image(){ }

#if 0

//binary pointwise commutative operator* I(u_char) I(IA_Bit) I(u_char)
friend IA_Image<IA_Point<int>, u_char> operator*(const IA_Image<IA_Point<int>,u_char> &,const IA_Image<IA_Point<int>,IA_Bit> &);
friend IA_Image<IA_Point<int>, u_char> operator*(const IA_Image<IA_Point<int>,IA_Bit> & lhs,const IA_Image<IA_Point<int>,u_char> & rhs) {
    return rhs*lhs;
}

//binary pointwise commutative operator* u_char I(IA_Bit) I(u_char)
friend IA_Image<IA_Point<int>, u_char> operator*(u_char,const IA_Image<IA_Point<int>,IA_Bit> &);
friend IA_Image<IA_Point<int>, u_char> operator*(const IA_Image<IA_Point<int>,IA_Bit> & lhs,u_char rhs) {
    return rhs*lhs;
}

//binary pointwise commutative operator* I(int) I(IA_Bit) I(int)
friend IA_Image<IA_Point<int>, int> operator*(const IA_Image<IA_Point<int>,int> &,const IA_Image<IA_Point<int>,IA_Bit> &);
friend IA_Image<IA_Point<int>, int> operator*(const IA_Image<IA_Point<int>,IA_Bit> & lhs,const IA_Image<IA_Point<int>,int> & rhs) {
    return rhs*lhs;
}

//binary pointwise commutative operator* int I(IA_Bit) I(int)
friend IA_Image<IA_Point<int>, int> operator*(int,const IA_Image<IA_Point<int>,IA_Bit> &);
friend IA_Image<IA_Point<int>, int> operator*(const IA_Image<IA_Point<int>,IA_Bit> & lhs,int rhs) {
    return rhs*lhs;
}

//binary pointwise commutative operator* I(float) I(IA_Bit) I(float)
friend IA_Image<IA_Point<int>, float> operator*(const IA_Image<IA_Point<int>,float> &,const IA_Image<IA_Point<int>,IA_Bit> &);
friend IA_Image<IA_Point<int>, float> operator*(const IA_Image<IA_Point<int>,IA_Bit> & lhs,const IA_Image<IA_Point<int>,float> & rhs) {
    return rhs*lhs;
}

//binary pointwise commutative operator* float I(IA_Bit) I(float)
friend IA_Image<IA_Point<int>, float> operator*(float,const IA_Image<IA_Point<int>,IA_Bit> &);
friend IA_Image<IA_Point<int>, float> operator*(const IA_Image<IA_Point<int>,IA_Bit> & lhs,float rhs) {
    return rhs*lhs;
}

//binary pointwise commutative operator* I(complex) I(IA_Bit) I(complex)
friend IA_Image<IA_Point<int>, complex> operator*(const IA_Image<IA_Point<int>,complex> &,const IA_Image<IA_Point<int>,IA_Bit> &);
friend IA_Image<IA_Point<int>, complex> operator*(const IA_Image<IA_Point<int>,IA_Bit> & lhs,const IA_Image<IA_Point<int>,complex> & rhs) {
    return rhs*lhs;
}

//binary pointwise commutative operator* complex I(IA_Bit) I(complex)
friend IA_Image<IA_Point<int>, complex> operator*(complex,const IA_Image<IA_Point<int>,IA_Bit> &);
friend IA_Image<IA_Point<int>, complex> operator*(const IA_Image<IA_Point<int>,IA_Bit> & lhs,complex rhs) {
    return rhs*lhs;
}
#endif
#if 0
    static IA_Image read_PBM(istream &);
    static IA_Image read_PBM(const char *fname);

    ostream& write_PBM(ostream &) const;
    void write_PBM(const char *fname) const;
#endif
};
#endif


#include        "BitIOps.h"

//
//

IA_Image<IA_Point<int>,IA_Bit> read_PBM(istream &i);
IA_Image<IA_Point<int>,IA_Bit> read_PBM(const char *fname);

//
//

void write_PBM(const IA_Image<IA_Point<int>,IA_Bit> &img,
		      const char *fname);

ostream & write_PBM(const IA_Image<IA_Point<int>,IA_Bit> &img, ostream &o);

//
//

inline int operator!=(const IA_Image<IA_Point<int>,IA_Bit> &lhs,
	       const IA_Image<IA_Point<int>,IA_Bit> &rhs) {
    return ! (lhs == rhs);
}
inline int operator!=(const IA_Image<IA_Point<int>,IA_Bit> &lhs,
		      IA_Bit rhs) {
    return ! (lhs == rhs);
}
inline int operator!=(IA_Bit lhs,
		      const IA_Image<IA_Point<int>,IA_Bit> &rhs) {
    return ! (rhs == lhs);
}

//
//

inline IA_Image<IA_Point<int>, IA_Bit>
operator&&(const IA_Image<IA_Point<int>, IA_Bit> &lhs,
	   const IA_Image<IA_Point<int>, IA_Bit> &rhs) {
    return lhs & rhs;
}

inline IA_Image<IA_Point<int>, IA_Bit>
operator&&(IA_Bit lhs,
	   const IA_Image<IA_Point<int>, IA_Bit> &rhs) {
    return lhs & rhs;
}

inline IA_Image<IA_Point<int>, IA_Bit>
operator&&(const IA_Image<IA_Point<int>, IA_Bit> &lhs,
	   IA_Bit rhs) {
    return lhs & rhs;
}

//
//

inline IA_Image<IA_Point<int>, IA_Bit>
operator||(const IA_Image<IA_Point<int>, IA_Bit> &lhs,
	   const IA_Image<IA_Point<int>, IA_Bit> &rhs) {
    return lhs | rhs;
}

inline IA_Image<IA_Point<int>, IA_Bit>
operator||(IA_Bit lhs,
	   const IA_Image<IA_Point<int>, IA_Bit> &rhs) {
    return lhs | rhs;
}

inline IA_Image<IA_Point<int>, IA_Bit>
operator||(const IA_Image<IA_Point<int>, IA_Bit> &lhs,
	   IA_Bit rhs) {
    return lhs | rhs;
}

//
//

pid_t display(IA_Image<IA_Point<int>,IA_Bit> img);

// compiler clue to allow inexact matches on a function template
ostream& operator <<(ostream&, const IA_Image<IA_Point<int>, IA_Bit>&);

#endif
