head	1.10;
access;
symbols
	r0_10:1.10
	Eglin_alpha_1:1.10;
locks; strict;
comment	@// @;


1.10
date	93.05.27.11.27.46;	author thoth;	state Exp;
branches;
next	1.9;

1.9
date	93.05.26.16.58.38;	author thoth;	state Exp;
branches;
next	1.8;

1.8
date	93.05.18.21.38.08;	author thoth;	state Exp;
branches;
next	1.7;

1.7
date	93.04.17.18.44.27;	author thoth;	state Exp;
branches;
next	1.6;

1.6
date	93.04.08.13.04.29;	author thoth;	state Exp;
branches;
next	1.5;

1.5
date	93.03.10.13.30.52;	author thoth;	state Exp;
branches;
next	1.4;

1.4
date	93.02.23.14.04.03;	author thoth;	state Exp;
branches;
next	1.3;

1.3
date	93.02.20.12.26.41;	author thoth;	state Exp;
branches;
next	1.2;

1.2
date	93.01.19.14.55.32;	author jnw;	state Exp;
branches;
next	1.1;

1.1
date	92.10.05.11.43.04;	author jnw;	state Exp;
branches;
next	;


desc
@Initial revision
@


1.10
log
@Copyright Notices
@
text
@// Emacs: -*- C++ -*-

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


static char BaseDIrcsid[] = "$Id: BaseDI.c,v 1.9 93/05/26 16:58:38 thoth Exp Locker: thoth $";

// $Log:	BaseDI.c,v $
// Revision 1.9  93/05/26  16:58:38  thoth
// Performance enhancement.
// 
// Revision 1.8  93/05/18  21:38:08  thoth
// range method returns ValueSet again.
// new value_array method gives an Array of image values.
// 
// 
// Revision 1.7  93/04/17  18:44:27  thoth
// Iterator support is no longer based on a switch statement.  We now
// use a virtual method.  The user can now provide faster iterators.
// 
// Revision 1.6  93/04/08  13:04:29  thoth
// Default restriction and translation methods.
// 
// Revision 1.5  93/03/10  13:30:52  thoth
// range method no longer returns valueset due to
// difficulties with template implementation.
// 
// Revision 1.4  93/02/23  14:04:03  thoth
// clone_self_extensively and range now have default versions.
// DI implementations that can do these operations faster can
// provide their own version that overrides the inherited default.
// 
// Revision 1.3  93/02/20  12:26:41  thoth
// operator[] is no longer inline.  Being virtual and moderately complicated,
// inlineness was not justified.
// 
// Revision 1.2  93/01/19  14:55:32  jnw
// Modified to support IA_ naming convention
// 
// Revision 1.1  92/10/05  11:43:04  jnw
// Initial revision
// 

#include "IPSIter.h"
#include "BaseDI.h"
#include "OtherDIIter.h"
#include "VectorDI.h"


