package fr.unistra.pelican.util.iterator;
import java.util.Iterator;
import fr.unistra.pelican.Image;
import fr.unistra.pelican.util.Pixel;
/**
* Allows smooth X,Y,Z,T,B iteration on an unmasked image.
* @author Régis Witz
*/
public class ImageIterator extends AbstractImageIterator<Pixel> {
/** Image on wich iteration is done. */
protected Image image;
/** X offset of the iteration. */
protected int xOffset;
/** Y offset of the iteration. */
protected int yOffset;
/** Z offset of the iteration. */
protected int zOffset;
/** T offset of the iteration. */
protected int tOffset;
/** B offset of the iteration. */
protected int bOffset;
/** X Dimension of {@link #image}. */
protected int xdim;
/** Y Dimension of {@link #image}. */
protected int ydim;
/** Z Dimension of {@link #image}. */
protected int zdim;
/** T Dimension of {@link #image}. */
protected int tdim;
/** B Dimension of {@link #image}. */
protected int bdim;
/** Equals to {@link #bdim }. */
protected int mulX;
/** Equals to {@link #xdim } x {@link #mulX }. */
protected int mulY;
/** Equals to {@link #ydim } x {@link #mulY }. */
protected int mulZ;
/** Equals to {@link #zdim } x {@link #mulZ }. */
protected int mulT;
/** Next point in iteration. Please see {@link #next} description. */
protected Pixel next = null;
/**
* To avoid multiple index computing for hasNext function.
* NB: we should have some checks, perhaps true is not true at the beginning
* (but don't worry i understand myself)
*/
protected boolean hasNext=true;
public ImageIterator( Image image ) {
this.image = image;
this.xOffset = 0;
this.yOffset = 0;
this.zOffset = 0;
this.tOffset = 0;
this.bOffset = 0;
this.xdim = this.image.getXDim();
this.ydim = this.image.getYDim();
this.zdim = this.image.getZDim();
this.tdim = this.image.getTDim();
this.bdim = this.image.getBDim();
this.mulX = this.bdim;
this.mulY = this.mulX * xdim;
this.mulZ = this.mulY * ydim;
this.mulT = this.mulZ * zdim;
if(image.size()==0)
hasNext=false;
this.next = new Pixel();
}
/** Returns <tt>true</tt> if the iteration has more elements. ( In other words, returns
* <tt>true</tt> if next would return an element rather than throwing an exception. )
* @return <tt>true</tt> if the iterator has more elements.
*/
public boolean hasNext() {
//return this.getIndex() < this.image.size();
return hasNext;
}
/** Returns the next element in the iteration. Calling this method repeatedly until the
* {@link #hasNext()} method returns <tt>false</tt> will return each element in the underlying
* collection exactly once.
* <p>
* <b>IMPORTANT NOTE :</b> Successive calls to this method always return a reference to the
* <i>same</i> object. This should be of no consequence because in foreach loops, one reuses
* always the same object. Remember, tough, if you want to keep up the {@link Pixel}
* wich this method enumerate, you should use the {@link #clone} method before reinvoking this
* method.
*
* @return Next element in the iteration.
*/
public Pixel next() {
this.next.x = this.xOffset;
this.next.y = this.yOffset;
this.next.z = this.zOffset;
this.next.t = this.tOffset;
this.next.b = this.bOffset;
this.forward();
return this.next;
}
/** Unsupported. */
public void remove() {}
protected int getIndex() {
return this.tOffset * this.mulT
+ this.zOffset * this.mulZ
+ this.yOffset * this.mulY
+ this.xOffset * this.mulX
+ this.bOffset;
}
protected void forward() {
this.bOffset++;
if ( this.bOffset == this.bdim ) {
this.bOffset = 0;
this.xOffset++;
if ( this.xOffset == this.xdim ) {
this.xOffset = 0;
this.yOffset++;
if ( this.yOffset == this.ydim ) {
this.yOffset = 0;
this.zOffset++;
if ( this.zOffset == this.zdim ) {
this.zOffset = 0;
this.tOffset++;
if ( this.tOffset == this.image.getTDim() )
hasNext=false;
}
}
}
}
}
/**
* @deprecated je ne sais pas si il y a
* vraiment usage et si on la met il faut
* la redéfinir dans tous les itérateurs dérivés
* et j'ai pas envie de le faire ... Ben
*/
protected void rewind() {
// currentIndex--;
this.bOffset--;
if ( this.bOffset < 0 ) {
this.bOffset = 0;
this.yOffset--;
if ( this.yOffset < 0 ) {
this.yOffset = 0;
this.xOffset--;
if ( this.xOffset < 0 ) {
this.xOffset = 0;
this.zOffset--;
if ( this.zOffset < 0 ) {
this.zOffset = 0;
this.tOffset--;
// be do not test if ( this.tOffset == this.image.getTDim() ) here, cuz
// this method should never be called when this.getIndex() == 0 .
}
}
}
}
}
@Override
public Iterator<Pixel> iterator() {
return this; // ouh que c'est pas bien
}
}