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


1.14
date	93.06.10.17.23.59;	author thoth;	state Exp;
branches;
next	1.13;

1.13
date	93.05.27.11.28.22;	author thoth;	state Exp;
branches;
next	1.12;

1.12
date	93.05.26.16.59.56;	author thoth;	state Exp;
branches;
next	1.11;

1.11
date	93.05.18.21.39.00;	author thoth;	state Exp;
branches;
next	1.10;

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

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

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

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

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

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

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

1.3
date	93.01.19.14.56.03;	author jnw;	state Exp;
branches;
next	1.2;

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

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


desc
@Initial revision
@


1.14
log
@Workaround for 3.0.1 bug.
@
text
@// Emacs: -*- C++ -*-

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


static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.13 93/05/27 11:28:22 thoth Exp $";

// $Log:	DiscreteImage.c,v $
// Revision 1.13  93/05/27  11:28:22  thoth
// Copyright Notices
// 
// Revision 1.12  93/05/26  16:59:56  thoth
// Read and write of IAA image files.
// 
// Revision 1.11  93/05/18  21:39:00  thoth
// BaseDI range method returns ValueSet again.
// New Point-Point composition closure object.
// 
// Revision 1.10  93/04/29  11:18:38  thoth
// Support for point-point-function and image composition.
// 
// Revision 1.9  93/04/08  13:10:49  thoth
// removed cruft.
// restriction is now a virtual method of the BaseDI.  We don't
// need that goofy case statement any more.
// translation is also a virtual method.
// 
// Revision 1.8  93/03/10  13:32:36  thoth
// range method no longer returns valueset due to
// difficulties with template implementation.
// FunctionDI constructor was not truly generic.
// 
// Revision 1.7  93/02/23  14:10:14  thoth
// set_and_reference_image method encodes common initialization semantics.
// User-defined OtherDIs are now supported.
// 
// Revision 1.6  93/02/20  12:55:06  thoth
// Function images are no longer supported.
// ErrorDIs are created dynamically as needed.
// This is conceptually convenient.
// The pointset should go first in an image constructor.
// Vector constructors now can give away the value vector.
// Image restriction and extension should be fast now.  I can't
// be certain they work though...
// 
// Revision 1.5  93/02/17  11:00:18  thoth
// We now have the ability to give away the value vector.
// 
// Revision 1.4  93/02/08  12:57:57  thoth
// virtual destructor is now outlined.
// 
// Revision 1.3  93/01/19  14:56:03  jnw
// Modified to support IA_ naming convention
// 
// Revision 1.2  92/11/12  16:59:09  jnw
// Added restriction, extension, iteration, etc.
// 
// Revision 1.1  92/10/05  11:42:42  jnw
// Initial revision
// 

#include <stream.h>
#include	<netinet/in.h>	// for ntohl
#include <string.h>

#include "SetStructure.h"
// if included here, DIIters screw up
//#include "PredicatePS.h"

#include "DiscreteImage.h"

//#include "LazyDI.h"
#include "DIVIter.h"
#include "DIPIter.h"

#include "ErrorDI.h"
#include "ConstDI.h"
#include "VectorDI.h"
#include "OtherDI.h"
#include "FunctionRefDI.h"

#include "PredicatePS.h"

// I wish this worked
//template <class T> IA_ErrorDI<T> IA_DiscreteImage<T>::errorDI;


template <class T>
void IA_DiscreteImage<T>::set_and_reference_image(IA_BaseDI<T> *i)
{
    i->incr_ref();
    this->bdip = i;
}

template <class T>
void IA_DiscreteImage<T>::disassociate_image()
//
// Adjusts the reference count of the BaseDI associated with *this.
// If this is the only reference to the BaseDI, it is deleted.
//
{
    if (this->bdip->decr_ref() <= 0) {
	delete this->bdip;
    }
    this->bdip = 0;
}

template <class T>
IA_DiscreteImage<T>::~IA_DiscreteImage()
// clean up the storage associated with this image
{
    this->disassociate_image();
}

template <class T>
IA_DiscreteImage<T>::IA_DiscreteImage()
{
    set_and_reference_image(new IA_ErrorDI<T>);
}

template <class T>
IA_DiscreteImage<T>::IA_DiscreteImage(const IA_DiscreteImage<T>& im)
//
// Copy ctor  increments the reference count of the BaseDI associated
// with the image being copied.
//
// im		UNmodified
//
{
    set_and_reference_image(im.bdip);
}

template <class T>
IA_DiscreteImage<T>::IA_DiscreteImage(const IA_IntPointSet& p, const T& value)
//
// Constant valued image ctor
//
// value	UNmodified
// p		UNmodified
//
{
    set_and_reference_image(new IA_ConstDI<T>(p, value));
}

template <class T>
IA_DiscreteImage<T>::IA_DiscreteImage(const IA_IntPointSet& p, T *values,
				      unsigned sz, int giveaway)
//
// Vector image constructor
//	Given values (a vector with elements of type T), IntPointSet p,
//	and sz (the number of Points in p), this creates a new image which
//	associates the elements in values with the points in p in the
//	iteration order of points p.  If the flag giveaway is true, we now
//	own the storage for values (and we give it to the VectorDI).
//
// p		UNmodified
{
    this->bdip=0;	// in case we throw

    if (!p.extensivep()){
	ia_throw( IA::IMAGE_STRUCTURE_NOT_SUPPORTED, __FILE__, __LINE__);
	return;
    }

    if (sz != p.card()) {
	abort(); // throw
	return;
    }
    set_and_reference_image(new IA_VectorDI<T>(p, values, sz, giveaway));
}

template <class T>
IA_DiscreteImage<T>::IA_DiscreteImage(const IA_IntPointSet& p,
				      const T *values, unsigned sz)
//
// Vector image constructor
//	Given values (a vector with elements of type T), IntPointSet p,
//	and sz (the number of Points in p), this creates a new image which
//	associates the elements in values with the points in p in the
//	iteration order of points p.
//
// p		UNmodified
{
    this->bdip=0;	// in case we throw

    if (!p.extensivep()){
	ia_throw( IA::IMAGE_STRUCTURE_NOT_SUPPORTED
	      , __FILE__, __LINE__);
	return;
    }

    if (sz != p.card()) {
	abort(); // throw
	return;
    }

    // We can cast away constness because we know the VectorDI
    // constructor won\'t hose us.
    set_and_reference_image(new IA_VectorDI<T>(p, (T*)values, sz, 0));
}

template <class T>
IA_DiscreteImage<T>::IA_DiscreteImage(const IA_OtherDI<T>&i)
// User-defined-image constructor.  They provide us with an object,
// we clone a copy onto the heap and point to it.
{
    set_and_reference_image(i.clone_self());
}

template <class T>
IA_DiscreteImage<T>::IA_DiscreteImage(const IA_IntPointSet &ps,
				      T (*f)(const IA_IntPoint&))
// User-defined-image constructor.  They provide us with a function
// and we wrap an implementation around it.
{
    set_and_reference_image(new IA_FunctionRefDI<T>(ps,f));
}

