* the rectangle within the destination to be written.
*/
protected void computeRect(final PlanarImage[] sources,
final WritableRaster dest, final Rectangle destRect) {
final PlanarImage source = sources[0];
WritableRectIter iterator = RectIterFactory.createWritable(dest,
destRect);
if (true) {
// TODO: Detect if source and destination rasters are the same. If
// they are the same, we should skip this block. Iteration will then
// be faster.
iterator = TransfertRectIter.create(RectIterFactory.create(source,
destRect), iterator);
}
// ////////////////////////////////////////////////////////////////////
//
// Prepare the iterator to work on the correct bands, if this is
// requested.
//
// ////////////////////////////////////////////////////////////////////
if (!iterator.finishedBands()) {
for (int i = 0; i < bandIndex; i++)
iterator.nextBand();
}
// ////////////////////////////////////////////////////////////////////
//
// Check if we can make good use of a no data category for filling gaps
// in the input range
//
// ////////////////////////////////////////////////////////////////////
double gapsValue = Double.NaN;
boolean hasGapsValue = false;
if (this.pieces.hasDefaultValue()) {
gapsValue = this.pieces.getDefaultValue();
hasGapsValue = true;
}
// ////////////////////////////////////////////////////////////////////
//
// Check if we can optimize this operation by reusing the last used
// category first. The speed up we get can be substantial since we avoid
// n explicit search in the category list for the fitting category given
// a certain sample value.
//
// This is not possible when the NoDataCategories range overlaps with
// the range of the valid values. In this case we have ALWAYS to check
// first the NoDataRange when applying transformations. If we optimized
// in this case we would get erroneous results given to the fact that we
// might be reusing a valid sample category while we should be using a
// no data one.
//
// ////////////////////////////////////////////////////////////////////
PiecewiseTransform1DElement last = null;
final boolean useLast = pieces instanceof DefaultDomain1D;
do {
try {
iterator.startLines();
if (!iterator.finishedLines())
do {
iterator.startPixels();
if (!iterator.finishedPixels())
do {
// //
//
// get the input value to be transformed
//
// //
final double value = iterator.getSampleDouble();
// //
//
// get the correct category for this
// transformation
//
// //
final PiecewiseTransform1DElement transform;
if (useLast) {
if (last != null && last.contains(value))
transform = last;
else {
last = transform = pieces.findDomainElement(value);
}
} else
transform = (PiecewiseTransform1DElement) pieces.findDomainElement(value);
// //
//
// in case everything went fine let's apply the
// transform.
//
// //
if (transform != null)
iterator.setSample(transform.transform(value));
else {
// //
//
// if we did not find one let's try to use
// one of the nodata ones to fill the gaps,
// if we are allowed to (see above).
//
// //
if (hasGapsValue)
iterator.setSample(gapsValue);
else
// //
//
// if we did not find one let's throw a
// nice error message
//
// //
throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, Double.toString(value)));
}
} while (!iterator.nextPixelDone());
} while (!iterator.nextLineDone());
} catch (Throwable cause) {
throw new ImagingException(
cause.getLocalizedMessage(),cause);
}
if (bandIndex != -1)
break;
} while (iterator.finishedBands());
}