template <class T>
T& IA_BaseDI<T>::operator[](const IA_IntPoint&)
{
    ia_throw( IA::IMAGE_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
    abort(); // internal error
    T	lie;
    return lie;
}

template <class T>
IA_BaseDI<T>* IA_BaseDI<T>::clone_self_extensively() const
{
    // This will throw if the pointset is comprehensive, but
    // we can\'t clone extensively if our domain is comprehensive.
    const unsigned sz = ps.card();

    // We will build a VectorDI
    T *const dest = new T[sz];

    {
	// Iterate over the domain.
	IA_IPSIter	iter(ps);
	// For each point
	IA_IntPoint	ip;
	T *scan = dest;

	while (iter(ip))
	    // evaluate the image at that point and place it in the
	    // proper slot of the vector.
	    *(scan++) = (*this)(ip);
    }

    // Build a VectorDI and give away the value vector.
    return new IA_VectorDI<T>(ps, dest, sz, 1);
}

#if 1
template <class T>
IA_ValueSet<T> IA_BaseDI<T>::range() const
{
    // This will throw if the pointset is comprehensive, but
    // we can\'t compute the range if our domain is comprehensive.
    const unsigned sz = ps.card();

    // We will build a vector of values
    T *const dest = new T[sz];

    {
	// Iterate over the domain.
	IA_IPSIter	iter(ps);
	// For each point
	IA_IntPoint	ip;
	T *scan = dest;

	while (iter(ip))
	    // evaluate the image at that point and place it in the vector.
	    *(scan++) = (*this)(ip);
    }

    IA_ValueSet<T>	rval(dest, sz);
    delete[] dest;

    return rval;
}
#else
template <class T>
T* IA_BaseDI<T>::range(unsigned *sz) const
{
    // This will throw if the pointset is comprehensive, but
    // we can\'t compute the range if our domain is comprehensive.
    *sz = ps.card();

    // We will build a vector of values
    T *const dest = new T[*sz];

    {
	// Iterate over the domain.
	IA_IPSIter	iter(ps);
	// For each point
	IA_IntPoint	ip;
	T *scan = dest;

	while (iter(ip))
	    // evaluate the image at that point and place it in the vector.
	    *(scan++) = (*this)(ip);
    }

    return dest;
}
#endif

template <class T>
IA_Array<T> IA_BaseDI<T>::value_array() const
{
    // This will throw if the pointset is comprehensive, but
    // we can\'t compute the value_array if our domain is comprehensive.
    const unsigned sz = ps.card();

    // We will build a vector of values
    T *const dest = new T[sz];

    {
	// Iterate over the domain.
	IA_IPSIter	iter(ps);
	// For each point
	IA_IntPoint	ip;
	T *scan = dest;

	while (iter(ip))
	    // evaluate the image at that point and place it in the vector.
	    *(scan++) = (*this)(ip);
    }

    return IA_Array<T>(dest, sz, 1);
}

template <class T>
IA_BaseDI<T> *IA_BaseDI<T>::restricted_to(const IA_IntPointSet &ips) const
{
    IA_SetStructure	ss;
    IA_IntPointSet	result_domain =
	intersect_with_structure(this->domain(), ips, &ss);
    if (result_domain == this->domain())
	// clue to reuse this object
	return 0;

    const unsigned	sz = result_domain.card();
    T * const	dest = new T[sz];
    {
	T	*scan = dest;
	IA_IPSIter	iter(result_domain);
	IA_IntPoint	ip;
	while (iter(ip))
	    *(scan++) = (*this)(ip);
    }

    return new IA_VectorDI<T>(result_domain, dest, sz, 1);
}

//
//
//

template <class T>
class IA_LazyXlationDI: public IA_BaseDI<T> {
  private:
    static char	dummy;

    const IA_IntPoint	offset;
    IA_BaseDI<T>	* base;
  public:
    IA_LazyXlationDI(const IA_BaseDI<T> *base_, IA_IntPoint offset_)
    :IA_BaseDI<T>(base_->domain() + offset_), offset(offset_),
     base((IA_BaseDI<T>*)base_) {
	base->incr_ref();
    }
    ~IA_LazyXlationDI() {
	if (base->decr_ref()<=0)
	    delete base;
    }
    int extensivep() const { return 0; }
    T operator() (const IA_IntPoint &p) const {
	return (*base)(p-offset);
    }
    IA_DiscreteImageType type() const { return &dummy; }
    IA_BaseDI<T> * xlated_by(const IA_IntPoint &p) const {
	return new IA_LazyXlationDI<T>(base, p+offset);
    }
    ostream& print_this(ostream&o) const {
	o<< "translation by " << offset << " of \n";
	return base->print_this(o);
    }
};

template <class T>
char IA_LazyXlationDI<T>::dummy;

template <class T>
IA_BaseDI<T> *IA_BaseDI<T>::xlated_by(const IA_IntPoint &p) const
{
    return new IA_LazyXlationDI<T>(this, p);
}

//
// Value iterator support below
//

template <class T>
IA_BaseDIVIter<T> *IA_BaseDI<T>::value_iterator() const
{
    return new IA_OtherDIVIter<T>(this);
}

template <class T>
IA_BaseDIPIter<T> *IA_BaseDI<T>::pixel_iterator() const
{
    return new IA_OtherDIPIter<T>(this);
}

//
//
//

template <class T>
ostream& operator<<(ostream& o, const IA_BaseDI<T>& bdi)
{
    o << "**Discrete Image**\n";
    bdi.print_this(o);
    return o << "\n******************\n" ;
}

@


1.9
log
@Performance enhancement.
@
text
@d3 4
a6 1
static char BaseDIrcsid[] = "$Id: BaseDI.c,v 1.8 93/05/18 21:38:08 thoth Exp Locker: thoth $";
d8 3
d12 3
@


1.8
log
@range method returns ValueSet again.
new value_array method gives an Array of image values.

@
text
@d3 1
a3 1
static char BaseDIrcsid[] = "$Id: BaseDI.c,v 1.7 93/04/17 18:44:27 thoth Exp Locker: thoth $";
d6 5
d157 1
a157 4
    IA_Array<T>	rval(dest, sz);
    delete[] dest;

    return rval;
@


1.7
log
@Iterator support is no longer based on a switch statement.  We now
use a virtual method.  The user can now provide faster iterators.
@
text
@d3 1
a3 1
static char BaseDIrcsid[] = "$Id: BaseDI.c,v 1.6 93/04/08 13:04:29 thoth Exp Locker: thoth $";
d6 4
d75 1
d77 28
d127 29
@


1.6
log
@Default restriction and translation methods.
@
text
@d3 1
a3 1
static char BaseDIrcsid[] = "$Id: BaseDI.c,v 1.5 93/03/10 13:30:52 thoth Exp Locker: thoth $";
d6 3
d31 1
d161 16
@


1.5
log
@range method no longer returns valueset due to
difficulties with template implementation.
@
text
@d3 1
a3 1
static char BaseDIrcsid[] = "$Id: BaseDI.c,v 1.4 93/02/23 14:04:03 thoth Exp Locker: thoth $";
d6 4
d91 71
@


1.4
log
@clone_self_extensively and range now have default versions.
DI implementations that can do these operations faster can
provide their own version that overrides the inherited default.
@
text
@d3 1
a3 1
static char BaseDIrcsid[] = "$Id: BaseDI.c,v 1.3 93/02/20 12:26:41 thoth Exp Locker: thoth $";
d6 5
d64 1
a64 1
IA_ValueSet<T> IA_BaseDI<T>::range() const
d68 1
a68 1
    const unsigned sz = ps.card();
d71 1
a71 1
    T *const dest = new T[sz];
d85 1
a85 3
    IA_ValueSet<T>	rval(dest, sz);
    delete[] dest;
    return rval;
@


1.3
log
@operator[] is no longer inline.  Being virtual and moderately complicated,
inlineness was not justified.
@
text
@d3 1
a3 1
static char BaseDIrcsid[] = "$Id: BaseDI.c,v 1.2 93/01/19 14:55:32 jnw Exp Locker: thoth $";
d6 4
d17 1
d19 1
d27 56
a82 2
    T	liar;
    return liar;
@


1.2
log
@Modified to support IA_ naming convention
@
text
@d3 1
a3 1
static char BaseDIrcsid[] = "$Id: BaseDI.c,v 1.1 92/10/05 11:43:04 jnw Exp Locker: jnw $";
d6 3
d14 10
@


1.1
log
@Initial revision
@
text
@d3 1
a3 1
static char BaseDIrcsid[] = "$Id$";
d5 4
a8 1
// $Log$
d13 1
a13 1
ostream& operator<<(ostream& o, const BaseDI<T>& bdi)
@