template <class T>
IA_DiscreteImage<T>&
IA_DiscreteImage<T>::operator=(const IA_DiscreteImage<T>& im)
//
// Image assignment operator
//
// im		UNmodified (however, the reference count of the image
//		       	referenced by im will be modified)
//
{
    IA_BaseDI<T> *temp = im.bdip;
    temp->incr_ref();

    this->disassociate_image();

    this->bdip = temp;

    return *this;
}

template <class T>
IA_DiscreteImage<T>& IA_DiscreteImage<T>::operator =(const T& value)
//
// Image assignment by constant value
//
// value	UNmodified
//
{
    IA_IntPointSet pset;
    pset = this->domain();
    this->disassociate_image();
    set_and_reference_image(new IA_ConstDI<T>(pset, value));
    return *this;
}

template <class T>
T& IA_DiscreteImage<T>::operator [](const IA_IntPoint& p)
//
// Return a reference to a pixel value.  The user could potentially
// modify the value through the reference.  Since images are reference
// counted we use a copy-on-(potential)write scheme.
//
{
    if (!this->domain().contains(p)) {
	abort();		// throw
    }
    if (this->bdip->get_ref() > 1 || !this->bdip->extensivep()) {

	// If reference count > 1, we need to clone the base image to avoid
	//	multiple writers.
	// If bdip is not extensive, we need to clone the base image to have
	//	an address we can return.

	IA_BaseDI<T>	*temp = bdip->clone_self_extensively();

	this->disassociate_image();	// We don\'t need this anymore.

	set_and_reference_image(temp);
    }
    return (*this->bdip)[p];
}


template <class T>
IA_DiscreteImage<T> IA_DiscreteImage<T>::restrict(const IA_IntPointSet& ips)
    const
{
    IA_BaseDI<T>	*rval = bdip->restricted_to(ips);
    if (rval)
	return rval;
    else
	return *this;
}

template <class T>
IA_DiscreteImage<T> IA_DiscreteImage<T>::restrict(const IA_ValueSet<T>& vs)
    const
{
    if (!this->domain().extensivep()) {
	ia_throw( IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
    }
    
    const	unsigned sz = this->domain().card();
    IA_IntPoint *point_vec = new IA_IntPoint[sz];
    T *value_vec = new T[sz];
    
    IA_DIPIter<T> iter(*this);
    IA_IntPoint point;
    T value;
    int new_size=0;
    
    // Copy all points in *this\'s domain that have values in the argument
    // ValueSet.
    while(iter(point,value)){
	if (vs.contains(value)){
	    value_vec[new_size] = value;
	    point_vec[new_size] = point;
	    new_size++;
	}
    }
    
    IA_DiscreteImage<T> rval = IA_DiscreteImage<T>
	(IA_IntPointSet(this->domain().dim(), point_vec, new_size),
	 value_vec, new_size, 1);
    
    delete[] point_vec;
    
    return rval;
}

//
// The following functions implement image extension
//

template <class T>
void IA_DiscreteImage<T>::vec_vec_2_vec_structcopy
(const T **lhs_data, const T **rhs_data, T **dest, const IA_SetStructure &ss)
//
// Copy values from *lhs_data and *rhs_data into *dest according to
// SetStructure ss.  If there is a value from both, the **lhs_data
// is preferred.
//
// *lhs_data	MODIFIED
// *rhs_data	MODIFIED
// *dest	MODIFIED
// ss		not modified
{
    for(int i = 0; i < ss.nintervals(); i++) {
	IA_ss_interval ssi = ss.retrieve_interval(i);
	if (ssi.substructure == IA_SetStructure::BOTH) {
	    for (int j=0; j<ssi.count; j++) {
		*((*dest)++) = *((*lhs_data)++);
		(*rhs_data)++;
	    }
	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		*((*dest)++) = *((*lhs_data)++);
	    }
	} else if (ssi.substructure == IA_SetStructure::SECOND_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		*((*dest)++) = *((*rhs_data)++);
	    }
	} else {
	    for (int j=0; j<ssi.count; j++) {
		vec_vec_2_vec_structcopy(lhs_data, rhs_data, dest,
					 ssi.substructure);
	    }
	}
    }
}

template <class T>
void IA_DiscreteImage<T>::vec_iter_2_vec_structcopy
(
 const T	**lhs_data,
#ifdef FUNKY_ERROR
 void *rhs_v,
#else
 IA_DIVIter<T> *rhs_iter,
#endif
 T **dest, const IA_SetStructure &ss)
//
// Copy values from *lhs_data and *rhs_iter into *dest according to
// SetStructure ss.  If there is a value from both, the lhs data
// is preferred.
//
// *lhs_data	MODIFIED
// *rhs_iter	MODIFIED
// *dest	MODIFIED
// ss		not modified
{
#ifdef FUNKY_ERROR
    IA_DIVIter<T>	*rhs_iter = (IA_DIVIter<T> *)rhs_v;
#endif
    T	temp;
    for(int i = 0; i < ss.nintervals(); i++) {
	IA_ss_interval ssi = ss.retrieve_interval(i);
	if (ssi.substructure == IA_SetStructure::BOTH) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*rhs_iter)(temp))
		    abort(); // internal error
		*((*dest)++) = *((*lhs_data)++);
	    }
	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		*((*dest)++) = *((*lhs_data)++);
	    }
	} else if (ssi.substructure == IA_SetStructure::SECOND_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*rhs_iter)(temp))
		    abort(); // internal error
		*((*dest)++) = temp;
	    }
	} else {
	    for (int j=0; j<ssi.count; j++) {
		vec_iter_2_vec_structcopy(lhs_data, rhs_iter, dest,
					   ssi.substructure);
	    }
	}
    }
}

template <class T>
void IA_DiscreteImage<T>::iter_vec_2_vec_structcopy
(
#ifdef FUNKY_ERROR
 void *lhs_v,
#else
 IA_DIVIter<T> *lhs_iter,
#endif
 const T**rhs_data,
 T **dest, const IA_SetStructure &ss)
//
// Copy values from *lhs_iter and *rhs_data into *dest according to
// SetStructure ss.  If there is a value from both, the lhs data
// is preferred.
//
// *lhs_iter	MODIFIED
// *rhs_data	MODIFIED
// *dest	MODIFIED
// ss		not modified
{
#ifdef FUNKY_ERROR
    IA_DIVIter<T>	*lhs_iter = (IA_DIVIter<T> *)lhs_v;
#endif
    T	temp;
    for(int i = 0; i < ss.nintervals(); i++) {
	IA_ss_interval ssi = ss.retrieve_interval(i);
	if (ssi.substructure == IA_SetStructure::BOTH) {
	    for (int j=0; j<ssi.count; j++) {
		(*rhs_data)++;
		if (!(*lhs_iter)(temp))
		    abort(); // internal error
		*((*dest)++) = temp;
	    }
	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*lhs_iter)(temp))
		    abort(); // internal error
		*((*dest)++) = temp;
	    }
	} else if (ssi.substructure == IA_SetStructure::SECOND_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		*((*dest)++) = *((*rhs_data)++);
	    }
	} else {
	    for (int j=0; j<ssi.count; j++) {
		iter_vec_2_vec_structcopy(lhs_iter, rhs_data, dest,
					   ssi.substructure);
	    }
	}
    }
}

