package gdsc.smlm.results;
import java.awt.Rectangle;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/*-----------------------------------------------------------------------------
* GDSC SMLM Software
*
* Copyright (C) 2013 Alex Herbert
* Genome Damage and Stability Centre
* University of Sussex, UK
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------*/
/**
* Represent a named results source. Does not support data provision.
*/
public class MemoryImageSource extends ImageSource
{
@XStreamOmitField
private int counter;
private float[][] data;
private boolean freeMemoryOnClose;
/**
* Create a new image source
*/
public MemoryImageSource(int width, int height, float[]... data)
{
super("Memory");
if (width < 1)
throw new IllegalArgumentException("Width must be above zero");
if (height < 1)
throw new IllegalArgumentException("Height must be above zero");
if (data == null)
throw new IllegalArgumentException("Image data must not be null");
final int length = width * height;
for (float[] f : data)
{
if (f == null)
throw new IllegalArgumentException("Image data must not be null");
if (f.length != length)
throw new IllegalArgumentException("Image data length does not match width*height");
}
this.width = width;
this.height = height;
this.data = data;
this.frames = data.length;
}
/*
* (non-Javadoc)
*
* @see gdsc.smlm.results.ImageSource#openSource()
*/
@Override
protected boolean openSource()
{
counter = 0;
return true;
}
/*
* (non-Javadoc)
*
* @see gdsc.smlm.results.ImageSource#close()
*/
@Override
public void close()
{
// Free the memory
if (freeMemoryOnClose)
data = new float[0][0];
}
/*
* (non-Javadoc)
*
* @see gdsc.smlm.results.ImageSource#nextFrame(java.awt.Rectangle)
*/
@Override
protected float[] nextFrame(Rectangle bounds)
{
if (counter < data.length)
return getFrame(++counter, bounds);
return null;
}
/*
* (non-Javadoc)
*
* @see gdsc.smlm.results.ImageSource#getFrame(int, java.awt.Rectangle)
*/
@Override
protected float[] getFrame(int frame, Rectangle bounds)
{
if (frame > 0 && frame <= data.length)
{
if (checkBounds(bounds))
{
final float[] pixels = data[frame - 1];
float[] pixels2 = new float[bounds.width * bounds.height];
for (int ys = bounds.y; ys < bounds.y + bounds.height; ys++)
{
int offset1 = (ys - bounds.y) * bounds.width;
int offset2 = ys * width + bounds.x;
for (int xs = 0; xs < bounds.width; xs++)
pixels2[offset1++] = pixels[offset2++];
}
return pixels2;
}
else
{
return data[frame - 1];
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see gdsc.smlm.results.ImageSource#isValid(int)
*/
@Override
public boolean isValid(int frame)
{
return (frame > 0 && frame <= data.length);
}
/**
* @return Set to true if freeing the memory on calling {@link #close()}
*/
public boolean isFreeMemoryOnClose()
{
return freeMemoryOnClose;
}
/**
* Set this to true to free the memory when the {@link #close()} method is called. No subsequent calls to
* {@link #open()} will be valid.
*
* @param freeMemoryOnClose
* Set to true to free the memory on calling {@link #close()}
*/
public void setFreeMemoryOnClose(boolean freeMemoryOnClose)
{
this.freeMemoryOnClose = freeMemoryOnClose;
}
}