#ifndef IMAGES2ITER_HH
#define IMAGES2ITER_HH
////////////////////////////////////////////////////////////////////////////
//! file="amma/Image/BasImage/ImageS2Iter.hh"
//! lib=Image
//! userlevel=Normal
//! author="Charles Galambos"
//! docentry="Image.Indexing.Iterators"
//! rcsid="$Id: ImageS2Iter.hh,v 1.4 2000/07/07 12:57:28 ees1cg Exp $"
//! date="05/03/2000"
#include "amma/ImagIter.hh"
//: Pointer based image iterator for image pairs.
// NB. This does NOT hold a refrence to any of the images!
//
// Allows FAST iteration over a pair of images. It is intended for
// implementing image processing operations which require access to
// a pixel in two images.
// Note that the two images do not need to be of the same type.
template
class ImageS2IterC
: protected ImageIterC
{
public:
inline ImageS2IterC ();
//: Default constructor
inline ImageS2IterC (const ImageC &img1,const ImageC &img2);
//: Construct from input and output images.
inline ImageS2IterC (const ImageC &img1,const ImageRectangleC &rect1,const ImageC &img2,const ImageRectangleC &rect2);
//: Construct from input and output images.
// rect1 and rect2 should must be the same size.
inline ImageS2IterC (const ImageS2IterC &Oth);
//: Copy constructor.
inline BooleanT First ();
//: Goto first pixel in image.
// Returns false if image is empty.
inline void Next ();
//: Goto next pixel in image.
inline BooleanT RNext();
//: Goto next pixel in the image.
// Returns TRUE, if next pixels is in same row.
// FALSE otherwise.
inline Data1C & Data1()
{ return ImageIterC::Data(); }
//: Access pixel from image 1
inline Data2C & Data2()
{ return *place2; }
//: Access pixel from image 2
inline IndexT Col() const
{ return ImageIterC::Col(); }
//: Get current column.
// (SLOW) Use ImagPIterC<> if you use this alot.
inline PixelC Pixel() const
{ return ImageIterC::Pixel(); }
//: Get current pixel location.
// (SLOW) Use ImagPIterC<> if you use this alot.
inline IndexT Row() const
{ return ImageIterC::Row(); }
//: Get current row.
inline BooleanT IsElm() const
{ return ImageIterC::IsElm(); }
//: At valid pixel in image ?
inline BooleanT IsEndOfRow() const
{ return ImageIterC::IsEndOfRow(); }
//: Test if last pixel in row.
protected:
inline Data2C *RowPtr2(const IndexT &x)
{ return &(img2[x.V()][lcol2.V()]); }
//: Get start of row for image 2
Data2C **img2; // table of pointers to image rows
Data2C *place2; // Ptr to current pixel in output image
IndexT lcol2; // Offset of left coloumb in image2;
IndexT row2; // row in image2;
IndexT trow2; // top row in image2.
};
////////////////////////////////////////////////////////////////////////////
template
inline ImageS2IterC::ImageS2IterC ()
{}
template
inline ImageS2IterC::ImageS2IterC (const ImageC &nImg1,const ImageC &nImg2)
: ImageIterC(nImg1),
img2(nImg2.StartAddress()),
lcol2(nImg2.LCol()),
row2(nImg2.TRow()),
trow2(nImg2.TRow())
{
#if AMMA_CHECK
if (nImg1.Cnum() > nImg2.Cnum() || nImg1.Rnum() > nImg2.Rnum()) {
cerr << "Error: ImageS2IterC, Image1 must not be bigger than Image2 in either dimention.\n";
assert(0);
}
#endif
if(IsElm())
place2 = RowPtr2(row2);
}
template
inline ImageS2IterC::ImageS2IterC (const ImageC &nimg1,const ImageRectangleC &rect1,
const ImageC &nimg2,const ImageRectangleC &rect2)
: ImageIterC(nimg1,rect1),
img2(nimg2.StartAddress()),
lcol2(rect2.LCol()),
row2(rect2.TRow()),
trow2(rect2.TRow())
{
#if AMMA_CHECK
if (nimg1.Cnum() > nimg2.Cnum() || nimg1.Rnum() > nimg2.Rnum()) {
cerr << "Error: ImageS2IterC, Image1 must not be bigger than Image2 in either dimention.\n";
assert(0);
}
#endif
if(IsElm())
place2 = RowPtr2(row2);
}
template
inline ImageS2IterC::ImageS2IterC(const ImageS2IterC &oth)
: ImageIterC(oth),
img2(oth.img2),
place2(oth.place2),
lcol2(oth.lcol2)
{}
template
inline
BooleanT ImageS2IterC::First ()
{
if(!ImageIterC::First())
return FALSE;
row2 = trow2;
place2 = RowPtr2(row2);
return TRUE;
}
template
inline
void ImageS2IterC::Next()
{
if(ImageIterC::RNext()) {
place2++;
return ;
}
if(!ImageIterC::IsElm())
return ; // End of image ?
place2 = RowPtr2(++row2);
}
template
inline
BooleanT ImageS2IterC::RNext()
{
if(ImageIterC::RNext()) {
place2++;
return TRUE;
}
if(!ImageIterC::IsElm())
return FALSE; // End of image ?
place2 = RowPtr2(++row2);
return FALSE;
}
#endif