* This method it aimed to computing a tile size such that the tile grid would have overlapped * the image bound in order to avoid having tiles crossing the image bounds and being therefore * partially empty. This method will never returns a tile size smaller than * {@value ImageUtilities#GEOTOOLS_MIN_TILE_SIZE}. If this method can't suggest a size, * then it left the corresponding {@code size} field ({@link Dimension#width width} or * {@link Dimension#height height}) unchanged. *
* The {@link Dimension#width width} and {@link Dimension#height height} fields are processed * independently in the same way. The following discussion use the {@code width} field as an * example. *
* This method inspects different tile sizes close to the {@linkplain JAI#getDefaultTileSize() * default tile size}. Lets {@code width} be the default tile width. Values are tried in the * following order: {@code width}, {@code width+1}, {@code width-1}, {@code width+2}, * {@code width-2}, {@code width+3}, {@code width-3}, etc. until one of the * following happen: *
*
* Implementation note: the current implementation assume that JAI codec
* class name start with "CLib". It work for Sun's 1.0 implementation, but may change in
* future versions. If this method doesn't recognize the class name, it does nothing.
*
* @param format The format name (e.g. "png").
* @param category {@code ImageReaderSpi.class} to set the reader, or
* {@code ImageWriterSpi.class} to set the writer.
* @param allowed {@code false} to disallow native acceleration.
* @deprecated Use {@link ImageIOExt#allowNativeCodec(String, Class, boolean)} instead
*/
public static synchronized
* In case no reader is found,
* Notice that none of the input parameters can be
* Input parameters cannot be null.
*
* @param readParameters
* an instance of {@link ImageReadParam} for which we want to
* check the source region element.
* @param dimensions
* an instance of {@link Rectangle} to use for the check.
* @return true
otherwise.
*/
public static boolean isMediaLibAvailable() {
return mediaLibAvailable;
}
/**
* Tells me whether or not the native libraries for JAI/ImageIO are active or not.
*
* @return false
in case the JAI/ImageIO native libs are not in the path, true
otherwise.
* @deprecated Use {@link ImageIOExt#isCLibAvailable()} instead
*/
public static boolean isCLibAvailable() {
return PackageUtil.isCodecLibAvailable();
}
/**
* Get a proper {@link ImageInputStreamSpi} instance for the provided {@link Object} input without
* trying to create an {@link ImageInputStream}.
*
* @see #getImageInputStreamSPI(Object, boolean)
* @deprecated Use {@link ImageIOExt#getImageInputStreamSPI(Object, boolean)} instead
*/
public final static ImageInputStreamSpi getImageInputStreamSPI(final Object input) {
return ImageIOExt.getImageInputStreamSPI(input);
}
/**
* Get a proper {@link ImageInputStreamSpi} instance for the provided {@link Object} input.
*
* @param input the input object for which we need to find a proper {@link ImageInputStreamSpi} instance
* @param streamCreationCheck if true
, when a proper {@link ImageInputStreamSpi} have been found
* for the provided input, use it to try creating an {@link ImageInputStream} on top of the input.
*
* @return an {@link ImageInputStreamSpi} instance.
* @deprecated Use {@link ImageIOExt#getImageInputStreamSPI(Object, boolean)} instead
*/
public final static ImageInputStreamSpi getImageInputStreamSPI(final Object input, final boolean streamCreationCheck) {
return ImageIOExt.getImageInputStreamSPI(input, streamCreationCheck);
}
/**
* Dispose an image with all its ancestors.
*
* @param pi the {@link PlanarImage} to dispose.
*/
public static void disposePlanarImageChain(PlanarImage pi) {
Utilities.ensureNonNull("PlanarImage", pi);
disposePlanarImageChain(pi, new HashSetnull
is returned.
*
* @param inStream
* an instance of {@link ImageInputStream} for which we need to
* find a suitable {@link ImageReader}.
* @return a suitable instance of {@link ImageReader} or null
* if one cannot be found.
* @deprecated Use {@link ImageIOExt#getImageioReader(ImageInputStream)} instead
*/
static public ImageReader getImageioReader(final ImageInputStream inStream) {
return ImageIOExt.getImageioReader(inStream);
}
/**
* Builds a {@link ReferencedEnvelope} from a {@link GeographicBoundingBox}.
* This is useful in order to have an implementation of {@link BoundingBox}
* from a {@link GeographicBoundingBox} which strangely does implement
* {@link GeographicBoundingBox}.
*
* @param geographicBBox
* the {@link GeographicBoundingBox} to convert.
* @return an instance of {@link ReferencedEnvelope}.
*/
static public ReferencedEnvelope getReferencedEnvelopeFromGeographicBoundingBox(
final GeographicBoundingBox geographicBBox) {
Utilities.ensureNonNull("GeographicBoundingBox", geographicBBox);
return new ReferencedEnvelope(geographicBBox.getEastBoundLongitude(),
geographicBBox.getWestBoundLongitude(), geographicBBox
.getSouthBoundLatitude(), geographicBBox
.getNorthBoundLatitude(), DefaultGeographicCRS.WGS84);
}
/**
* Builds a {@link ReferencedEnvelope} in WGS84 from a {@link GeneralEnvelope}.
*
* @param coverageEnvelope
* the {@link GeneralEnvelope} to convert.
* @return an instance of {@link ReferencedEnvelope} in WGS84 or null
in case a problem during the conversion occurs.
*/
static public ReferencedEnvelope getWGS84ReferencedEnvelope(
final GeneralEnvelope coverageEnvelope) {
Utilities.ensureNonNull("coverageEnvelope", coverageEnvelope);
final ReferencedEnvelope refEnv= new ReferencedEnvelope(coverageEnvelope);
try{
return refEnv.transform(DefaultGeographicCRS.WGS84, true);
}catch (Exception e) {
return null;
}
}
/**
* Retrieves the dimensions of the {@link RenderedImage} at index
* imageIndex
for the provided {@link ImageReader} and
* {@link ImageInputStream}.
*
* null
or a
* {@link NullPointerException} will be thrown. Morevoer the
* imageIndex
cannot be negative or an
* {@link IllegalArgumentException} will be thrown.
*
* @param imageIndex
* the index of the image to get the dimensions for.
* @param inStream
* the {@link ImageInputStream} to use as an input
* @param reader
* the {@link ImageReader} to decode the image dimensions.
* @return a {@link Rectangle} that contains the dimensions for the image at
* index imageIndex
* @throws IOException
* in case the {@link ImageReader} or the
* {@link ImageInputStream} fail.
*/
public static Rectangle getDimension(final int imageIndex,
final ImageInputStream inStream, final ImageReader reader)
throws IOException {
Utilities.ensureNonNull("inStream", inStream);
Utilities.ensureNonNull("reader", reader);
if (imageIndex < 0)
throw new IllegalArgumentException(Errors.format(
ErrorKeys.INDEX_OUT_OF_BOUNDS_$1, imageIndex));
inStream.reset();
reader.setInput(inStream);
return new Rectangle(0, 0, reader.getWidth(imageIndex), reader
.getHeight(imageIndex));
}
/**
* Checks that the provided dimensions
when intersected with
* the source region used by the provided {@link ImageReadParam} instance
* does not result in an empty {@link Rectangle}.
*
* true
if the intersection is not empty,
* false
otherwise.
*/
public final static boolean checkEmptySourceRegion(final ImageReadParam readParameters,
final Rectangle dimensions) {
Utilities.ensureNonNull("readDimension", dimensions);
Utilities.ensureNonNull("readP", readParameters);
final Rectangle sourceRegion = readParameters.getSourceRegion();
Rectangle.intersect(sourceRegion, dimensions, sourceRegion);
if (sourceRegion.isEmpty())
return true;
readParameters.setSourceRegion(sourceRegion);
return false;
}
/**
* Build a background values array using the same dataType of the input {@link SampleModel} (if
* available) and the values provided in the input array.
*
* @param sampleModel
* @param backgroundValues
* @return
*/
public static Number[] getBackgroundValues(final SampleModel sampleModel, final double[] backgroundValues) {
Number[] values = null;
final int dataType = sampleModel != null ? sampleModel.getDataType() : DataBuffer.TYPE_DOUBLE;
final int numBands=sampleModel != null? sampleModel.getNumBands() : 1;
switch (dataType){
case DataBuffer.TYPE_BYTE:
values = new Byte[numBands];
if (backgroundValues == null){
Arrays.fill(values, Byte.valueOf((byte)0));
}
else{
//we have background values available
for (int i = 0; i < values.length; i++)
values[i] = i>=backgroundValues.length?Byte.valueOf((byte)backgroundValues[0]):Byte.valueOf((byte)backgroundValues[i]);
}
break;
case DataBuffer.TYPE_SHORT:
case DataBuffer.TYPE_USHORT:
values = new Short[numBands] ;
if (backgroundValues == null)
Arrays.fill(values, Short.valueOf((short)0));
else {
//we have background values available
for (int i = 0; i < values.length; i++)
values[i] = i>=backgroundValues.length?Short.valueOf((short)backgroundValues[0]):Short.valueOf((short)backgroundValues[i]);
}
break;
case DataBuffer.TYPE_INT:
values = new Integer[numBands] ;
if (backgroundValues == null)
Arrays.fill(values, Integer.valueOf((int) 0));
else {
// we have background values available
for (int i = 0; i < values.length; i++)
values[i] = i >= backgroundValues.length ? Integer.valueOf((int) backgroundValues[0]) : Integer.valueOf((int) backgroundValues[i]);
}
break;
case DataBuffer.TYPE_FLOAT:
values = new Float[numBands] ;
if (backgroundValues == null)
Arrays.fill(values, Float.valueOf(0.f));
else{
//we have background values available
for (int i = 0; i < values.length; i++)
values[i] = i>=backgroundValues.length?Float.valueOf((float)backgroundValues[0]):Float.valueOf((float)backgroundValues[i]);
}
break;
case DataBuffer.TYPE_DOUBLE:
values = new Double[numBands] ;
if (backgroundValues == null)
Arrays.fill(values, Double.valueOf(0.d));
else {
//we have background values available
for (int i = 0; i < values.length; i++)
values[i] = i>=backgroundValues.length?Double.valueOf((Double)backgroundValues[0]):Double.valueOf((Double)backgroundValues[i]);
}
break;
}
return values;
}
}