head	1.10;
access;
symbols
	bobbase:1.10
	bob:1.10.1
	r2_1:1.10
	r2_0:1.9
	r1_1_beta:1.9
	r1_1_alpha:1.9
	r1_0:1.9
	r0_11:1.9
	r0_10:1.7
	r0_9:1.4;
locks
	thoth:1.10.1.2; strict;
comment	@// @;


1.10
date	94.09.16.14.57.11;	author thoth;	state Exp;
branches
	1.10.1.1;
next	1.9;

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

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

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

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

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

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

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

1.2
date	93.09.27.15.50.21;	author thoth;	state Exp;
branches;
next	1.1;

1.1
date	93.09.15.12.53.48;	author thoth;	state Exp;
branches;
next	;

1.10.1.1
date	94.12.28.15.47.07;	author thoth;	state Exp;
branches;
next	1.10.1.2;

1.10.1.2
date	95.01.13.19.37.42;	author thoth;	state Exp;
branches;
next	;


desc
@Image handle class implementation.
@


1.10
log
@more DOS-inspired renaming.
@
text
@// Emacs: -*- C++ -*-

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


//
// $Log: CoreImage.c,v $
// Revision 1.9  1994/03/14  15:48:33  thoth
// ValueSet has been replaced by container class Set.
//
// Revision 1.8  1994/02/26  16:02:08  thoth
// operator() of the container now relies upon the contained classes
// to check if p is contained in the domain.  This means that users
// could possibly write an erroneous operator().
//
// Revision 1.7  1994/01/31  15:40:44  thoth
// chi_contains and compositions have been moved into AuxImage.c.
//
// Revision 1.6  1994/01/07  15:10:00  thoth
// Image class is now CoreImage and named image types are
// Image<P,T>.
//
// Revision 1.5  1993/12/29  16:55:40  thoth
// Improved error handling.
// Pixel array constructor.
// pointarray valuearray constructor.
// Added FunctionI that accepts functions with simple T type instead of
// const T&.
// new chi_contains function.
//
// Revision 1.4  1993/11/17  18:12:59  thoth
// extensivep is now extensive
// translated is now translate.
//
// Revision 1.3  1993/10/05  19:33:08  thoth
// Move to new Closure naming convention.
//
// Revision 1.2  1993/09/27  15:50:21  thoth
// Some diagnostics for abort()s that need to be ia_throws.
// xlated is now translated.
//
// Revision 1.1  1993/09/15  12:53:48  thoth
// Initial revision
//

#include <iostream.h>
#include <string.h>

#include "Point.h"
#include "Set.h"
#include "SetStructure.h"
// if included here, DIIters screw up
//#include "ClosurePS.h"

#include "CoreImage.h"

//#include "LazyDI.h"

#include "ImageIter.h"
// #include "IPIter.h"

#include "ErrorI.h"
#include "ConstI.h"
#include "VectorI.h"
#include "ClosureI.h"
#include "FuncI.h"

#include "ClosurePS.h"

#include "image_errors.h"


template <class P,class T>
void IA_CoreImage<P,T>::set_and_reference_image(IA_BaseImage<P,T> *i)
{
    i->incr_ref();
    this->bip = i;
}

template < class P,class T>
void IA_CoreImage<P,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->bip->decr_ref() <= 0) {
	delete this->bip;
    }
    this->bip = 0;
}


//
//
//


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


template < class P,class T>
IA_CoreImage<P,T>::IA_CoreImage()
{
    set_and_reference_image(new IA_ErrorI<P,T>);
}


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


template < class P,class T>
IA_CoreImage<P,T>::IA_CoreImage(const IA_Set<P>& p, const T& value)
//
// Constant valued image ctor
//
// value	UNmodified
// p		UNmodified
//
{
    set_and_reference_image(new IA_ConstI<P,T>(p, value));
}


template < class P,class T>
IA_CoreImage<P,T>::IA_CoreImage(const IA_Set<P>& 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->bip=0;	// in case we throw

    if (!p.extensive()){
	ia_throw( IA::IMAGE_STRUCTURE_NOT_SUPPORTED, __FILE__, __LINE__);
	set_and_reference_image(new IA_ErrorI<P,T>);
	return;
    }

    if (sz != p.card()) {
	ia_throw(IA::IMAGE_VECTOR_CNSTR_SZMISMATCH, __FILE__, __LINE__);
	set_and_reference_image(new IA_ErrorI<P,T>);
	return;
    }
    set_and_reference_image(new IA_VectorI<P,T>(p, values, sz, giveaway));
}


