// Default to TYPE_BYTE for floating point images only; otherwise keep unchanged.
targetType = sourceIsFloat ? SampleDimensionType.UNSIGNED_8BITS : sourceType;
}
// Default setting: no scaling
final boolean targetIsFloat = TypeMap.isFloatingPoint(targetType);
NumberRange targetRange = TypeMap.getRange(targetType);
Category[] categories = new Category[1];
final boolean needScaling;
if (targetIsFloat) {
// Never rescale if the target is floating point numbers.
needScaling = false;
} else if (sourceIsFloat) {
// Always rescale for "float to integer" conversions. In addition,
// Use 0 value as a "no data" category for unsigned data type only.
needScaling = true;
if (!TypeMap.isSigned(targetType)) {
categories = new Category[2];
categories[1] = Category.NODATA;
targetRange = TypeMap.getPositiveRange(targetType);
}
} else {
// In "integer to integer" conversions, rescale only if
// the target range is smaller than the source range.
needScaling = !targetRange.contains(TypeMap.getRange(sourceType));
}
/*
* Computes the minimal and maximal values, if not explicitely provided.
* This information is required for determining the range of geophysics
* values.
*/
if (needScaling && (min==null || max==null)) {
final boolean computeMin;
final boolean computeMax;
if (computeMin = (min == null)) {
min = new double[numBands];
Arrays.fill(min, Double.POSITIVE_INFINITY);
}
if (computeMax = (max == null)) {
max = new double[numBands];
Arrays.fill(max, Double.NEGATIVE_INFINITY);
}
int b = 0;
iterator.startBands();
if (!iterator.finishedBands()) do {
iterator.startLines();
if (!iterator.finishedLines()) do {
iterator.startPixels();
if (!iterator.finishedPixels()) do {
final double z = iterator.getSampleDouble();
if (computeMin && z<min[b]) min[b]=z;
if (computeMax && z>max[b]) max[b]=z;
} while (!iterator.nextPixelDone());
} while (!iterator.nextLineDone());
if (computeMin && computeMax) {
if (!(min[b] < max[b])) {
min[b] = 0;
max[b] = 1;
}
}
b++;
} while (!iterator.nextBandDone());
}
/*
* Now, constructs the sample dimensions. We will inconditionnaly provides a "nodata"
* category for floating point images targeting unsigned integers, since we don't know
* if the user plan to have NaN values. Even if the current image doesn't have NaN values,
* it could have NaN later if the image uses a writable raster.
*/
final InternationalString n = SimpleInternationalString.wrap(name);
NumberRange sourceRange = TypeMap.getRange(sourceType);
for (int b=0; b<numBands; b++) {
final Color[] c = colors!=null ? colors[b] : null;
if (needScaling) {
sourceRange = NumberRange.create(min[b], max[b]).castTo(sourceRange.getElementClass());
categories[0] = new Category(n, c, targetRange, sourceRange);
} else {
categories[0] = new Category(n, c, targetRange, LinearTransform1D.IDENTITY);
}
dst[b] = new GridSampleDimension(name,categories, units).geophysics(true);