package fr.unistra.pelican.util.mask;
import java.util.Stack;
import fr.unistra.pelican.BooleanImage;
/**
* This represent a stack of mask. Each MaskStack uses his stack of masks and a
* comparison policy to decide if a given pixel is present or not. With policy
* FALSE, a pixel is never present. With policy TRUE, a pixel is always present.
* With policy AND, a pixel is present if it is present in every mask of the
* stack. With policy OR, a pixel is present if it is present in at least one
* mask of the stack.
*
* @see Mask
* @author Benjamin Perret, Régis Witz
*/
public class MaskStack extends Stack<Mask> implements Mask {
// /////////////
// CONSTANTS //
// /////////////
private static final long serialVersionUID = 1L;
// DEVNOTE:
// if you add a policy, you should :
// step 1: add its name and ID below.
// step 2: update the "should I throw an exception ?" part in
// this.setPolicy( int policy ).
// step 3: update with your processing all the isInMask( xxx ) methods.
public static final int FALSE = 0;
public static final int TRUE = 1;
public static final int AND = 2;
public static final int OR = 3;
// //////////
// FIELDS //
// //////////
/** Comparison policy. */
private int policy = AND;
// ////////////////
// CONSTRUCTORS //
// ////////////////
/**
* Default constructor : create a stack of masks and push a mask on it
*
* @param m
* Mask to push
*/
public MaskStack(Mask m) {
super();
if (m != null)
push(m);
}
/**
* Create a stack of masks, affect it a comparison policy and push a mask on
* it.
*
* @param m
* Mask to push.
* @param policy
* Comparaison policy.
*/
public MaskStack(Mask m, int policy) {
this(m);
this.setPolicy(policy);
}
/** Create an empty stack of masks. */
public MaskStack() {
this(null);
}
/**
* Create an empty stack of masks and affect it a comparison policy .
*
* @param policy
* Comparaison policy.
*/
public MaskStack(int policy) {
this(null, policy);
}
// ///////////
// METHODS //
// ///////////
/*
* (non-Javadoc)
*
* @see fr.unistra.pelican.util.mask.Mask#cloneMask()
*/
public Mask cloneMask() {
MaskStack ms = new MaskStack(this.policy);
for (Mask m : this)
ms.push(m.cloneMask());
return ms;
}
public boolean isInMask(int loc) {
switch (this.policy) {
case TRUE:
return true;
case FALSE:
return false;
case AND:
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMask(loc))
return false;
return true;
case OR:
if (this.size() == 0)
return true;
for (Mask m : this)
if (m.isInMask(loc))
return true;
return false;
default:
return false;
}
}
public boolean isInMask(long loc) {
switch (this.policy) {
case TRUE:
return true;
case FALSE:
return false;
case AND:
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMask(loc))
return false;
return true;
case OR:
if (this.size() == 0)
return true;
for (Mask m : this)
if (m.isInMask(loc))
return true;
return false;
default:
return false;
}
}
public boolean isInMask(int x, int y, int z, int t, int b) {
if (this.policy == TRUE)
return true;
else if (this.policy == FALSE)
return false;
else if (this.policy == AND) {
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMask(x, y, z, t, b))
return false;
return true;
} else if (this.policy == OR) {
if ( this.size() == 0 ) return true;
for (Mask m : this)
if (m.isInMask(x, y, z, t, b))
return true;
return false;
} else
return false;
}
/**
* @return <tt>true</tt> if a pixel is NOT hidden by the mask.
*/
public boolean isInMaskXY(int x, int y) {
if (this.policy == TRUE)
return true;
else if (this.policy == FALSE)
return false;
else if (this.policy == AND) {
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMaskXY(x, y))
return false;
return true;
} else if (this.policy == OR) {
if ( this.size() == 0 ) return true;
for (Mask m : this)
if (m.isInMaskXY(x, y))
return true;
return false;
} else
return false;
}
public boolean isInMaskXYB(int x, int y, int b) {
if (this.policy == TRUE)
return true;
else if (this.policy == FALSE)
return false;
else if (this.policy == AND) {
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMaskXYB(x, y, b))
return false;
return true;
} else if (this.policy == OR) {
if ( this.size() == 0 ) return true;
for (Mask m : this)
if (m.isInMaskXYB(x, y, b))
return true;
return false;
} else
return false;
}
public boolean isInMaskXYT(int x, int y, int t) {
if (this.policy == TRUE)
return true;
else if (this.policy == FALSE)
return false;
else if (this.policy == AND) {
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMaskXYT(x, y, t))
return false;
return true;
} else if (this.policy == OR) {
if ( this.size() == 0 ) return true;
for (Mask m : this)
if (m.isInMaskXYT(x, y, t))
return true;
return false;
} else
return false;
}
public boolean isInMaskXYTB(int x, int y, int t, int b) {
if (this.policy == TRUE)
return true;
else if (this.policy == FALSE)
return false;
else if (this.policy == AND) {
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMaskXYTB(x, y, t, b))
return false;
return true;
} else if (this.policy == OR) {
if ( this.size() == 0 ) return true;
for (Mask m : this)
if (m.isInMaskXYTB(x, y, t, b))
return true;
return false;
} else
return false;
}
public boolean isInMaskXYZ(int x, int y, int z) {
if (this.policy == TRUE)
return true;
else if (this.policy == FALSE)
return false;
else if (this.policy == AND) {
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMaskXYZ(x, y, z))
return false;
return true;
} else if (this.policy == OR) {
if ( this.size() == 0 ) return true;
for (Mask m : this)
if (m.isInMaskXYZ(x, y, z))
return true;
return false;
} else
return false;
}
public boolean isInMaskXYZB(int x, int y, int z, int b) {
if (this.policy == TRUE)
return true;
else if (this.policy == FALSE)
return false;
else if (this.policy == AND) {
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMaskXYZB(x, y, z, b))
return false;
return true;
} else if (this.policy == OR) {
if ( this.size() == 0 ) return true;
for (Mask m : this)
if (m.isInMaskXYZB(x, y, z, b))
return true;
return false;
} else
return false;
}
public boolean isInMaskXYZT(int x, int y, int z, int t) {
if (this.policy == TRUE)
return true;
else if (this.policy == FALSE)
return false;
else if (this.policy == AND) {
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMaskXYZT(x, y, z, t))
return false;
return true;
} else if (this.policy == OR) {
if ( this.size() == 0 ) return true;
for (Mask m : this)
if (m.isInMaskXYZT(x, y, z, t))
return true;
return false;
} else
return false;
}
public boolean isInMaskXYZTB(int x, int y, int z, int t, int b) {
if (this.policy == TRUE)
return true;
else if (this.policy == FALSE)
return false;
else if (this.policy == AND) {
// if ( this.size() == 0 ) return true;
for (Mask m : this)
if (!m.isInMaskXYZTB(x, y, z, t, b))
return false;
return true;
} else if (this.policy == OR) {
if ( this.size() == 0 ) return true;
for (Mask m : this)
if (m.isInMaskXYZTB(x, y, z, t, b))
return true;
return false;
} else
return false;
}
/**
* Set this MaskStack's comparaison policy.
*
* @param policy
* Comparison policy. Must be one of the
* "public static final int" constants wich are at the beginning
* of this class declaration.
*/
public void setPolicy(int policy) {
// "should I throw an exception ?"
if ((policy != FALSE) && (policy != TRUE) && (policy != AND)
&& (policy != OR))
throw new fr.unistra.pelican.PelicanException("Policy unknown.");
// update
this.policy = policy;
}
/**
* Attempts to merge BooleanMasks contained in {@link #mask} if they are all
* equal to each other. A time consumer, but room-saver.
*/
public void mergeBooleanMasks() {
java.util.ArrayList<BooleanMask> array = new java.util.ArrayList<BooleanMask>();
for (java.util.Enumeration<Mask> e = this.elements(); e
.hasMoreElements();) {
Mask m = e.nextElement();
if (m instanceof BooleanMask)
array.add((BooleanMask) m);
}
if (array.size() == 0)
return;
BooleanImage bi = new BooleanImage(array.get(0).getXDim(), array.get(0)
.getYDim(), array.get(0).getZDim(), array.get(0).getTDim(),
array.get(0).getBDim());
boolean val;
for (int x = 0; x < bi.xdim; x++)
for (int y = 0; y < bi.ydim; y++)
for (int z = 0; z < bi.zdim; z++)
for (int t = 0; t < bi.tdim; t++)
for (int b = 0; b < bi.bdim; b++) {
val = array.get(0).isInMask(x, y, z, t, b);
for (int i = 1; i < array.size(); i++)
if (val != array.get(i).isInMask(x, y, z, t, b))
return;
bi.setPixelXYZTBBoolean(x, y, z, t, b, val);
}
for (int i = 0; i < array.size(); i++)
this.removeElement(array.get(i));
this.push(new BooleanMask(bi));
}
/**
* Push all masks from a given MaskStack into the current MaskStack
*
* @param stack
* @return the given MaskStack
* @author Lefevre
*/
public MaskStack push(MaskStack stack) {
for (Mask m : stack)
this.push(m);
return stack;
}
}