/*
* omeis.providers.re.GreyScaleStrategy
*
* Copyright 2006 University of Dundee. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package omeis.providers.re;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ome.conditions.ResourceError;
import ome.io.nio.PixelBuffer;
import ome.model.core.Pixels;
import ome.model.display.ChannelBinding;
import omeis.providers.re.codomain.CodomainChain;
import omeis.providers.re.data.PlaneFactory;
import omeis.providers.re.data.Plane2D;
import omeis.providers.re.data.PlaneDef;
import omeis.providers.re.quantum.QuantizationException;
import omeis.providers.re.quantum.QuantumStrategy;
/**
* Transforms a plane within a given pixels set into a greyscale image.
*
* @author Jean-Marie Burel <a
* href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author <br>
* Andrea Falconi <a
* href="mailto:a.falconi@dundee.ac.uk"> a.falconi@dundee.ac.uk</a>
* @version 2.2 <small> (<b>Internal version:</b> $Revision$ $Date:
* 2005/06/22 17:09:48 $) </small>
* @since OME2.2
*/
class GreyScaleStrategy extends RenderingStrategy {
/** The logger for this particular class */
private static Logger log = LoggerFactory.getLogger(GreyScaleStrategy.class);
/** The channel we're operating on */
private int channel;
/** The channel binding we're using */
private ChannelBinding channelBinding;
/**
* Implemented as specified by the superclass.
*
* @see RenderingStrategy#render(Renderer ctx, PlaneDef planeDef)
*/
@Override
RGBBuffer render(Renderer ctx, PlaneDef planeDef) throws IOException,
QuantizationException {
// Set the context and retrieve objects we're gonna use.
renderer = ctx;
// Initialize sizeX1 and sizeX2 according to the plane definition and
// create the RGB buffer.
Pixels metadata = renderer.getMetadata();
initAxesSize(planeDef, metadata);
if (!findFirstActiveChannelBinding())
{
return getRgbBuffer();
}
PixelBuffer pixels = renderer.getPixels();
RenderingStats performanceStats = renderer.getStats();
QuantumStrategy qs =
renderer.getQuantumManager().getStrategyFor(channel);
CodomainChain cc = renderer.getCodomainChain();
// Retrieve the planar data to render
performanceStats.startIO(channel);
Plane2D plane =
PlaneFactory.createPlane(planeDef, channel, metadata, pixels);
performanceStats.endIO(channel);
RGBBuffer buf = getRgbBuffer();
byte value;
float alpha = channelBinding.getAlpha().floatValue() / 255;
int x1, x2, discreteValue, pixelIndex;
byte[] r = buf.getRedBand();
byte[] g = buf.getBlueBand();
byte[] b = buf.getGreenBand();
if (plane.isXYPlanar())
{
int planeSize = sizeX1 * sizeX2;
for (int i = 0; i < planeSize; i++)
{
for (x1 = 0; x1 < sizeX1; ++x1)
{
discreteValue = qs.quantize(plane.getPixelValue(i));
discreteValue = cc.transform(discreteValue);
value = (byte) (discreteValue * alpha);
r[i] = value;
g[i] = value;
b[i] = value;
}
}
}
else
{
for (x2 = 0; x2 < sizeX2; ++x2) {
for (x1 = 0; x1 < sizeX1; ++x1) {
pixelIndex = sizeX1 * x2 + x1;
discreteValue = qs.quantize(plane.getPixelValue(x1, x2));
discreteValue = cc.transform(discreteValue);
value = (byte) (discreteValue * alpha);
r[pixelIndex] = value;
g[pixelIndex] = value;
b[pixelIndex] = value;
}
}
}
return buf;
}
/**
* Implemented as specified by the superclass.
*
* @see RenderingStrategy#render(Renderer ctx, PlaneDef planeDef)
*/
@Override
RGBIntBuffer renderAsPackedInt(Renderer ctx, PlaneDef planeDef)
throws IOException, QuantizationException {
// Set the context and retrieve objects we're gonna use.
renderer = ctx;
// Initialize sizeX1 and sizeX2 according to the plane definition and
// create the RGB buffer.
Pixels metadata = renderer.getMetadata();
initAxesSize(planeDef, metadata);
if (!findFirstActiveChannelBinding())
{
return getIntBuffer();
}
PixelBuffer pixels = renderer.getPixels();
RenderingStats performanceStats = renderer.getStats();
QuantumStrategy qs =
renderer.getQuantumManager().getStrategyFor(channel);
CodomainChain cc = renderer.getCodomainChain();
// Retrieve the planar data to render
Plane2D plane;
try {
performanceStats.startIO(channel);
plane = PlaneFactory.createPlane(planeDef, channel, metadata, pixels);
performanceStats.endIO(channel);
} finally
{
try
{
pixels.close();
}
catch (IOException e)
{
log.error("Pixels could not be closed successfully.", e);
throw new ResourceError(
e.getMessage() + " Please check server log.");
}
}
RGBIntBuffer dataBuf = getIntBuffer();
int alpha = channelBinding.getAlpha();
int[] buf = ((RGBIntBuffer) dataBuf).getDataBuffer();
int x1, x2, discreteValue, pixelIndex;
if (plane.isXYPlanar())
{
int planeSize = sizeX1 * sizeX2;
for (int i = 0; i < planeSize; i++)
{
discreteValue = qs.quantize(plane.getPixelValue(i));
// Right now we have no transforms being used so it's safe to
// comment this out for the time being.
//discreteValue = cc.transform(discreteValue);
buf[i] = alpha << 24 | discreteValue << 16
| discreteValue << 8 | discreteValue;
}
}
else
{
for (x2 = 0; x2 < sizeX2; ++x2) {
pixelIndex = sizeX1 * x2;
for (x1 = 0; x1 < sizeX1; ++x1) {
discreteValue = qs.quantize(plane.getPixelValue(x1, x2));
discreteValue = cc.transform(discreteValue);
buf[pixelIndex + x1] = alpha << 24 | discreteValue << 16
| discreteValue << 8 | discreteValue;
}
}
}
return dataBuf;
}
/**
* Implemented as specified by the superclass.
*
* @see RenderingStrategy#renderAsPackedIntAsRGBA(Renderer ctx, PlaneDef planeDef)
*/
@Override
RGBAIntBuffer renderAsPackedIntAsRGBA(Renderer ctx, PlaneDef planeDef)
throws IOException, QuantizationException {
// Set the context and retrieve objects we're gonna use.
renderer = ctx;
// Initialize sizeX1 and sizeX2 according to the plane definition and
// create the RGB buffer.
Pixels metadata = renderer.getMetadata();
initAxesSize(planeDef, metadata);
if (!findFirstActiveChannelBinding())
{
return getRGBAIntBuffer();
}
PixelBuffer pixels = renderer.getPixels();
RenderingStats performanceStats = renderer.getStats();
QuantumStrategy qs =
renderer.getQuantumManager().getStrategyFor(channel);
CodomainChain cc = renderer.getCodomainChain();
// Retrieve the planar data to render
performanceStats.startIO(channel);
Plane2D plane =
PlaneFactory.createPlane(planeDef, channel, metadata, pixels);
performanceStats.endIO(channel);
RGBAIntBuffer dataBuf = getRGBAIntBuffer();
int alpha = channelBinding.getAlpha();
int[] buf = ((RGBAIntBuffer) dataBuf).getDataBuffer();
int x1, x2, discreteValue, pixelIndex;
if (plane.isXYPlanar())
{
int planeSize = sizeX1 * sizeX2;
for (int i = 0; i < planeSize; i++)
{
discreteValue = qs.quantize(plane.getPixelValue(i));
// Right now we have no transforms being used so it's safe to
// comment this out for the time being.
//discreteValue = cc.transform(discreteValue);
buf[i] = alpha | discreteValue << 24
| discreteValue << 16 | discreteValue << 8;
}
}
else
{
for (x2 = 0; x2 < sizeX2; ++x2) {
pixelIndex = sizeX1 * x2;
for (x1 = 0; x1 < sizeX1; ++x1) {
discreteValue = qs.quantize(plane.getPixelValue(x1, x2));
discreteValue = cc.transform(discreteValue);
buf[pixelIndex + x1] = alpha | discreteValue << 24
| discreteValue << 16 | discreteValue << 8;
}
}
}
return dataBuf;
}
/**
* Initializes the first active channel binding for the current rendering
* context.
*
* @return <code>true</code> when an active channel binding can be
* located and <code>false</code> otherwise.
*/
private boolean findFirstActiveChannelBinding()
{
ChannelBinding[] channelBindings = renderer.getChannelBindings();
for (int i = 0; i < channelBindings.length; i++)
{
if (channelBindings[i].getActive())
{
channel = i;
channelBinding = channelBindings[i];
return true;
}
}
return false;
}
/**
* Implemented as specified by the superclass.
*
* @see RenderingStrategy#getImageSize(PlaneDef, Pixels)
*/
@Override
int getImageSize(PlaneDef pd, Pixels pixels) {
initAxesSize(pd, pixels);
return sizeX1 * sizeX2 * 3;
}
/**
* Implemented as specified by the superclass.
*
* @see RenderingStrategy#getPlaneDimsAsString(PlaneDef, Pixels)
*/
@Override
String getPlaneDimsAsString(PlaneDef pd, Pixels pixels) {
initAxesSize(pd, pixels);
return sizeX1 + "x" + sizeX2;
}
}