#ifndef IMAGES4ITER_HH
#define IMAGES4ITER_HH
////////////////////////////////////////////////////////////////////////////
//! file="amma/Image/BasImage/ImageS4Iter.hh"
//! lib=Image
//! userlevel=Normal
//! docentry="Image.Indexing.Iterators"
//! rcsid="$Id: ImageS4Iter.hh,v 1.3 2000/07/07 12:57:30 ees1cg Exp $"
//! author="Charles Galambos"
//! date="09/03/2000"
#include "amma/ImageS3Iter.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 ImageS4IterC
: protected ImageS3IterC
{
public:
inline ImageS4IterC ();
//: Default constructor
inline ImageS4IterC (const ImageC &img1,
const ImageC &img2,
const ImageC &img3,
const ImageC &img4
);
//: Construct from input and output images.
inline ImageS4IterC (const ImageC &img1,const ImageRectangleC &rect1,
const ImageC &img2,const ImageRectangleC &rect2,
const ImageC &img3,const ImageRectangleC &rect3,
const ImageC &img4,const ImageRectangleC &rect4
);
//: Construct from input and output images.
// rect1 and rect2 should must be the same size.
inline ImageS4IterC (const ImageS4IterC &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 ImageS3IterC::Data1(); }
//: Access pixel from image 1
inline Data2C & Data2()
{ return ImageS3IterC::Data2(); }
//: Access pixel from image 1
inline Data3C & Data3()
{ return ImageS3IterC::Data3(); }
//: Access pixel from image 1
inline Data4C & Data4()
{ return *place4; }
//: Access pixel from image 2
inline IndexT Col() const
{ return ImageS3IterC::Col(); }
//: Get current column.
// (SLOW) Use ImagPIterC<> if you use this alot.
inline PixelC Pixel() const
{ return ImageS3IterC::Pixel(); }
//: Get current pixel location.
// (SLOW) Use ImagPIterC<> if you use this alot.
inline IndexT Row() const
{ return ImageS3IterC::Row(); }
//: Get current row.
inline BooleanT IsElm() const
{ return ImageS3IterC::IsElm(); }
//: At valid pixel in image ?
inline BooleanT IsEndOfRow() const
{ return ImageS3IterC::IsEndOfRow(); }
//: Test if last pixel in row.
protected:
inline Data2C *RowPtr4(const IndexT &x)
{ return &(img4[x.V()][lcol4.V()]); }
//: Get start of row for image 2
Data2C **img4; // table of pointers to image rows
Data2C *place4; // Ptr to current pixel in output image
IndexT lcol4; // Offset of left coloumb in image2;
IndexT row4; // row in image2;
IndexT trow4; // top row in image2.
};
////////////////////////////////////////////////////////////////////////////
template
inline ImageS4IterC::ImageS4IterC ()
{}
template
inline ImageS4IterC::ImageS4IterC (const ImageC &nimg1,
const ImageC &nimg2,
const ImageC &nimg3,
const ImageC &nimg4
)
: ImageS3IterC(nimg1,nimg2,nimg3),
img4(nimg4.StartAddress()),
lcol4(nimg4.LCol()),
row4(nimg4.TRow()),
trow4(nimg4.TRow())
{
#if AMMA_CHECK
if (nimg1.Cnum() > nimg4.Cnum() || nimg1.Rnum() > nimg4.Rnum()) {
cerr << "Error: ImageS4IterC, Image1 must not be bigger than Image2 in either dimention.\n";
assert(0);
}
#endif
if(IsElm())
place4 = RowPtr4(row4);
}
template
inline ImageS4IterC::ImageS4IterC (const ImageC &nimg1,const ImageRectangleC &rect1,
const ImageC &nimg2,const ImageRectangleC &rect2,
const ImageC &nimg3,const ImageRectangleC &rect3,
const ImageC &nimg4,const ImageRectangleC &rect4
)
: ImageS3IterC(nimg1,rect1,
nimg2,rect2,
nimg3,rect3),
img4(nimg4.StartAddress()),
lcol4(rect4.LCol()),
row4(rect4.TRow()),
trow4(rect4.TRow())
{
#if AMMA_CHECK
if (nimg1.Cnum() > nimg4.Cnum() || nimg1.Rnum() > nimg4.Rnum()) {
cerr << "Error: ImageS4IterC, Image1 must not be bigger than Image2 in either dimention.\n";
assert(0);
}
#endif
if(IsElm())
place4 = RowPtr4(row4);
}
template
inline ImageS4IterC::ImageS4IterC(const ImageS4IterC &oth)
: ImageS3IterC(oth),
img4(oth.img4),
place4(oth.place4),
lcol4(oth.lcol4)
{}
template
inline
BooleanT ImageS4IterC::First ()
{
if(!ImageS3IterC::First())
return FALSE;
row4 = trow4;
place4 = RowPtr4(row4);
return TRUE;
}
template
inline
void ImageS4IterC::Next()
{
if(ImageS3IterC::RNext()) {
place4++;
return ;
}
if(!ImageS3IterC::IsElm())
return ; // End of image ?
place4 = RowPtr4(++row4);
}
template
inline
BooleanT ImageS4IterC::RNext()
{
if(ImageS3IterC::RNext()) {
place4++;
return TRUE;
}
if(!ImageS3IterC::IsElm())
return FALSE; // End of image ?
place4 = RowPtr4(++row4);
return FALSE;
}
#endif