template <class T>
void IA_DiscreteImage<T>::iter_iter_2_vec_structcopy
(
#ifdef FUNKY_ERROR
 void *lhs_v, void *rhs_v,
#else
 IA_DIVIter<T> *lhs_iter, IA_DIVIter<T> *rhs_iter,
#endif
 T **dest, const IA_SetStructure &ss)
//
// Copy values from *lhs_iter and *rhs_iter into *dest according to
// SetStructure ss.  If there is a value from both, the lhs data
// is preferred.
//
// *lhs_iter	MODIFIED
// *rhs_iter	MODIFIED
// *dest	MODIFIED
// ss		not modified
{
#ifdef FUNKY_ERROR
    IA_DIVIter<T>	*lhs_iter = (IA_DIVIter<T> *)lhs_v;
    IA_DIVIter<T>	*rhs_iter = (IA_DIVIter<T> *)rhs_v;
#endif
    T	temp;
    for(int i = 0; i < ss.nintervals(); i++) {
	IA_ss_interval ssi = ss.retrieve_interval(i);
	if (ssi.substructure == IA_SetStructure::BOTH) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*rhs_iter)(temp))
		    abort(); // internal error
		if (!(*lhs_iter)(temp)) // throw away the rhs value
		    abort(); // internal error
		*((*dest)++) = temp;
	    }
	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*lhs_iter)(temp))
		    abort(); // internal error
		*((*dest)++) = temp;
	    }
	} else if (ssi.substructure == IA_SetStructure::SECOND_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*rhs_iter)(temp))
		    abort(); // internal error
		*((*dest)++) = temp;
	    }
	} else {
	    for (int j=0; j<ssi.count; j++) {
		iter_iter_2_vec_structcopy(lhs_iter, rhs_iter, dest,
					   ssi.substructure);
	    }
	}
    }
}


