package mil.nga.giat.geowave.adapter.raster.stats;
import java.awt.image.SampleModel;
import java.nio.ByteBuffer;
import mil.nga.giat.geowave.core.index.Persistable;
import org.geotools.coverage.TypeMap;
import org.geotools.util.NumberRange;
public class HistogramConfig implements
Persistable
{
private static final int MAX_DEFAULT_NUM_BINS = 65536;
private double[] highValues;
private double[] lowValues;
private int[] numBins;
protected HistogramConfig() {}
public HistogramConfig(
final SampleModel sampleModel ) {
final int numBands = sampleModel.getNumBands();
highValues = new double[numBands];
lowValues = new double[numBands];
numBins = new int[numBands];
for (int b = 0; b < numBands; b++) {
final NumberRange range = TypeMap.getRange(TypeMap.getSampleDimensionType(
sampleModel,
b));
int bins;
double min = range.getMinimum(true);
double max = range.getMaximum(true);
if (Double.isInfinite(min) || Double.isInfinite(max) || Double.isNaN(min) || Double.isNaN(max)) {
// in this case there is no reasonable default, just use a range
// of 0 to 1 as a placeholder
min = 0;
max = 1;
bins = MAX_DEFAULT_NUM_BINS;
}
else {
bins = (int) Math.min(
MAX_DEFAULT_NUM_BINS,
(max - min) + 1);
}
lowValues[b] = min;
highValues[b] = max;
numBins[b] = bins;
}
}
public HistogramConfig(
final double[] highValues,
final double[] lowValues,
final int[] numBins ) {
this.highValues = highValues;
this.lowValues = lowValues;
this.numBins = numBins;
}
@Override
public byte[] toBinary() {
// constant number of bands, 8 + 8 + 4 bytes per band (high,low, and
// numBins), and 4 more for the total bands
final ByteBuffer buf = ByteBuffer.allocate((20 * highValues.length) + 4);
buf.putInt(highValues.length);
for (int b = 0; b < highValues.length; b++) {
buf.putDouble(lowValues[b]);
buf.putDouble(highValues[b]);
buf.putInt(numBins[b]);
}
return buf.array();
}
public double[] getHighValues() {
return highValues;
}
public double[] getLowValues() {
return lowValues;
}
public int[] getNumBins() {
return numBins;
}
@Override
public void fromBinary(
final byte[] bytes ) {
final ByteBuffer buf = ByteBuffer.wrap(bytes);
final int numBands = buf.getInt();
highValues = new double[numBands];
lowValues = new double[numBands];
numBins = new int[numBands];
for (int b = 0; b < numBands; b++) {
lowValues[b] = buf.getDouble();
highValues[b] = buf.getDouble();
numBins[b] = buf.getInt();
}
}
}