template < class P,class T>
IA_CoreImage<P,T>::IA_CoreImage(const IA_Set<P>& 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->bip=0;	// in case we throw

    if (!p.extensive()){
	ia_throw( IA::IMAGE_STRUCTURE_NOT_SUPPORTED, __FILE__, __LINE__);
	set_and_reference_image(new IA_ErrorI<P,T>);
	return;
    }

    if (sz != p.card()) {
	cerr << "image vector constructor, pointset size and array size mismatch"<<endl;
	ia_throw(IA::IMAGE_VECTOR_CNSTR_SZMISMATCH, __FILE__, __LINE__);
	set_and_reference_image(new IA_ErrorI<P,T>);
	return;
    }

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


//
//
//

template < class P,class T>
IA_VectorI<P,T> *
IA_CoreImage<P,T>::sortedPixel_to_VectorI(const IA_Pixel<P,T> *pixels,
				      unsigned count)
{
    P * const	points = new P[count];
    T * const	vals = new T[count];
    for (int i=0; i<count; i++) {
	points[i] = pixels[i].point;
	vals[i] = pixels[i].value;
    }


    IA_Set<P>	ps(points[0].dim(), points, count);

    IA_VectorI<P,T> *	rval = new IA_VectorI<P,T>(ps, vals, count, 1);

    delete[] points;
    /* we've given the values away */

    return rval;
}

//
// constructor from Pixel arrays to images
//
template < class P,class T>
IA_CoreImage<P,T>::IA_CoreImage(const IA_Pixel<P,T> *pixels, unsigned count)
{
    // gotta check, dimensions, and what if they don't give us any pixels?
    // clean up later.

    IA_Pixel<P,T> * const	copy = new IA_Pixel<P,T>[count];
    for (int i=0; i<count; i++)
	copy[i] = pixels[i];

    qsort((char*)copy, count, sizeof(*copy), IA_Pixel<P,T>::vcompare);

    set_and_reference_image(sortedPixel_to_VectorI(copy, count));

    delete[] copy;
}


//
// constructor from an array of points with a corresponding array of values
//

template < class P,class T>
IA_CoreImage<P,T>::IA_CoreImage(const P *points, unsigned pcount,
			const T *values, unsigned vcount)
{
    if (pcount!=vcount)  {
	ia_throw(IA::IMAGE_VECTOR_CNSTR_SZMISMATCH, __FILE__, __LINE__);
	set_and_reference_image(new IA_ErrorI<P,T>);
	return;
    }

    if (pcount<1) {
	ia_throw(Image_PointsetTooSmall_Exception(__FILE__, __LINE__));
	set_and_reference_image(new IA_ErrorI<P,T>);
	return;
    }

    int	dim=points[0].dim();

    for (int i=1; i<pcount; i++)
	if (points[i].dim() != dim)
	    break;

    if (i<pcount) {
	ia_throw(IA::PSET_DIMENSION_MISMATCH, __FILE__, __LINE__);
	set_and_reference_image(new IA_ErrorI<P,T>);
	return;
    }

    for (i=0; i+1<pcount; i++)
	if (pointcmp(points[i], points[i+1])>=0)
	    break;		// if it\'s not strictly increasing

    if (i+1<pcount) {
	// the point array is not sorted
	IA_Pixel<P,T> * const	pixels = new IA_Pixel<P,T>[pcount];
	for (int i=0; i<pcount; i++) {
	    pixels[i].point = points[i];
	    pixels[i].value = values[i];
	}

	qsort((char*)pixels, pcount, sizeof(*pixels), IA_Pixel<P,T>::vcompare);

	set_and_reference_image(sortedPixel_to_VectorI(pixels, pcount));

	delete[] pixels;
    } else {
	// the point array IS sorted
	IA_Set<P>	ps(dim, points, pcount);
	set_and_reference_image(new IA_VectorI<P,T>(ps, (T*)values, vcount,
						    0));
    }
}

template < class P,class T>
IA_CoreImage<P,T>::IA_CoreImage(const P *points, unsigned pcount,
			T *values, unsigned vcount, int giveaway)
{
    if (pcount!=vcount)  {
	ia_throw(IA::IMAGE_VECTOR_CNSTR_SZMISMATCH, __FILE__, __LINE__);
	set_and_reference_image(new IA_ErrorI<P,T>);
	return;
    }

    if (pcount<1) {
	IA::not_yet_implemented(__FILE__, __LINE__);
	abort();		// should ia_throw
	set_and_reference_image(new IA_ErrorI<P,T>);
    }

    int	dim=points[0].dim();

    for (int i=1; i<pcount; i++)
	if (points[i].dim() != dim)
	    break;

    if (i<pcount) {
	ia_throw(IA::PSET_DIMENSION_MISMATCH, __FILE__, __LINE__);
	set_and_reference_image(new IA_ErrorI<P,T>);
	return;
    }

    for (i=0; i+1<pcount; i++)
	if (pointcmp(points[i], points[i+1])>=0)
	    break;		// if it\'s not strictly increasing

    if (i+1<pcount) {
	// the point array is not sorted
	IA_Pixel<P,T> * const	pixels = new IA_Pixel<P,T>[pcount];
	for (int i=0; i<pcount; i++) {
	    pixels[i].point = points[i];
	    pixels[i].value = values[i];
	}

	qsort((char*)pixels, pcount, sizeof(*pixels), IA_Pixel<P,T>::vcompare);

	set_and_reference_image(sortedPixel_to_VectorI(pixels, pcount));

	delete[] pixels;
	if (giveaway)
	    delete[] values;	// well, we couldn\'t use them as-is
    } else {
	// the point array IS sorted
	IA_Set<P>	ps(dim, points, pcount);
	set_and_reference_image(new IA_VectorI<P,T>(ps, values, vcount,
						    giveaway));
    }
}

template < class P,class T>
IA_CoreImage<P,T>::IA_CoreImage(const IA_ClosureI<P,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 P,class T>
IA_CoreImage<P,T>::IA_CoreImage(const IA_Set<P> &ps,
			T (*f)(const P&))
// User-defined-image constructor.  They provide us with a function
// and we wrap an implementation around it.
{
    set_and_reference_image(new IA_FunctionRefI<P,T>(ps,f));
}

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

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

    this->disassociate_image();

    this->bip = temp;

    return *this;
}

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

template < class P,class T>
T& IA_CoreImage<P,T>::operator [](const P& 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 0
    if (!this->domain().contains(p)) {
	ia_throw(IA::IMAGE_POINT_OUTSIDE_DOMAIN, __FILE__, __LINE__);
    }
#endif
    if (this->bip->get_ref() > 1 || !this->bip->extensive()) {

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

	IA_BaseImage<P,T>	*temp = bip->clone_self_extensively();

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

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

template <class P,class T>
IA_CoreImage<IA_Point<int>,T> IA_CoreImage<P,T>::restrict(const IA_Set<IA_Point<int> >& ips)
    const
{
    IA_BaseImage<IA_Point<int>,T>	*rval = bip->restricted_to(ips);
    return rval;
}

template <class P,class T>
IA_CoreImage<P,T> IA_CoreImage<P,T>::restrict(const IA_Set<IA_Point<double> >& ips)
    const
{
    IA_BaseImage<P,T>	*rval = bip->restricted_to(ips);
    if (rval)
	return rval;
    else
	return *this;
}

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

#if 1 // NYI

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

template <class P, class T>
void IA_CoreImage<P,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 P, class T>
void IA_CoreImage<P,T>::vec_iter_2_vec_structcopy
(
 const T	**lhs_data,
#ifdef FUNKY_ERROR
 void *rhs_v,
#else
 IA_IVIter<P,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_IVIter<P,T>	*rhs_iter = (IA_IVIter<P,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))
		    IA::internal_error(__FILE__, __LINE__);
		*((*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))
		    IA::internal_error(__FILE__, __LINE__);
		*((*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 P, class T>
void IA_CoreImage<P,T>::iter_vec_2_vec_structcopy
(
#ifdef FUNKY_ERROR
 void *lhs_v,
#else
 IA_IVIter<P,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_IVIter<P,T>	*lhs_iter = (IA_IVIter<P,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))
		    IA::internal_error(__FILE__,__LINE__);
		*((*dest)++) = temp;
	    }
	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*lhs_iter)(temp))
		    IA::internal_error(__FILE__,__LINE__);
		*((*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 P, class T>
void IA_CoreImage<P,T>::iter_iter_2_vec_structcopy
(
#ifdef FUNKY_ERROR
 void *lhs_v, void *rhs_v,
#else
 IA_IVIter< IA_IVIter<T,T> *lhs_iter> *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_IVIter<P,T>	*lhs_iter = (IA_IVIter<P,T> *)lhs_v;
    IA_IVIter<P,T>	*rhs_iter = (IA_IVIter<P,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))
		    IA::internal_error(__FILE__,__LINE__);
		if (!(*lhs_iter)(temp)) // throw away the rhs value
		    IA::internal_error(__FILE__,__LINE__);
		*((*dest)++) = temp;
	    }
	} else if (ssi.substructure == IA_SetStructure::FIRST_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*lhs_iter)(temp))
		    IA::internal_error(__FILE__,__LINE__);
		*((*dest)++) = temp;
	    }
	} else if (ssi.substructure == IA_SetStructure::SECOND_ONLY) {
	    for (int j=0; j<ssi.count; j++) {
		if (!(*rhs_iter)(temp))
		    IA::internal_error(__FILE__,__LINE__);
		*((*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 P, class T>
IA_CoreImage<P,T>
IA_CoreImage<P,T>::extend(const IA_CoreImage<P,T>& imr) const
//
// Returns the extension of image *this to image imr.
//
// imr		UNmodified
//
{
    if(!this->domain().extensive() || !imr.domain().extensive()) {
	// Need LazyExtensionImage
	ia_throw( IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__);
	return IA_CoreImage<P,T>();
    }

    IA_SetStructure ss;
    IA_Set<P> 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_VectorI<P,T>::s_type()) {
	const IA_VectorI<P,T> *lhs = (IA_VectorI<P,T>*)this->bip;
	const T	*lhs_data = lhs->vec;

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

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

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

#endif // NYI

//
//
//

template < class P,class T>
IA_CoreImage<P,T> IA_CoreImage<P,T>::translate(const P &p) const
{
    return bip->xlated_by(p);
}
//
//
//

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

template < class P,class T>
T IA_CoreImage<P,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_IVIter<P,T> iter(*this);

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

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

    if (this->card()>0) {
	IA_IVIter<P,T> iter(*this);

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

//
//
//

#include "ImgRestrictAssn.c"

//
//
//

template < class P,class T>
ostream& operator <<(ostream& o, const IA_CoreImage<P,T> &im)
{
    return o << *(im.bip);
}
@


1.10.1.1
log
@Conversion to classes for throw.
restrict and extend are now ROFs in AuxImage.c.
@
text
@a10 3
// Revision 1.10  1994/09/16  14:57:11  thoth
// more DOS-inspired renaming.
//
d159 1
a159 1
	ia_throw(Pointset_RequireExtensive_Exception(__FILE__, __LINE__));
d165 1
a165 1
	ia_throw(Image_VectorConstructorSizeMismatch_Exception(__FILE__, __LINE__));
d188 1
a188 1
	ia_throw(Pointset_RequireExtensive_Exception(__FILE__, __LINE__));
d195 1
a195 1
	ia_throw(Image_VectorConstructorSizeMismatch_Exception(__FILE__, __LINE__));
d263 1
a263 1
	ia_throw(Image_VectorConstructorSizeMismatch_Exception(__FILE__, __LINE__));
d281 1
a281 1
	ia_throw(Pointset_DimensionMismatch_Exception(__FILE__, __LINE__));
d316 1
a316 1
	ia_throw(Image_VectorConstructorSizeMismatch_Exception(__FILE__, __LINE__));
d334 1
a334 1
	ia_throw(Pointset_DimensionMismatch_Exception(__FILE__, __LINE__));
a455 2
#if 0

d480 1
a480 2
	ia_throw( Pointset_RequireExtensive_Exception(__FILE__, __LINE__));
	return IA_CoreImage<P,T>();
d511 1
a511 1
#endif
a712 2
#if 0 // implemented elsewhere

d724 1
a724 1
	ia_throw(Pointset_RequireExtensive_Exception(__FILE__, __LINE__));
a766 1
#if 1
a771 2
#endif

@


1.10.1.2
log
@CoreImage has been re-merged with Image.  All special stuff should be
friends of FBI now.
@
text
@d10 1
a10 5
// $Log: Image.c,v $
// Revision 1.10.1.1  1994/12/28  15:47:07  thoth
// Conversion to classes for throw.
// restrict and extend are now ROFs in AuxImage.c.
//
d61 1
a61 1
#include "Image.h"
d80 1
a80 1
void IA_Image<P,T>::set_and_reference_image(IA_BaseImage<P,T> *i)
d87 1
a87 1
void IA_Image<P,T>::disassociate_image()
d106 1
a106 1
IA_Image<P,T>::~IA_Image()
d114 1
a114 1
IA_Image<P,T>::IA_Image()
d121 1
a121 1
IA_Image<P,T>::IA_Image(const IA_Image<P,T>& im)
d134 1
a134 1
IA_Image<P,T>::IA_Image(const IA_Set<P>& p, const T& value)
d147 1
a147 1
IA_Image<P,T>::IA_Image(const IA_Set<P>& p, T *values,
d177 1
a177 1
IA_Image<P,T>::IA_Image(const IA_Set<P>& p,
d215 1
a215 1
IA_Image<P,T>::sortedPixel_to_VectorI(const IA_Pixel<P,T> *pixels,
d240 1
a240 1
IA_Image<P,T>::IA_Image(const IA_Pixel<P,T> *pixels, unsigned count)
d262 1
a262 1
IA_Image<P,T>::IA_Image(const P *points, unsigned pcount,
d315 1
a315 1
IA_Image<P,T>::IA_Image(const P *points, unsigned pcount,
d370 1
a370 1
IA_Image<P,T>::IA_Image(const IA_ClosureI<P,T>&i)
d378 1
a378 1
IA_Image<P,T>::IA_Image(const IA_Set<P> &ps,
d387 1
a387 1
IA_Image<P,T>::IA_Image(const IA_Set<P> &ps,
d396 2
a397 2
IA_Image<P,T>&
IA_Image<P,T>::operator=(const IA_Image<P,T>& im)
d416 1
a416 1
IA_Image<P,T>& IA_Image<P,T>::operator =(const T& value)
d431 1
a431 1
T& IA_Image<P,T>::operator [](const P& p)
d462 1
a462 1
IA_Image<IA_Point<int>,T> IA_Image<P,T>::restrict(const IA_Set<IA_Point<int> >& ips)
d470 1
a470 1
IA_Image<P,T> IA_Image<P,T>::restrict(const IA_Set<IA_Point<double> >& ips)
d481 1
a481 1
IA_Image<P,T> IA_Image<P,T>::restrict(const IA_Set<T>& vs)
d486 1
a486 1
	return IA_Image<P,T>();
d508 1
a508 1
    IA_Image<P,T> rval = IA_Image<P,T>
d524 1
a524 1
void IA_Image<P,T>::vec_vec_2_vec_structcopy
d561 1
a561 1
void IA_Image<P,T>::vec_iter_2_vec_structcopy
d612 1
a612 1
void IA_Image<P,T>::iter_vec_2_vec_structcopy
d664 1
a664 1
void IA_Image<P,T>::iter_iter_2_vec_structcopy
d722 2
a723 2
IA_Image<P,T>
IA_Image<P,T>::extend(const IA_Image<P,T>& imr) const
d733 1
a733 1
	return IA_Image<P,T>();
d766 1
a766 1
    return IA_Image<P,T>(newps, dest, sz, 1);
d777 1
a777 1
IA_Image<P,T> IA_Image<P,T>::translate(const P &p) const
d788 1
a788 1
IA_Set<T> IA_Image<P,T>::range() const
d802 1
a802 1
T IA_Image<P,T>::reduce(T (*gamma)(const T&, const T&), T identity) const
d821 1
a821 1
T IA_Image<P,T>::reduce(T (*gamma) (T, T), T identity) const
d844 10
@


1.9
log
@ValueSet has been replaced by container class Set.
@
text
@d11 3
d69 1
a69 1
#include "FunctionI.h"
@


1.8
log
@operator() of the container now relies upon the contained classes
to check if p is contained in the domain.  This means that users
could possibly write an erroneous operator().
@
text
@d11 5
d473 1
a473 1
IA_CoreImage<P,T> IA_CoreImage<P,T>::restrict(const IA_ValueSet<T>& vs)
d490 1
a490 1
    // ValueSet.
d774 1
a774 1
IA_ValueSet<T> IA_CoreImage<P,T>::range() const
d781 1
a781 1
    IA_ValueSet<T>	rval(vec,sz);
@


1.7
log
@chi_contains and compositions have been moved into AuxImage.c.
@
text
@d11 3
d427 1
a428 1
	cerr << "operator[]: point not in image domain" << endl;
d431 1
@


1.6
log
@Image class is now CoreImage and named image types are
Image<P,T>.
@
text
@d11 4
d817 1
a817 1
//  The chi_contains function between an image and a valueset.
d820 1
a820 58
typedef int ATYPE;

template <class P, class T>
IA_CoreImage<P, ATYPE>
vec_chi_contains(const IA_VectorI<P, T> *lhs, const IA_ValueSet<T> &rhs)
{
    const IA_Set<P> domain = lhs->domain();
    const unsigned sz = domain.card();
    ATYPE *const vec = new ATYPE[sz];

    {
	ATYPE *ds = vec;
	const T *ls = lhs->vec;
	for (unsigned i=0; i<sz; i++) {
	    *(ds++) = rhs.contains(*ls);
	    ls++;
	}
    }
    return IA_CoreImage<P, ATYPE>(domain, vec, sz, 1);
}


// scalar-scalar operation is trivial


template <class P, class T>
IA_CoreImage<P, ATYPE>
iter_chi_contains(IA_CoreImage<P, T> lhs, const IA_ValueSet<T> &rhs)
{
    const IA_Set<P> domain = lhs.domain();
    const unsigned sz = domain.card();
    ATYPE *const vec = new ATYPE[sz];

    {
	ATYPE *ds = vec;
	T ltmp;
	IA_IVIter<P, T>	liter(lhs);
	for (unsigned i=0; i<sz; i++) {
	    liter(ltmp);
	    *(ds++) = rhs.contains(ltmp);
	}
    }
    return IA_CoreImage<P, ATYPE>(domain, vec, sz, 1);
}


template <class P, class T>
IA_CoreImage<P, ATYPE>
chi_contains ( const IA_CoreImage<P, T> &lhs, const IA_ValueSet<T> &rhs)
{
    if (lhs.type() == IA_VectorI<P, T>::s_type()) {
	return vec_chi_contains((IA_VectorI<P, T> *)lhs.bip,rhs);
    } else if (lhs.type() == IA_ConstI<P, T>::s_type()) {
	return IA_CoreImage<P, ATYPE> (lhs.domain(), rhs.contains(((IA_ConstI<P, T> *)lhs.bip)->value));
    } else {
	return iter_chi_contains(lhs,rhs);
    }
}
a829 205
}

//
//
//

template < class Q,class P>
class IA_PPCompositionPS: public IA_ClosurePS<P> {
    // This class is used to define a pointset that contains
    // a point of type P if the pointset "base" contains f(p).
    // It is a Point-Point composition PointSet.
    Q	(*f)(const P&);
    IA_Set<Q>	base;
  public:
    IA_PPCompositionPS(Q (*f_)(const P&),
			const IA_Set<Q> &base_)
    :IA_ClosurePS<P>(base_.dim()), f(f_), base(base_) {
    }
    IA_ClosurePS<P> *clone_self() const {
	return new IA_PPCompositionPS(*this);
    }
    // given:
    // c = compose(ps, f);
    // then
    // c.contains(p)   iff ps.contains(f(p))
    int contains(const P &ip) const {
	// Uglier than Rosanne bug
	Q (*f2)(const P&) = f;
	return base.contains(f2(ip));
    }
};

template < class P, class Q,class T>
class IA_PPCompositionI: public IA_ClosureI<P,T> {
    //  This defines an image whose values are taken
    // from a source image after applying a function to the point.
    // It is a Point-Point composition image.
    Q	(*f)(const P&);
    IA_CoreImage<Q,T>	im;
  public:
    IA_PPCompositionI( const IA_CoreImage<Q,T> &im_,
		       Q (*f_)(const P&))
    :IA_ClosureI<P,T>(IA_PPCompositionPS<Q,P>(f_, im_.domain())),
     f(f_), im(im_) { }
    // given:
    // c = compose(i, f);
    // then
    // c(p) is defined by i(f(p))
    T operator()(const P&p) const {
	Q (*f2)(const P &) = f;
	return im(f2(p));
    }
    IA_ClosureI<P,T>* clone_self() const {
	return new IA_PPCompositionI<P,Q,T>(*this);
    }
#if 0
    T *range(unsigned *n) const {
	return im.range(n);
    }
#endif
};

template < class P,class T>
IA_CoreImage<P,T> compose(const IA_CoreImage<P,T> &i,
		      P (*f)(const P&))
{
    return IA_PPCompositionI<P,P,T>(i, f);
}

//
//
//

#include "Closure.h"

template < class Q,class P>
class IA_PPCompClosurePS: public IA_ClosurePS<P> {
    IA_Closure< P,Q> *f;
    IA_Set<Q>	base;
  public:
    IA_PPCompClosurePS( const IA_Closure< P,Q> &f_,
			const IA_Set<Q> &base_)
    :IA_ClosurePS<P>(base_.dim()), f(f_.clone_self()), base(base_) {
    }
    IA_PPCompClosurePS(const IA_PPCompClosurePS &other)
    :IA_ClosurePS<P>(other.base.dim()), f(other.f->clone_self()),
     base(other.base) {
	 // f has been cloned
    }
    ~IA_PPCompClosurePS() { delete f; }

    IA_ClosurePS<P> *clone_self() const {
	return new IA_PPCompClosurePS(*this);
    }
    int contains(const P &ip) const {
	return base.contains((*f)(ip));
    }
};

template < class P, class Q,class T>
class IA_PPCompClosureI: public IA_ClosureI<P,T> {
    IA_Closure<P,Q> *f;
    IA_CoreImage<Q,T>	im;
  public:
    IA_PPCompClosureI( const IA_Closure< P,Q> &f_,
		       const IA_CoreImage<Q,T> &im_)
    :IA_ClosureI<P,T>(IA_PPCompClosurePS<P,Q>(f_, im_.domain())),
     f(f_.clone_self()), im(im_) { }
    IA_PPCompClosureI(const IA_PPCompClosureI &other) 
    :IA_ClosureI<P,T>(IA_PPCompClosurePS<P,Q>(*other.f, other.im.domain())),
     f(other.f->clone_self()), im(other.im) { }
    ~IA_PPCompClosureI() { delete f; }

    T operator()(const P&p) const {
	return im((*f)(p));
    }
    IA_ClosureI<P,T>* clone_self() const {
	return new IA_PPCompClosureI<P,Q,T>(*this);
    }
#if 0
    T *range(unsigned *n) const {
	return im.range(n);
    }
#endif
};


template < class P,class T>
IA_CoreImage<P,T> compose
(const IA_CoreImage<P,T>& im,
 const IA_Closure<P,P> &f)
{
    return IA_PPCompClosureI<P,P,T>(f, im);
}

//
//
//

template < class P,class T>
IA_CoreImage<P,T> compose(T (*f)(T), const IA_CoreImage<P,T> &i)
{
    IA_IVIter<P,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_CoreImage<P,T>(i.domain(), vals, size, 1);
}

template <class T, class P,class S>
IA_CoreImage<P,S> compose(S (*f)(T), const IA_CoreImage<P,T> &i, const S*)
{
    IA_IVIter<P,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_CoreImage<P,S>(i.domain(), vals, size, 1);
}

template < class S, class T, class P,class R>
IA_CoreImage<P,R> compose(R (*f)(S), const IA_CoreImage<P,T> &i, const R*, const S*)
{
    IA_IVIter<P,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_CoreImage<P,R>(i.domain(), vals, size, 1);
}

template < class R, class S, class T, class P,class Q>
IA_CoreImage<P,Q> compose(R (*f)(S), const IA_CoreImage<P,T> &i, const Q*, const R*, const S*)
{
    IA_IVIter<P,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_CoreImage<P,Q>(i.domain(), vals, size, 1);
@


1.5
log
@Improved error handling.
Pixel array constructor.
pointarray valuearray constructor.
Added FunctionI that accepts functions with simple T type instead of
const T&.
new chi_contains function.
@
text
@d10 9
a18 1
// $Log: Image.c,v $
d43 1
a43 1
#include "Image.h"
d62 1
a62 1
void IA_Image<P,T>::set_and_reference_image(IA_BaseImage<P,T> *i)
d69 1
a69 1
void IA_Image<P,T>::disassociate_image()
d88 1
a88 1
IA_Image<P,T>::~IA_Image()
d96 1
a96 1
IA_Image<P,T>::IA_Image()
d103 1
a103 1
IA_Image<P,T>::IA_Image(const IA_Image<P,T>& im)
d116 1
a116 1
IA_Image<P,T>::IA_Image(const IA_Set<P>& p, const T& value)
d129 1
a129 1
IA_Image<P,T>::IA_Image(const IA_Set<P>& p, T *values,
d159 1
a159 1
IA_Image<P,T>::IA_Image(const IA_Set<P>& p,
d197 1
a197 1
IA_Image<P,T>::sortedPixel_to_VectorI(const IA_Pixel<P,T> *pixels,
d222 1
a222 1
IA_Image<P,T>::IA_Image(const IA_Pixel<P,T> *pixels, unsigned count)
d244 1
a244 1
IA_Image<P,T>::IA_Image(const P *points, unsigned pcount,
d297 1
a297 1
IA_Image<P,T>::IA_Image(const P *points, unsigned pcount,
d352 1
a352 1
IA_Image<P,T>::IA_Image(const IA_ClosureI<P,T>&i)
d360 1
a360 1
IA_Image<P,T>::IA_Image(const IA_Set<P> &ps,
d369 1
a369 1
IA_Image<P,T>::IA_Image(const IA_Set<P> &ps,
d378 2
a379 2
IA_Image<P,T>&
IA_Image<P,T>::operator=(const IA_Image<P,T>& im)
d398 1
a398 1
IA_Image<P,T>& IA_Image<P,T>::operator =(const T& value)
d413 1
a413 1
T& IA_Image<P,T>::operator [](const P& p)
d441 1
a441 1
IA_Image<IA_Point<int>,T> IA_Image<P,T>::restrict(const IA_Set<IA_Point<int> >& ips)
d449 1
a449 1
IA_Image<P,T> IA_Image<P,T>::restrict(const IA_Set<IA_Point<double> >& ips)
d460 1
a460 1
IA_Image<P,T> IA_Image<P,T>::restrict(const IA_ValueSet<T>& vs)
d486 1
a486 1
    IA_Image<P,T> rval = IA_Image<P,T>
d502 1
a502 1
void IA_Image<P,T>::vec_vec_2_vec_structcopy
d539 1
a539 1
void IA_Image<P,T>::vec_iter_2_vec_structcopy
d590 1
a590 1
void IA_Image<P,T>::iter_vec_2_vec_structcopy
d642 1
a642 1
void IA_Image<P,T>::iter_iter_2_vec_structcopy
d698 2
a699 2
IA_Image<P,T>
IA_Image<P,T>::extend(const IA_Image<P,T>& imr) const
d709 1
a709 1
	return IA_Image<P,T>();
d742 1
a742 1
    return IA_Image<P,T>(newps, dest, sz, 1);
d752 1
a752 1
IA_Image<P,T> IA_Image<P,T>::translate(const P &p) const
d761 1
a761 1
IA_ValueSet<T> IA_Image<P,T>::range() const
d775 1
a775 1
T IA_Image<P,T>::reduce(T (*gamma)(const T&, const T&), T identity) const
d794 1
a794 1
T IA_Image<P,T>::reduce(T (*gamma) (T, T), T identity) const
d819 1
a819 1
IA_Image<P, ATYPE>
d834 1
a834 1
    return IA_Image<P, ATYPE>(domain, vec, sz, 1);
d842 2
a843 2
IA_Image<P, ATYPE>
iter_chi_contains(IA_Image<P, T> lhs, const IA_ValueSet<T> &rhs)
d858 1
a858 1
    return IA_Image<P, ATYPE>(domain, vec, sz, 1);
d863 2
a864 2
IA_Image<P, ATYPE>
chi_contains ( const IA_Image<P, T> &lhs, const IA_ValueSet<T> &rhs)
d869 1
a869 1
	return IA_Image<P, ATYPE> (lhs.domain(), rhs.contains(((IA_ConstI<P, T> *)lhs.bip)->value));
d880 1
a880 1
ostream& operator <<(ostream& o, const IA_Image<P,T> &im)
d921 1
a921 1
    IA_Image<Q,T>	im;
d923 1
a923 1
    IA_PPCompositionI( const IA_Image<Q,T> &im_,
d946 1
a946 1
IA_Image<P,T> compose(const IA_Image<P,T> &i,
d985 1
a985 1
    IA_Image<Q,T>	im;
d988 1
a988 1
		       const IA_Image<Q,T> &im_)
d1011 2
a1012 2
IA_Image<P,T> compose
(const IA_Image<P,T>& im,
d1023 1
a1023 1
IA_Image<P,T> compose(T (*f)(T), const IA_Image<P,T> &i)
d1036 1
a1036 1
    return IA_Image<P,T>(i.domain(), vals, size, 1);
d1040 1
a1040 1
IA_Image<P,S> compose(S (*f)(T), const IA_Image<P,T> &i, const S*)
d1053 1
a1053 1
    return IA_Image<P,S>(i.domain(), vals, size, 1);
d1057 1
a1057 1
IA_Image<P,R> compose(R (*f)(S), const IA_Image<P,T> &i, const R*, const S*)
d1070 1
a1070 1
    return IA_Image<P,R>(i.domain(), vals, size, 1);
d1074 1
a1074 1
IA_Image<P,Q> compose(R (*f)(S), const IA_Image<P,T> &i, const Q*, const R*, const S*)
d1087 1
a1087 1
    return IA_Image<P,Q>(i.domain(), vals, size, 1);
@


1.4
log
@extensivep is now extensive
translated is now translate.
@
text
@d11 4
d46 1
a46 1
#include "FuncRefI.h"
d50 2
d73 6
d86 1
d93 1
d106 1
d119 1
d137 1
d142 2
a143 2
	cerr << "image vector constructor, pointset size and array size mismatch"<<endl;
	abort(); // throw
d149 1
d165 2
a166 2
	ia_throw( IA::IMAGE_STRUCTURE_NOT_SUPPORTED
	      , __FILE__, __LINE__);
d172 2
a173 1
	abort(); // throw
d182 161
d361 9
d414 1
a414 1
	abort();		// throw
d559 1
a559 1
		    abort(); // internal error
d569 1
a569 1
		    abort(); // internal error
d611 1
a611 1
		    abort(); // internal error
d617 1
a617 1
		    abort(); // internal error
d662 1
a662 1
		    abort(); // internal error
d664 1
a664 1
		    abort(); // internal error
d670 1
a670 1
		    abort(); // internal error
d676 1
a676 1
		    abort(); // internal error
d804 66
@


1.3
log
@Move to new Closure naming convention.
@
text
@d11 3
d119 1
a119 1
    if (!p.extensivep()){
d146 1
a146 1
    if (!p.extensivep()){
d227 1
a227 1
    if (this->bip->get_ref() > 1 || !this->bip->extensivep()) {
d266 1
a266 1
    if (!this->domain().extensivep()) {
d509 1
a509 1
    if(!this->domain().extensivep() || !imr.domain().extensivep()) {
d555 1
a555 1
IA_Image<P,T> IA_Image<P,T>::translated(const P &p) const
@


1.2
log
@Some diagnostics for abort()s that need to be ia_throws.
xlated is now translated.
@
text
@d11 4
d26 1
a26 1
//#include "PredicatePS.h"
d38 1
a38 1
#include "OtherI.h"
d41 1
a41 1
#include "PredicatePS.h"
d161 1
a161 1
IA_Image<P,T>::IA_Image(const IA_OtherI<P,T>&i)
d624 1
a624 1
class IA_PPCompositionPS: public IA_PSPred<P> {
d633 1
a633 1
    :IA_PSPred<P>(base_.dim()), f(f_), base(base_) {
d635 1
a635 1
    IA_PSPred<P> *clone_self() const {
d650 1
a650 1
class IA_PPCompositionI: public IA_OtherI<P,T> {
d659 1
a659 1
    :IA_OtherI<P,T>(IA_PPCompositionPS<Q,P>(f_, im_.domain())),
d669 1
a669 1
    IA_OtherI<P,T>* clone_self() const {
d693 1
a693 1
class IA_PPCompClosurePS: public IA_PSPred<P> {
d699 1
a699 1
    :IA_PSPred<P>(base_.dim()), f(f_.clone_self()), base(base_) {
d702 1
a702 1
    :IA_PSPred<P>(other.base.dim()), f(other.f->clone_self()),
d708 1
a708 1
    IA_PSPred<P> *clone_self() const {
d717 1
a717 1
class IA_PPCompClosureI: public IA_OtherI<P,T> {
d723 1
a723 1
    :IA_OtherI<P,T>(IA_PPCompClosurePS<P,Q>(f_, im_.domain())),
d726 1
a726 1
    :IA_OtherI<P,T>(IA_PPCompClosurePS<P,Q>(*other.f, other.im.domain())),
d733 1
a733 1
    IA_OtherI<P,T>* clone_self() const {
@


1.1
log
@Initial revision
@
text
@d10 4
a13 1
// $Log:	Image.c,v $
d118 1
d146 1
d217 1
d548 1
a548 1
IA_Image<P,T> IA_Image<P,T>::xlated(const P &p) const
@