template <class T>
IA_DiscreteImage<T>
IA_DiscreteImage<T>::extend(const IA_DiscreteImage<T>& imr) const
//
// Returns the extension of image *this to image imr.
//
// imr		UNmodified
//
{
    if(!this->domain().extensivep() || !imr.domain().extensivep()) {
	// Need LazyExtensionImage
	ia_throw( IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
	return IA_DiscreteImage<T>();
    }

    IA_SetStructure ss;
    IA_IntPointSet newps = union_with_structure(this->domain(),
						imr.domain(), &ss);
    const unsigned	sz = newps.card();
    T	* const dest = new T[sz];
    T	*scan = dest;

    if (this->type()==IA_VectorDI<T>::s_type()) {
	const IA_VectorDI<T> *lhs = (IA_VectorDI<T>*)this->bdip;
	const T	*lhs_data = lhs->vec;

	if (imr.type()==IA_VectorDI<T>::s_type()) {
	    const T	*rhs_data = ((IA_VectorDI<T>*)imr.bdip)->vec;
	    vec_vec_2_vec_structcopy(&lhs_data, &rhs_data, &scan, ss);
	} else {
	    IA_DIVIter<T>	rhs_iter(imr);
	    vec_iter_2_vec_structcopy(&lhs_data, &rhs_iter, &scan, ss);
	}
    } else {
	IA_DIVIter<T>	lhs_iter(*this);

	if (imr.type()==IA_VectorDI<T>::s_type()) {
	    const T	*rhs_data = ((IA_VectorDI<T>*)imr.bdip)->vec;
	    iter_vec_2_vec_structcopy(&lhs_iter, &rhs_data, &scan, ss);
	} else {
	    IA_DIVIter<T>	rhs_iter(imr);
	    iter_iter_2_vec_structcopy(&lhs_iter, &rhs_iter, &scan, ss);
	}
    }

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

//
//
//

template <class T>
IA_DiscreteImage<T> IA_DiscreteImage<T>::xlated(const IA_IntPoint &p) const
{
    return bdip->xlated_by(p);
}
//
//
//

template <class T>
IA_ValueSet<T> IA_DiscreteImage<T>::range() const
{
#if 1
    return bdip->range();
#else
    unsigned	sz;
    T	*vec = bdip->range(&sz);
    IA_ValueSet<T>	rval(vec,sz);
    delete[] vec;
    return rval;
#endif
}

template <class T>
T IA_DiscreteImage<T>::reduce(T (*gamma)(const T&, const T&), T identity) const
//
// Reduces *this with function gamma.
//
{
    T result(identity), new_value;

    if (this->card()>0) {
	IA_DIVIter<T> iter(*this);

	iter(result);
	while(iter(new_value)) {
	    result = gamma( result, new_value);
	}
    }
    return result;
}

template <class T>
T IA_DiscreteImage<T>::reduce(T (*gamma) (T, T), T identity) const
//
// Reduces *this with function gamma.
//
{
    T result(identity), new_value;

    if (this->card()>0) {
	IA_DIVIter<T> iter(*this);

	iter(result);
	while(iter(new_value)) {
	    result = gamma( result, new_value);
	}
    }
    return result;
}


template <class T>
ostream& operator <<(ostream& o, const IA_DiscreteImage<T> &im)
{
    return o << *(im.bdip);
}

//
//
//

inline int slurpint(istream &is) {
    int	k;
    is.read((char*)&k, 4);
    return ntohl(k);
}

template <class T>
IA_DiscreteImage<T> IA_DiscreteImage<T>::read_IAA(istream &header,
						      istream &values)
{
    // start parsing the header

    if ( ! ( header.get() == 0x61 &&
	     header.get() == 0x69 &&
	     header.get() == 0x41 &&
	     header.get() == 0x49) ) {
	// format error;
	ia_throw(IA::IAAIO_FORMAT_ERROR, __FILE__, __LINE__);
	return IA_DiscreteImage<T>();
    }

    // this is all ugly.  The IAA image file spec is not specced.
    //  We should probably talk about network byte order and specify the
    // sizes of the fields.

    int	k;
    k = slurpint(header);
    switch (k) {
    case 1:
	break;
    default:
	// wrong version of the file format
	ia_throw(IA::IAAIO_FORMAT_ERROR, __FILE__, __LINE__);
	return IA_DiscreteImage<T>();
    }

    k = slurpint(header);	// bits per value
    if (k!=8*sizeof(T)) {
	// wrong sort.
	ia_throw(IA::TYPE_MISMATCH, __FILE__, __LINE__);
	return IA_DiscreteImage<T>();
    }

    header.seekg(5*4, ios::cur); // skip reserved bytes

    const int nheadelem = slurpint(header);
    const unsigned valsoffset = slurpint(header);
    const int dim = slurpint(header);
    const int code = slurpint(header);
    IA_IntPointSet	domain;
    switch (code) {
    case 0:
	domain = IA_BlackHole(dim);
	// how do we handle the rest of the header?
	return IA_DiscreteImage<T>(domain, (T)0);
	break;
    case 1:
	{
	    int	*inf = new int[dim];
	    int	*sup = new int[dim];
	    for (k=0; k<dim; k++)
		inf[k] = slurpint(header);
	    for (k=0; k<dim; k++)
		sup[k] = slurpint(header);
	    domain = IA_IntPointSet(IA_IntPoint(inf, dim, 1),
				    IA_IntPoint(sup, dim, 1));
	}
	break;
    default:
	// pure or impure interval?
	// abort(); // throw
	ia_throw(IA::IAAIO_FORMAT_ERROR, __FILE__, __LINE__);
	return IA_DiscreteImage<T>();
    }

    const int card = slurpint(header);

    if (card != domain.card()) {
	// file consistency error
	// abort(); throw
	ia_throw(IA::IAAIO_FORMAT_ERROR, __FILE__, __LINE__);
	return IA_DiscreteImage<T>();
    }

    if (!header) {
	// error somewhere in the reading process
	ia_throw(IA::IAAIO_FORMAT_ERROR, __FILE__, __LINE__);
	return IA_DiscreteImage<T>();
    }

    T	*valvec = new T[card];
    values.read((char*)valvec, card * sizeof(T));

    return IA_DiscreteImage<T>(domain, valvec, card, 1);
}

template <class T>
IA_DiscreteImage<T> IA_DiscreteImage<T>::read_IAA(const char *fname1,
						      const char *fname2)
{
    ifstream header(fname1), values(fname2);
    return read_IAA(header, values);
}

template <class T>
IA_DiscreteImage<T> IA_DiscreteImage<T>::read_IAA(const char *fname)
{
    // create some istreams
    char	*temp = new char[strlen(fname)+5];
    strcpy(temp, fname);
    strcat(temp, ".iaa1");
    ifstream	header(temp);
    strcpy(temp, fname);
    strcat(temp, ".iaa2");
    ifstream	values(temp);
    delete [] temp;

    return read_IAA(header, values);
}

//
//
//


inline void spewint(ostream &is, int i) {
    int	k = htonl(i);
    is.write((char*)&k, 4);
}

template <class T>
void IA_DiscreteImage<T>::write_IAA(ostream &header, ostream &values) const
{
    header.put(0x61);		// magic number
    header.put(0x69);
    header.put(0x41);
    header.put(0x49);

    spewint(header, 1);		// version
    spewint(header, 8*sizeof(T)); // bits per value

    spewint(header, 0);		// reserved
    spewint(header, 0);
    spewint(header, 0);
    spewint(header, 0);
    spewint(header, 0);

    spewint(header, 18);	// how do we compute this?

    spewint(header, 1);		// data offset

    const int dim = domain().dim();
    spewint(header, dim);
    if (domain().empty()) {
	// this stuff is probably wrong
	spewint(header, 0);
	spewint(header, 0); // cardinality
	// we\'re done
    } else if (domain().boxy()) {
	spewint(header, 1);
	int	k;
	IA_IntPoint	p;

	p=domain().inf();
	for (k=0; k<dim; k++)
	    spewint(header, p[k]);

	p=domain().sup();
	for (k=0; k<dim; k++)
	    spewint(header, p[k]);

	const int card=domain().card();
	spewint(header, card);

	values.write((const char*)value_array().data_start(), card*sizeof(T));

    } else {
	ia_throw(IA::IAAIO_FORMAT_ERROR, __FILE__, __LINE__);
	abort(); // unhandled domain type
    }

}

template <class T>
void IA_DiscreteImage<T>::write_IAA(const char *fname1, const char *fname2)
    const
{
    ofstream header(fname1), values(fname2);
    write_IAA(header, values);
}

template <class T>
void IA_DiscreteImage<T>::write_IAA(const char *fname) const
{
    // create some ostreams
    char	*temp = new char[strlen(fname)+6];
    strcpy(temp, fname);
    strcat(temp, ".iaa1");
    ofstream	header(temp);
    strcpy(temp, fname);
    strcat(temp, ".iaa2");
    ofstream	values(temp);
    delete [] temp;

    write_IAA(header, values);
}


//
//
//

class IA_PPCompositionIPS: public IA_PSPred<IA_IntPoint> {
    IA_IntPoint	(*f)(const IA_IntPoint&);
    IA_IntPointSet	base;
  public:
    IA_PPCompositionIPS(IA_IntPoint (*f_)(const IA_IntPoint&),
			const IA_IntPointSet &base_)
    :IA_PSPred<IA_IntPoint>(base_.dim()), f(f_), base(base_) {
    }
    IA_PSPred<IA_IntPoint> *clone_self() const {
	return new IA_PPCompositionIPS(*this);
    }
    int contains(const IA_IntPoint &ip) const {
	// Uglier than Rosanne bug
	IA_IntPoint (*f2)(const IA_IntPoint&) = f;
	return base.contains(f2(ip));
    }
};

template <class T>
class IA_PPCompositionDI: public IA_OtherDI<T> {
    IA_IntPoint	(*f)(const IA_IntPoint&);
    IA_DiscreteImage<T>	im;
  public:
    IA_PPCompositionDI( IA_IntPoint (*f_)(const IA_IntPoint&),
		       const IA_DiscreteImage<T> &im_)
    :IA_OtherDI<T>(IA_PPCompositionIPS(f_, im_.domain())), f(f_), im(im_) {
    }
    T operator()(const IA_IntPoint&p) const {
	IA_IntPoint (*f2)(const IA_IntPoint &) = f;
	return im(f2(p));
    }
    IA_OtherDI<T>* clone_self() const {
	return new IA_PPCompositionDI<T>(*this);
    }
#if 0
    T *range(unsigned *n) const {
	return im.range(n);
    }
#endif
};

template <class T>
IA_DiscreteImage<T> compose(const IA_DiscreteImage<T> &i,
			    IA_IntPoint (*f)(const IA_IntPoint&))
{
    return IA_PPCompositionDI<T>(f, i);
}

//
//
//


class IA_PPCompClosureIPS: public IA_PSPred<IA_IntPoint> {
    IA_PPCompClosure<IA_IntPoint, IA_IntPoint> *f;
    IA_IntPointSet	base;
  public:
    IA_PPCompClosureIPS( const IA_PPCompClosure<IA_IntPoint, IA_IntPoint> &f_,
			const IA_IntPointSet &base_)
    :IA_PSPred<IA_IntPoint>(base_.dim()), f(f_.clone_self()), base(base_) {
    }
    IA_PPCompClosureIPS(const IA_PPCompClosureIPS &other)
    :IA_PSPred<IA_IntPoint>(other.base.dim()), f(other.f->clone_self()),
     base(other.base) {
    }
    ~IA_PPCompClosureIPS() { delete f; }

    IA_PSPred<IA_IntPoint> *clone_self() const {
	return new IA_PPCompClosureIPS(*this);
    }
    int contains(const IA_IntPoint &ip) const {
	return base.contains((*f)(ip));
    }
};

template <class T>
class IA_PPCompClosureDI: public IA_OtherDI<T> {
    IA_PPCompClosure<IA_IntPoint, IA_IntPoint> *f;
    IA_DiscreteImage<T>	im;
  public:
    IA_PPCompClosureDI( const IA_PPCompClosure<IA_IntPoint, IA_IntPoint> &f_,
		       const IA_DiscreteImage<T> &im_)
    :IA_OtherDI<T>(IA_PPCompClosureIPS(f_, im_.domain())),
     f(f_.clone_self()), im(im_) {
    }
    IA_PPCompClosureDI(const IA_PPCompClosureDI &other) 
    :IA_OtherDI<T>(IA_PPCompClosureIPS(*other.f, other.im.domain())),
     f(other.f->clone_self()), im(other.im) { }
    ~IA_PPCompClosureDI() { delete f; }

    T operator()(const IA_IntPoint&p) const {
	return im((*f)(p));
    }
    IA_OtherDI<T>* clone_self() const {
	return new IA_PPCompClosureDI<T>(*this);
    }
#if 0
    T *range(unsigned *n) const {
	return im.range(n);
    }
#endif
};


template <class T>
IA_DiscreteImage<T> compose
(const IA_DiscreteImage<T>& im,
 const IA_PPCompClosure<IA_IntPoint, IA_IntPoint> &f)
{
    return IA_PPCompClosureDI<T>(f, im);
}

//
//
//

template <class T>
IA_DiscreteImage<T> compose(T (*f)(T), const IA_DiscreteImage<T> &i)
{
    IA_DIVIter<T>	iter(i);
    const int size = i.card();
    T * const vals = new T[size];

    {
	T	*scan=vals;
	T	temp;
	while (iter(temp))
	    *(scan++) = f(temp);
    }

    return IA_DiscreteImage<T>(i.domain(), vals, size, 1);
}

template <class S,class T>
IA_DiscreteImage<S> compose(S (*f)(T), const IA_DiscreteImage<T> &i, const S*)
{
    IA_DIVIter<T>	iter(i);
    const int size = i.card();
    S * const vals = new S[size];

    {
	S	*scan=vals;
	T	temp;
	while (iter(temp))
	    *(scan++) = f(temp);
    }

    return IA_DiscreteImage<S>(i.domain(), vals, size, 1);
}

template <class R, class S, class T>
IA_DiscreteImage<R> compose(R (*f)(S), const IA_DiscreteImage<T> &i, const R*, const S*)
{
    IA_DIVIter<T>	iter(i);
    const int size = i.card();
    R * const vals = new R[size];

    {
	R	*scan=vals;
	T	temp;
	while (iter(temp))
	    *(scan++) = f(temp);
    }

    return IA_DiscreteImage<R>(i.domain(), vals, size, 1);
}

template <class Q, class R, class S, class T>
IA_DiscreteImage<Q> compose(R (*f)(S), const IA_DiscreteImage<T> &i, const Q*, const R*, const S*)
{
    IA_DIVIter<T>	iter(i);
    const int size = i.card();
    Q * const vals = new Q[size];

    {
	Q	*scan=vals;
	T	temp;
	while (iter(temp))
	    *(scan++) = f(temp);
    }

    return IA_DiscreteImage<Q>(i.domain(), vals, size, 1);
}
@


1.13
log
@Copyright Notices
@
text
@d9 1
a9 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.12 93/05/26 16:59:56 thoth Exp Locker: thoth $";
d12 3
d880 3
a882 1
	return base.contains(f(ip));
d896 2
a897 1
	return im(f(p));
@


1.12
log
@Read and write of IAA image files.
@
text
@d3 4
a6 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.11 93/05/18 21:39:00 thoth Exp Locker: thoth $";
d8 3
d12 3
@


1.11
log
@BaseDI range method returns ValueSet again.
New Point-Point composition closure object.
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.10 93/04/29 11:18:38 thoth Exp Locker: thoth $";
d6 4
d54 2
d644 212
d1001 34
@


1.10
log
@Support for point-point-function and image composition.
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.9 93/04/08 13:10:49 thoth Exp Locker: thoth $";
d6 3
d578 3
d586 1
d681 102
@


1.9
log
@removed cruft.
restriction is now a virtual method of the BaseDI.  We don't
need that goofy case statement any more.
translation is also a virtual method.
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.8 93/03/10 13:32:36 thoth Exp Locker: thoth $";
d6 6
d49 2
d64 2
d627 48
@


1.8
log
@range method no longer returns valueset due to
difficulties with template implementation.
FunctionDI constructor was not truly generic.
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.7 93/02/23 14:10:14 thoth Exp Locker: thoth $";
d6 5
a58 2
template <class T>
void restrict_copy(T*&, IA_DIVIter<T>&, IA_SetStructure&);
a60 3
void extend_copy(T*&, IA_DIVIter<T>&, IA_DIVIter<T>&, IA_SetStructure);

template <class T>
a253 4
//
// The following set of functions implements image restriction
//

a254 96
void IA_DiscreteImage<T>::vec_2_vec_structcopy
(const T** source_vec, T** dest_vec, const IA_SetStructure &ss)
//
// Copies values provided by the source vector into the
// vector pointed at by dest_vec according to the SetStructure ss.
//
// *source_vec	  MODIFIED
// *dest_vec	  MODIFIED
// ss		UNmodified
//
{
    int i,j;

    // for each interval in the current set structure, do the appropriate
    //	copying.
    for(i=0; i<ss.nintervals(); i++){
	const IA_ss_interval &ssi = ss.retrieve_interval(i);

	if (ssi.substructure == IA_SetStructure::BOTH) {
	    // These pixels are in the intersection -- copy them!
	    for(j=0; j < ssi.count; j++)
		*((*dest_vec)++) = *((*source_vec)++);

	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    // These pixels aren\'t in the intersection -- skip them!
	    (*source_vec) += ssi.count;

	} else if (ssi.substructure != IA_SetStructure::SECOND_ONLY) {
	    // Make recursive calls on complicated structure
	    for(j=0; j<ssi.count; j++)
		vec_2_vec_structcopy(source_vec, dest_vec, ssi.substructure);

	} else { // ssi.substructure == IA_SetStructure::SECOND_ONLY
	    // These points aren\'t in the image being restricted
	}
    }
}

template <class T>
void IA_DiscreteImage<T>::iter_2_vec_structcopy
(
#ifdef FUNKY_ERROR
 void *source_v,
#else
 IA_DIVIter<T> *source_iter,
#endif
 T** result_vec, const IA_SetStructure &ss)
//
// Copies values provided by the source iterator (source_iter) into the
// vector pointed at by result_vec according to the SetStructure ss.
//
// *source_iter	  MODIFIED
// *result_vec	  MODIFIED
// ss		UNmodified
//
{
#ifdef FUNKY_ERROR
    IA_DIVIter<T>	*source_iter = (IA_DIVIter<T> *)source_v;
#endif
    T value;
    int j;

    // for each interval in the current set structure, do the appropriate
    //	copying.
    for(int i = 0; i < ss.nintervals(); i++){
	IA_ss_interval ssi = ss.retrieve_interval(i);
	if (ssi.substructure == IA_SetStructure::BOTH) {
	    // These pixels are in the intersection -- copy them!
	    for(j=0; j < ssi.count; j++){
		if (!(*source_iter)(value)){
		    // didn\'t get enough values from iterator.
		    abort(); // internal error
		}
		*((*result_vec)++) = value;
	    }
	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    // These pixels aren\'t in the intersection -- skip them!
	    for(j=0; j < ssi.count; j++){
		if (!(*source_iter)(value)) {
		    // didn\'t get enough values from iterator.
		    abort(); // internal error
		}
	    }
	} else if (ssi.substructure != IA_SetStructure::SECOND_ONLY) {
	    // Make recursive calls on complicated structure
	    for(j=0; j<ssi.count; j++){
		iter_2_vec_structcopy(source_iter, result_vec,
				      ssi.substructure);
	    }
	} else { // ssi.substructure == IA_SetStructure::SECOND_ONLY
	    // These points aren\'t in the image being restricted
	}
    }
}

template <class T>
a256 5
//
// Return the restriction of *this to PointSet ips
//
// ips		UNmodified
//
d258 5
a262 33
    if (this->type()==IA_ConstDI<T>::s_type()) {
	const IA_ConstDI<T>	*temp = (IA_ConstDI<T> *)this->bdip;
	// Real easy to restrict one of these.  It\'s another
	// constant image with a different domain.
	return IA_DiscreteImage<T>(this->domain() & ips, temp->value);
    }

    if (!this->domain().extensivep()) {
	// We really need a LazyRestrictionDI

	// Actually, if ips were extensive, we could compute a result.
	// I just don\'t feel like writing the code right now.

	ia_throw( IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
	return IA_DiscreteImage<T>();
    }

    IA_SetStructure	ss;
    IA_IntPointSet	result_domain =
	intersect_with_structure(this->domain(), ips, &ss);
    const unsigned	sz = result_domain.card();
    T * const	dest = new T[sz];

    if (this->type()==IA_VectorDI<T>::s_type()) {
	const T	*src = ((const IA_VectorDI<T> *)this->bdip)->vec;
	T	*scan = dest;
	vec_2_vec_structcopy(&src,&scan,ss);
    } else {
	IA_DIVIter<T>	iter(*this);
	T	*scan = dest;
	iter_2_vec_structcopy(&iter,&scan,ss);
    }
    return IA_DiscreteImage<T>(result_domain, dest, sz, 1);
a264 1

d272 1
a272 1

d276 1
a276 1

d291 1
a291 1

d295 1
a295 1

d297 1
a297 1

d549 9
@


1.7
log
@set_and_reference_image method encodes common initialization semantics.
User-defined OtherDIs are now supported.
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.6 93/02/20 12:55:06 thoth Exp Locker: thoth $";
d6 4
d184 1
a184 1
				      int (*f)(const IA_IntPoint&))
d687 9
@


1.6
log
@Function images are no longer supported.
ErrorDIs are created dynamically as needed.
This is conceptually convenient.
The pointset should go first in an image constructor.
Vector constructors now can give away the value vector.
Image restriction and extension should be fast now.  I can't
be certain they work though...
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.5 93/02/17 11:00:18 thoth Exp Locker: thoth $";
d6 9
d33 2
d37 1
a37 5
#include "ConstDI.h"
#include "VectorDI.h"
//#include "FunctionDI.h"
//#include "FunctionRefDI.h"
#include "LazyDI.h"
d40 1
a40 1
#include "SetStructure.h"
d42 4
d57 7
d86 1
a86 2
    bdip = new IA_ErrorDI<T>;
    bdip->incr_ref();
d98 1
a98 2
    bdip = im.bdip;
    bdip->incr_ref();
d110 1
a110 2
    this->bdip = (IA_BaseDI<T> *)new IA_ConstDI<T>(p, value);
    this->bdip->incr_ref();
d137 2
a139 3
    this->bdip = (IA_BaseDI<T> *)new IA_VectorDI<T>(p, values, sz, giveaway);
    this->bdip->incr_ref();
}
d167 1
a167 2
    this->bdip = (IA_BaseDI<T> *)new IA_VectorDI<T>(p, (T*)values, sz, 0);
    this->bdip->incr_ref();
a169 1
#if 0
d171 3
a173 11
IA_DiscreteImage<T>::IA_DiscreteImage(T (*vfunc)(const IA_IntPoint&),
				      const IA_IntPointSet& p)
//
// Function (with reference argument) image ctor
//
// Given function vfunc (mapping IntPoints into values in T), and
//	IntPointSet p, this yields an image with point set p,
//	associating value vfunc(x) with each point x in p.
//
// p		UNmodified
//
d175 1
a175 2
    this->bdip = (IA_BaseDI<T> *) new IA_FunctionRefDI<T>(vfunc, p);
    this->bdip->incr_ref();
d179 4
a182 11
IA_DiscreteImage<T>::IA_DiscreteImage(T (*vfunc)(IA_IntPoint),
				      const IA_IntPointSet& p)
//
// Function (with value argument) image ctor
//
// Given function vfunc (mapping IntPoints into values in T), and
//	IntPointSet p, this yields an image with point set p,
//	associating value vfunc(x) with each point x in p.
//
// p		UNmodified
//
d184 1
a184 2
    this->bdip = (IA_BaseDI<T> *)new IA_FunctionDI<T>( vfunc, p);
    this->bdip->incr_ref();
a185 1
#endif
d218 1
a218 2
    this->bdip = (IA_BaseDI<T> *) new IA_ConstDI<T>(pset, value);
    this->bdip->incr_ref();
d240 2
a241 2
	IA_BaseDI<T> *temp = this->bdip->clone_self_extensively();
	temp->incr_ref();		// someone points at the image now
d243 2
a244 1
	this->bdip = temp;
a394 2


a628 8
#if 0
template <class T>
void extend_copy(T*& result_vec,
		 IA_DIVIter<T>& left_iter, IA_DIVIter<T>& right_iter,
		 IA_SetStructure ss)
{
    T value;
    int j;
a629 10
    for(int i = 0; i < ss.nintervals(); i++){
	IA_ss_interval ssi = ss.retrieve_interval(i);
	if (ssi.substructure == IA_SetStructure::BOTH) {
	    for(j=0; j<ssi.count; j++){
		if (!left_iter(value)){
		    // Bad internal error
		    abort();
		} else {
		    // copy the value
		    *result_vec++ = value;
a630 36
		    // skip the same value in the right argument
		    if (!right_iter(value)) {
			// Another Bad internal error
			abort();
		    };
		}
	    }
	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    for(j=0; j<ssi.count; j++){
		if (!left_iter(value)){
		    // Bad internal error
		    abort();
		} else {
		    // copy the value
		    *result_vec++ = value;
		}
	    }
	} else if (ssi.substructure == IA_SetStructure::SECOND_ONLY) {
	    for(j=0; j<ssi.count; j++){
		if (!right_iter(value)){
		    // Bad internal error
		    abort();
		} else {
		    // copy the value
		    *result_vec++ = value;
		}
	    }
	} else {
	    for(j=0; j<ssi.count; j++){
		extend_copy(result_vec, left_iter, right_iter, ssi.substructure);
	    }
	}
    }
}
#endif

d724 1
a724 1
ostream& operator <<(ostream& o, IA_DiscreteImage<T> im)
@


1.5
log
@We now have the ability to give away the value vector.
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.4 93/02/08 12:57:57 thoth Exp Locker: thoth $";
d6 3
d23 1
d25 1
d28 2
a29 2
#include "FunctionDI.h"
#include "FunctionRefDI.h"
d55 1
a55 1
    this->bdip = (IA_BaseDI<T> *) &errorDI;
d60 1
d66 7
a80 7
#if 0
    IA_BaseDI<T> *temp;

    temp = im.bdip;
    im.bdip->incr_ref();
    this->bdip = temp;
#else
a82 1
#endif
d86 1
a86 1
IA_DiscreteImage<T>::IA_DiscreteImage(const T& value, const IA_IntPointSet& p)
d94 1
a94 1
    this->bdip = (IA_BaseDI<T> *)new IA_ConstDI<T>(value, p);
d99 1
a99 1
IA_DiscreteImage<T>::IA_DiscreteImage(T *values, const IA_IntPointSet& p,
d106 2
a107 1
//	iteration order of points p.
d111 5
a115 7
    if (p.extensivep()){
	this->bdip = (IA_BaseDI<T> *)new IA_VectorDI<T>(values, p, sz,
							giveaway);
	this->bdip->incr_ref();
    } else {
	ia_throw( IA::IMAGE_STRUCTURE_NOT_SUPPORTED
	      , __FILE__, __LINE__);
d117 8
d127 2
a128 2
IA_DiscreteImage<T>::IA_DiscreteImage(T *values, const IA_IntPointSet& p,
				      unsigned sz)
d138 3
a140 4
    if (p.extensivep()){
	this->bdip = (IA_BaseDI<T> *)new IA_VectorDI<T>(values, p, sz,0);
	this->bdip->incr_ref();
    } else {
d143 1
d145 10
d157 1
d191 1
d194 2
a195 2
IA_DiscreteImage<T>& IA_DiscreteImage<T>::operator=(const IA_DiscreteImage<T>&
						    im)
d203 2
a204 1
    IA_BaseDI<T> *temp;
a205 2
    temp = im.bdip;
    temp->incr_ref();
d207 1
d224 1
a224 1
    this->bdip = (IA_BaseDI<T> *) new IA_ConstDI<T>(value, pset);
d232 3
a234 1
// 
d237 3
d249 1
a249 1
	this->disassociate_image();	// We don't need this anymore.
d251 1
a251 1
	}
d256 4
d261 2
a262 2
void restrict_copy(T*& result_vec, IA_DIVIter<T> &source_iter,
		   IA_SetStructure &ss)
d264 45
d312 2
a313 1
// result_vec	  MODIFIED
d317 3
d330 1
a330 1
		if (!source_iter(value)){
d332 1
a332 2
		    // Bad internal error
		    abort();
d334 1
a334 1
		*result_vec++ = value;
d339 1
a339 1
		if (!source_iter(value)) {
d341 1
a341 2
		    // Another Bad internal error
		    abort();
d347 2
a348 1
		restrict_copy(result_vec, source_iter, ssi.substructure);
d357 1
a357 1
IA_DiscreteImage<T>& IA_DiscreteImage<T>::restrict(const IA_IntPointSet& ips)
d365 6
a370 2
    IA_SetStructure ss;
    if(this->domain().extensivep() || ips.extensivep()) {
d372 2
a373 3
	// find the structure of the intersection
	IA_IntPointSet newps(intersect_with_structure(this->domain(),
						      ips, &ss));
d375 2
a376 2
	// allocate storage for the new image\'s values
	T *result_vec_loc, *result_vec = new T [ newps.card()];
d378 3
a380 3
	// get an iterator for the current image values
	IA_DIVIter<T> this_iter(*this);
	T v;
d382 5
a386 3
	// store the result image\'s value vector location (it\'s modified
	//	by restrict_copy)
	result_vec_loc = result_vec;
d388 4
a391 8
	// copy the appropriate image values to the result vector
	restrict_copy(result_vec, this_iter, ss);

	// return the new result image that is made by giving the value
	// vector away to the VectorDI ctor
	return * new IA_DiscreteImage<T>(
	    (IA_BaseDI<T>*) new IA_VectorDI<T>(result_vec_loc, newps,
					       newps.card(), 1));
d393 3
a395 1
	ia_throw( IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
d397 1
d404 1
a404 1
IA_DiscreteImage<T>& IA_DiscreteImage<T>::restrict(const IA_ValueSet<T>& vs)
d407 3
a409 3
    IA_DiscreteImage<T> *result;
    IA_IntPoint *point_vec = new IA_IntPoint[this->domain().card()];
    T *value_vec = new T[this->domain().card()];
d411 3
a413 5
    if(this->domain().extensivep()) {
	IA_DIPIter<T> iter(*this);
	IA_IntPoint point;
	T value;
	int i=0;
d415 47
a461 6
	// Copy all points in *this\'s domain that have values in the argument
	// ValueSet.
	while(iter(point,value)){
	    if (vs.contains(value)){
		value_vec[i] = value;
		point_vec[i++] = point;
d463 13
d477 2
d480 48
a527 7
	IA_BaseDI<T> *ba_result =
	    new IA_VectorDI<T>( value_vec,IA_IntPointSet(this->domain().dim(), 
							 point_vec, i), i, 1);
	delete point_vec;
	result = new IA_DiscreteImage<T>(ba_result);
    } else {
	ia_throw( IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
a528 1
    return *result;
d532 107
d691 1
d694 2
a695 2
IA_DiscreteImage<T>& IA_DiscreteImage<T>::extend(const IA_DiscreteImage<T>&
						    imr)  const
d702 6
d709 5
a713 2
    if(this->domain().extensivep() && imr.domain().extensivep()) {
	IA_DIVIter<T> this_iter(*this), arg_iter(imr);
d715 3
a717 3
	IA_IntPointSet newps (union_with_structure(this->domain(),
						   imr.domain(), &ss));
	T *result_vec_loc, *result_vec = new T [newps.card()];
d719 9
a727 3
	result_vec_loc = result_vec;
	
	extend_copy(result_vec, this_iter, arg_iter, ss);
d729 7
a735 5
	return * new IA_DiscreteImage<T>(
	    (IA_BaseDI<T>*) new IA_VectorDI<T>(result_vec_loc, newps,
					       newps.card(), 1));
    } else {
	ia_throw( IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
d737 2
d740 4
@


1.4
log
@virtual destructor is now outlined.
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.3 93/01/19 14:56:03 jnw Exp Locker: thoth $";
d6 3
d95 1
a95 1
				      int sz)
d106 2
a107 1
	this->bdip = (IA_BaseDI<T> *)new IA_VectorDI<T>(values, p, sz, 0);
d114 20
d276 1
a276 1
IA_DiscreteImage<T>& IA_DiscreteImage<T>::operator&(const IA_IntPointSet& ips)
d319 1
a319 1
IA_DiscreteImage<T>& IA_DiscreteImage<T>::operator &(const IA_ValueSet<T>& vs)
d407 1
a407 1
IA_DiscreteImage<T>& IA_DiscreteImage<T>::operator|(const IA_DiscreteImage<T>&
@


1.3
log
@Modified to support IA_ naming convention
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.2 92/11/12 16:59:09 jnw Exp Locker: jnw $";
d6 3
d26 1
d28 2
a30 1

d51 6
d65 1
d71 4
@


1.2
log
@Added restriction, extension, iteration, etc.
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id: DiscreteImage.c,v 1.1 92/10/05 11:42:42 jnw Exp Locker: jnw $";
d6 3
d27 1
a27 1
void restrict_copy(T*&, DIVIter<T>&, SetStructure&);
d30 1
a30 1
void extend_copy(T*&, DIVIter<T>&, DIVIter<T>&, SetStructure);
d33 1
a33 1
void DiscreteImage<T>::disassociate_image()
d42 1
a42 1
    this->bdip = (BaseDI<T> *) &errorDI;
d46 1
a46 1
DiscreteImage<T>::DiscreteImage(const DiscreteImage<T>& im)
d54 1
a54 1
    BaseDI<T> *temp;
d62 1
a62 1
DiscreteImage<T>::DiscreteImage(const T& value, const IntPointSet& p)
d70 1
a70 1
    this->bdip = (BaseDI<T> *)new ConstDI<T>(value, p);
d75 2
a76 1
DiscreteImage<T>::DiscreteImage(T *values, const IntPointSet& p, int sz)
d87 1
a87 1
	this->bdip = (BaseDI<T> *)new VectorDI<T>(values, p, sz, 0);
d96 2
a97 2
DiscreteImage<T>::DiscreteImage(T (*vfunc)(const IntPoint&),
				const IntPointSet& p)
d108 1
a108 1
    this->bdip = (BaseDI<T> *) new FunctionRefDI<T>(vfunc, p);
d113 2
a114 2
DiscreteImage<T>::DiscreteImage(T (*vfunc)(IntPoint),
				const IntPointSet& p)
d125 1
a125 1
    this->bdip = (BaseDI<T> *)new FunctionDI<T>( vfunc, p);
d130 2
a131 1
DiscreteImage<T>& DiscreteImage<T>::operator =(const DiscreteImage<T>& im)
d139 1
a139 1
    BaseDI<T> *temp;
d150 1
a150 1
DiscreteImage<T>& DiscreteImage<T>::operator =(const T& value)
d157 1
a157 1
    IntPointSet pset;
d160 1
a160 1
    this->bdip = (BaseDI<T> *) new ConstDI<T>(value, pset);
d166 1
a166 1
T& DiscreteImage<T>::operator [](const IntPoint& p)
d178 1
a178 1
	BaseDI<T> *temp = this->bdip->clone_self_extensively();
d188 2
a189 2
void restrict_copy(T*& result_vec, DIVIter<T> &source_iter,
		   SetStructure &ss)
d204 2
a205 2
	ss_interval ssi = ss.retrieve_interval(i);
	if (ssi.substructure == SetStructure::BOTH) {
d215 1
a215 1
	} else if (ssi.substructure == SetStructure::FIRST_ONLY) {
d224 1
a224 1
	} else if (ssi.substructure != SetStructure::SECOND_ONLY) {
d229 1
a229 1
	} else { // ssi.substructure == SetStructure::SECOND_ONLY
d236 2
a237 1
DiscreteImage<T>& DiscreteImage<T>::operator &( const IntPointSet& ips) const
d244 1
a244 1
    SetStructure ss;
d248 2
a249 1
	IntPointSet newps(intersect_with_structure(this->domain(), ips, &ss));
d255 1
a255 1
	DIVIter<T> this_iter(*this);
d267 3
a269 3
	return * new DiscreteImage<T>(
	    (BaseDI<T>*) new VectorDI<T>(result_vec_loc, newps,
					 newps.card(), 1));
d279 2
a280 1
DiscreteImage<T>& DiscreteImage<T>::operator &( const ValueSet<T>& vs) const
d282 2
a283 2
    DiscreteImage<T> *result;
    IntPoint *point_vec = new IntPoint[this->domain().card()];
d287 2
a288 2
	DIPIter<T> iter(*this);
	IntPoint point;
d301 3
a303 3
	BaseDI<T> *ba_result =
	    new VectorDI<T>( value_vec,IntPointSet(this->domain().dim(), 
						      point_vec, i), i, 1);
d305 1
a305 1
	result = new DiscreteImage<T>(ba_result);
d314 2
a315 2
		 DIVIter<T>& left_iter, DIVIter<T>& right_iter,
		 SetStructure ss)
d321 2
a322 2
	ss_interval ssi = ss.retrieve_interval(i);
	if (ssi.substructure == SetStructure::BOTH) {
d338 1
a338 1
	} else if (ssi.substructure == SetStructure::FIRST_ONLY) {
d348 1
a348 1
	} else if (ssi.substructure == SetStructure::SECOND_ONLY) {
d367 2
a368 2
DiscreteImage<T>& DiscreteImage<T>::operator |( const DiscreteImage<T>& imr)
    const
d375 1
a375 1
    SetStructure ss;
d377 1
a377 1
	DIVIter<T> this_iter(*this), arg_iter(imr);
d379 2
a380 2
	IntPointSet newps (union_with_structure(this->domain(), imr.domain(),
						&ss));
d387 3
a389 3
	return * new DiscreteImage<T>(
	    (BaseDI<T>*) new VectorDI<T>(result_vec_loc, newps, newps.card(),
					 1));
d397 1
a397 1
T DiscreteImage<T>::reduce(T (*gamma)(const T&, const T&), T identity) const
d405 1
a405 1
	DIVIter<T> iter(*this);
d416 1
a416 1
T DiscreteImage<T>::reduce(T (*gamma) (T, T), T identity) const
d424 1
a424 1
	DIVIter<T> iter(*this);
d436 1
a436 1
ostream& operator <<(ostream& o, DiscreteImage<T> im)
@


1.1
log
@Initial revision
@
text
@d3 1
a3 1
static char DiscreteImagercsid[] = "$Id$";
d5 4
a8 1
// $Log$
d17 3
a19 1
#include "DIIter.h"
d21 2
d24 6
d31 4
d44 6
d60 6
d73 8
d94 9
d111 9
d127 6
d146 5
d162 3
d181 1
d183 9
a191 1
DiscreteImage<T>& DiscreteImage<T>::operator &( const IntPointSet& ips) const
d193 2
a194 1
    DiscreteImage<T> *result;
d196 31
a226 5
    if(this->domain().extensivep() || ips.extensivep()) {
	// Need to write this hard code !
//	return this->bdip->iter_restrict(ips);
    } else {
	ia_throw( IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
a227 1
    return *result;
d231 6
a236 1
DiscreteImage<T>& DiscreteImage<T>::operator &( int (*fps)(IntPoint)) const
d238 2
a239 1
    DiscreteImage<T> *result;
d241 22
a262 3
    if(this->domain().extensivep()) {
	// Need to write this hard code !
//	return this->bdip->iter_restrict(ips);
a265 1
    return *result;
d268 3
d275 2
d279 19
a297 2
	// Need to write this hard code !
//	return this->bdip->iter_restrict( vs);
d305 54
d361 5
d367 3
a369 1
    DiscreteImage<T> *result;
d371 14
a384 4
    result = new DiscreteImage<T>;
    // Hmmm.... Probably need some code here.
    // 
    return *result;
d387 1
d389 4
a392 1
T DiscreteImage<T>::reduce(T (*gamma)(const T&, const T&), T identity)
a395 1
    cerr << "Reduce - image cardinality: " << this->card() << "\n";
d397 1
a397 1
	DIIter<T> iter(*this);
d408 4
a411 1
T DiscreteImage<T>::reduce(T (*gamma) (T, T), T identity)
d416 1
a416 1
	DIIter<T> iter(*this);
a422 1
    cerr.flush();
d426 1
d428 1
a428 1
ostream& operator <<(ostream&o, DiscreteImage<T> im)
d432 1
@
