org.geotools.image.io
Class GeographicImageReader

java.lang.Object
  extended by javax.imageio.ImageReader
      extended by org.geotools.image.io.GeographicImageReader
Direct Known Subclasses:
StreamImageReader

public abstract class GeographicImageReader
extends javax.imageio.ImageReader

Base class for readers of geographic images. The default implementation assumes that only one image type is supported (as opposed to the arbitrary number allowed by the standard ImageReader). It also provides a default image type built automatically from a color palette and a range of valid values.

More specifically, this class provides the following conveniences to implementors:

Images may be flat binary or ASCII files with no meta-data and no color information. Their pixel values may be floating point values instead of integers. The default implementation assumes floating point values and uses a grayscale color space scaled to fit the range of values. Displaying such an image may be very slow. Consequently, users who want to display image are encouraged to change data type and color space with Java Advanced Imaging operators after reading.

Since:
2.4
Version:
$Id: GeographicImageReader.java 31445 2008-09-07 18:14:23Z desruisseaux $
Author:
Martin Desruisseaux

Field Summary
 
Fields inherited from class javax.imageio.ImageReader
availableLocales, ignoreMetadata, input, locale, minIndex, originatingProvider, progressListeners, seekForwardOnly, updateListeners, warningListeners, warningLocales
 
Constructor Summary
protected GeographicImageReader(javax.imageio.spi.ImageReaderSpi provider)
          Constructs a new image reader.
 
Method Summary
protected  void checkBandIndex(int imageIndex, int bandIndex)
          Ensures that the specified band index is inside the expected range.
protected  void checkImageIndex(int imageIndex)
          Ensures that the specified image index is inside the expected range.
protected  boolean collapseNoDataValues(boolean isZeroValid, double[] nodataValues, int unusedSpace)
          Returns true if the no-data values should be collapsed to 0 in order to save memory.
protected static void flipVertically(javax.imageio.ImageReadParam param, int srcHeight, java.awt.Rectangle srcRegion)
          Flips the source region vertically.
 javax.imageio.ImageReadParam getDefaultReadParam()
          Returns a default parameter object appropriate for this format.
protected  java.awt.image.BufferedImage getDestination(int imageIndex, javax.imageio.ImageReadParam parameters, int width, int height, SampleConverter[] converters)
          Returns the buffered image to which decoded pixel data should be written.
 int getDimension(int imageIndex)
          Returns the number of dimension of the image at the given index.
 GeographicMetadata getGeographicMetadata(int imageIndex)
          Returns a helper parser for metadata associated with the given image.
 javax.imageio.metadata.IIOMetadata getImageMetadata(int imageIndex)
          Returns metadata associated with the given image.
 java.util.Iterator<javax.imageio.ImageTypeSpecifier> getImageTypes(int imageIndex)
          Returns a collection of ImageTypeSpecifier containing possible image types to which the given image may be decoded.
 int getNumBands(int imageIndex)
          Returns the number of bands available for the specified image.
 int getNumImages(boolean allowSearch)
          Returns the number of images available from the current input source.
protected  int getRawDataType(int imageIndex)
          Returns the data type which most closely represents the "raw" internal data of the image.
 javax.imageio.ImageTypeSpecifier getRawImageType(int imageIndex)
          Returns an image type specifier indicating the SampleModel and ColorModel which most closely represents the "raw" internal format of the image.
protected  javax.imageio.ImageTypeSpecifier getRawImageType(int imageIndex, javax.imageio.ImageReadParam parameters, SampleConverter[] converters)
          Returns an image type specifier indicating the SampleModel and ColorModel which most closely represents the "raw" internal format of the image.
 javax.imageio.metadata.IIOMetadata getStreamMetadata()
          Returns metadata associated with the input source as a whole.
 java.awt.image.BufferedImage read(int imageIndex)
          Reads the image indexed by imageIndex using a default ImageReadParam.
 void setInput(java.lang.Object input, boolean seekForwardOnly, boolean ignoreMetadata)
          Sets the input source to use.
 void warningOccurred(java.util.logging.LogRecord record)
          Invoked when a warning occured.
 
Methods inherited from class javax.imageio.ImageReader
abort, abortRequested, addIIOReadProgressListener, addIIOReadUpdateListener, addIIOReadWarningListener, canReadRaster, checkReadParamBandSettings, clearAbortRequest, computeRegions, dispose, getAspectRatio, getAvailableLocales, getDestination, getFormatName, getHeight, getImageMetadata, getInput, getLocale, getMinIndex, getNumThumbnails, getOriginatingProvider, getSourceRegion, getStreamMetadata, getThumbnailHeight, getThumbnailWidth, getTileGridXOffset, getTileGridYOffset, getTileHeight, getTileWidth, getWidth, hasThumbnails, isIgnoringMetadata, isImageTiled, isRandomAccessEasy, isSeekForwardOnly, processImageComplete, processImageProgress, processImageStarted, processImageUpdate, processPassComplete, processPassStarted, processReadAborted, processSequenceComplete, processSequenceStarted, processThumbnailComplete, processThumbnailPassComplete, processThumbnailPassStarted, processThumbnailProgress, processThumbnailStarted, processThumbnailUpdate, processWarningOccurred, processWarningOccurred, read, readAll, readAll, readAsRenderedImage, readerSupportsThumbnails, readRaster, readThumbnail, readTile, readTileRaster, removeAllIIOReadProgressListeners, removeAllIIOReadUpdateListeners, removeAllIIOReadWarningListeners, removeIIOReadProgressListener, removeIIOReadUpdateListener, removeIIOReadWarningListener, reset, setInput, setInput, setLocale
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

GeographicImageReader

protected GeographicImageReader(javax.imageio.spi.ImageReaderSpi provider)
Constructs a new image reader.

Parameters:
provider - The ImageReaderSpi that is invoking this constructor, or null if none.
Method Detail

setInput

public void setInput(java.lang.Object input,
                     boolean seekForwardOnly,
                     boolean ignoreMetadata)
Sets the input source to use.

Overrides:
setInput in class javax.imageio.ImageReader
Parameters:
input - The input object to use for future decoding.
seekForwardOnly - If true, images and metadata may only be read in ascending order from this input source.
ignoreMetadata - If true, metadata may be ignored during reads.

checkImageIndex

protected void checkImageIndex(int imageIndex)
                        throws java.io.IOException,
                               java.lang.IndexOutOfBoundsException
Ensures that the specified image index is inside the expected range. The expected range is minIndex inclusive (initially 0) to getNumImages(false) exclusive.

Parameters:
imageIndex - Index to check for validity.
Throws:
java.lang.IndexOutOfBoundsException - if the specified index is outside the expected range.
java.io.IOException - If the operation failed because of an I/O error.

checkBandIndex

protected void checkBandIndex(int imageIndex,
                              int bandIndex)
                       throws java.io.IOException,
                              java.lang.IndexOutOfBoundsException
Ensures that the specified band index is inside the expected range. The expected range is 0 inclusive to getNumBands(imageIndex) exclusive.

Parameters:
imageIndex - The image index.
bandIndex - Index to check for validity.
Throws:
java.lang.IndexOutOfBoundsException - if the specified index is outside the expected range.
java.io.IOException - If the operation failed because of an I/O error.

getNumImages

public int getNumImages(boolean allowSearch)
                 throws java.lang.IllegalStateException,
                        java.io.IOException
Returns the number of images available from the current input source. The default implementation returns 1.

Specified by:
getNumImages in class javax.imageio.ImageReader
Parameters:
allowSearch - If true, the number of images will be returned even if a search is required.
Returns:
The number of images, or -1 if allowSearch is false and a search would be required.
Throws:
java.lang.IllegalStateException - if the input source has not been set.
java.io.IOException - if an error occurs reading the information from the input source.

getNumBands

public int getNumBands(int imageIndex)
                throws java.io.IOException
Returns the number of bands available for the specified image. The default implementation returns 1.

Parameters:
imageIndex - The image index.
Throws:
java.io.IOException - if an error occurs reading the information from the input source.

getDimension

public int getDimension(int imageIndex)
                 throws java.io.IOException
Returns the number of dimension of the image at the given index. The default implementation always returns 2.

Parameters:
imageIndex - The image index.
Returns:
The number of dimension for the image at the given index.
Throws:
java.io.IOException - if an error occurs reading the information from the input source.
Since:
2.5

getStreamMetadata

public javax.imageio.metadata.IIOMetadata getStreamMetadata()
                                                     throws java.io.IOException
Returns metadata associated with the input source as a whole. Since many raw images can't store metadata, the default implementation returns null.

Specified by:
getStreamMetadata in class javax.imageio.ImageReader
Throws:
java.io.IOException - if an error occurs during reading.

getImageMetadata

public javax.imageio.metadata.IIOMetadata getImageMetadata(int imageIndex)
                                                    throws java.io.IOException
Returns metadata associated with the given image. Since many raw images can't store metadata, the default implementation returns null.

Specified by:
getImageMetadata in class javax.imageio.ImageReader
Parameters:
imageIndex - The image index.
Returns:
The metadata, or null if none.
Throws:
java.io.IOException - if an error occurs during reading.

getGeographicMetadata

public GeographicMetadata getGeographicMetadata(int imageIndex)
                                         throws java.io.IOException
Returns a helper parser for metadata associated with the given image. This implementation invokes getImageMetadata(imageIndex), wraps the result in a GeographicMetadata object if non-null and caches the result.

Note that this method forces ImageReader.ignoreMetadata to false for the time of getImageMetadata(imageIndex) execution, because some image reader implementations need geographic metadata in order to infer a valid color model.

Parameters:
imageIndex - The image index.
Returns:
The geographic metadata, or null if none.
Throws:
java.io.IOException - if an error occurs during reading.

getImageTypes

public java.util.Iterator<javax.imageio.ImageTypeSpecifier> getImageTypes(int imageIndex)
                                                                   throws java.io.IOException
Returns a collection of ImageTypeSpecifier containing possible image types to which the given image may be decoded. The default implementation returns a singleton containing getRawImageType(imageIndex).

Specified by:
getImageTypes in class javax.imageio.ImageReader
Parameters:
imageIndex - The index of the image to be retrieved.
Returns:
A set of suggested image types for decoding the current given image.
Throws:
java.io.IOException - If an error occurs reading the format information from the input source.

getRawImageType

public javax.imageio.ImageTypeSpecifier getRawImageType(int imageIndex)
                                                 throws java.io.IOException
Returns an image type specifier indicating the SampleModel and ColorModel which most closely represents the "raw" internal format of the image. The default implementation delegates to the following:
getRawImageType(imageIndex, getDefaultReadParam(), null);
If this method needs to be overriden, consider overriding the later instead.

Overrides:
getRawImageType in class javax.imageio.ImageReader
Parameters:
imageIndex - The index of the image to be queried.
Returns:
The image type (never null).
Throws:
java.io.IOException - If an error occurs reading the format information from the input source.

getRawImageType

protected javax.imageio.ImageTypeSpecifier getRawImageType(int imageIndex,
                                                           javax.imageio.ImageReadParam parameters,
                                                           SampleConverter[] converters)
                                                    throws java.io.IOException
Returns an image type specifier indicating the SampleModel and ColorModel which most closely represents the "raw" internal format of the image. The default implementation applies the following rules:
  1. The range of expected values and the no-data values are extracted from the geographic metadata, if any.

  2. If the given parameters argument is an instance of GeographicImageReadParam, then the user-supplied palette name is fetched. Otherwise or if no palette name was explicitly set, then this method default to "rainbow". The palette name will be used in order to read a predefined set of colors (as RGB values) to be given to the index color model.

  3. If the raw data type is TYPE_FLOAT or TYPE_DOUBLE, then this method builds a continuous palette suitable for the range fetched at step 1. The data are assumed geophysics values rather than some packed values. Consequently, the sample converters will replace no-data values by NaN with no other changes.

  4. Otherwise, if the raw data type is a unsigned integer type like TYPE_BYTE or TYPE_USHORT, then this method builds an indexed palette (i.e. a palette backed by an index color model) with just the minimal size needed for containing fully the range and the no-data values fetched at step 1. The data are assumed packed values rather than geophysics values. Consequently, the sample converters will be the identity converter except in the following cases:

    • The range of valid values is outside the range allowed by the raw data type (e.g. the range of valid values contains negative integers). In this case, the sample converter will shift the values to a strictly positive range and replace no-data values by 0.
    • At least one no-data value is outside the range of values allowed by the raw data type. In this case, this method will try to only replace the no-data values by 0, without shifting the valid values if this shift can be avoided.
    • At least one no-data value is far away from the range of valid values (for example 9999 while the range of valid values is [0..255]). The meaning of "far away" is determined by the collapseNoDataValues method.

  5. Otherwise, if the raw data type is a signed integer type like TYPE_SHORT, then this method builds an indexed palette with the maximal size supported by the raw data type (note that this is memory expensive - typically 256 kilobytes). Negative values will be stored in their two's complement binary form in order to fit in the range of positive integers supported by the index color model.

Overriding this method

Subclasses may override this method when a constant color palette is wanted for all images in a series, for example for all Sea Surface Temperature (SST) from the same provider. A constant color palette facilitates the visual comparaison of different images at different time. The example below creates hard-coded objects:
int minimum = -2000; // minimal expected value
int maximum = +2300; //
maximal expected value
int fillValue = -9999; //
Value for missing data
String palette = "SST-Nasa";//
Named set of RGB colors
converters[0] = SampleConverter.createOffset(1 - minimum, fillValue);
return PaletteFactory.getDefault().getPalettePadValueFirst(paletteName, maximum - minimum).getImageTypeSpecifier();

Parameters:
imageIndex - The index of the image to be queried.
parameters - The user-supplied parameters, or null. Note: we recommand to supply getDefaultReadParam() instead of null since subclasses may override the later with default values suitable to a particular format.
converters - If non-null, an array where to store the converters created by this method. Those converters should be used by read(imageIndex, parameters) implementations for converting the values read in the datafile to values acceptable for the underling color model.
Returns:
The image type (never null).
Throws:
java.io.IOException - If an error occurs while reading the format information from the input source.
See Also:
getRawDataType(int), collapseNoDataValues(boolean, double[], int), getDestination(int, ImageReadParam, int, int, SampleConverter[])

getRawDataType

protected int getRawDataType(int imageIndex)
                      throws java.io.IOException
Returns the data type which most closely represents the "raw" internal data of the image. It should be one of DataBuffer constants. The default GeographicImageReader implementation works better with the following types: TYPE_BYTE, TYPE_SHORT, TYPE_USHORT and TYPE_FLOAT. The default implementation returns TYPE_FLOAT in every cases.

Handling of negative integer values

If the raw internal data contains negative values but this method still declares a unsigned integer type (TYPE_BYTE or TYPE_USHORT), then the values will be translated in order to fit in the range of strictly positive values. For example if the raw internal data range from -23000 to +23000, then there is a choice:

Parameters:
imageIndex - The index of the image to be queried.
Returns:
The data type (DataBuffer.TYPE_FLOAT by default).
Throws:
java.io.IOException - If an error occurs reading the format information from the input source.
See Also:
getRawImageType(int, ImageReadParam, SampleConverter[])

collapseNoDataValues

protected boolean collapseNoDataValues(boolean isZeroValid,
                                       double[] nodataValues,
                                       int unusedSpace)
Returns true if the no-data values should be collapsed to 0 in order to save memory. This method is invoked automatically by the getRawImageType method when it detected some unused space between the range of valid values and at least one no-data value.

The default implementation returns false in all cases, thus avoiding arbitrary choice. Subclasses can override this method with some arbitrary threashold, as in the example below:

 return unusedSpace >= 1024;
 

Parameters:
isZeroValid - true if 0 is a valid value. If this method returns true while isZeroValid is true, then the sample converter to be returned by getRawImageType will offset all valid values by 1.
nodataValues - The sorted no-data values (never null and never empty).
unusedSpace - The largest amount of unused space outside the range of valid values.

getDestination

protected java.awt.image.BufferedImage getDestination(int imageIndex,
                                                      javax.imageio.ImageReadParam parameters,
                                                      int width,
                                                      int height,
                                                      SampleConverter[] converters)
                                               throws java.io.IOException
Returns the buffered image to which decoded pixel data should be written. The image is determined by inspecting the supplied parameters if it is non-null, as described in the super-class method. In the default implementation, the image type specifier set is a singleton containing only the raw image type.

Implementations of the ImageReader.read(int,ImageReadParam) method should invoke this method instead of ImageReader.getDestination(ImageReadParam,Iterator,int,int).

Parameters:
imageIndex - The index of the image to be retrieved.
parameters - The parameter given to the read method.
width - The true width of the image or tile begin decoded.
height - The true width of the image or tile being decoded.
converters - If non-null, an array where to store the converters required for converting decoded pixel data into stored pixel data.
Returns:
The buffered image to which decoded pixel data should be written.
Throws:
java.io.IOException - If an error occurs reading the format information from the input source.
See Also:
getRawImageType(int, ImageReadParam, SampleConverter[])

getDefaultReadParam

public javax.imageio.ImageReadParam getDefaultReadParam()
Returns a default parameter object appropriate for this format. The default implementation constructs and returns a new GeographicImageReadParam.

Overrides:
getDefaultReadParam in class javax.imageio.ImageReader
Returns:
An ImageReadParam object which may be used.

read

public java.awt.image.BufferedImage read(int imageIndex)
                                  throws java.io.IOException
Reads the image indexed by imageIndex using a default ImageReadParam. This is a convenience method that calls read(imageIndex, getDefaultReadParam()).

The default Java implementation passed a null parameter. This implementation passes the default parameter instead in order to improve consistency when a subclass overrides getDefaultReadParam().

Overrides:
read in class javax.imageio.ImageReader
Parameters:
imageIndex - the index of the image to be retrieved.
Returns:
the desired portion of the image.
Throws:
java.lang.IllegalStateException - if the input source has not been set.
java.lang.IndexOutOfBoundsException - if the supplied index is out of bounds.
java.io.IOException - if an error occurs during reading.

flipVertically

protected static void flipVertically(javax.imageio.ImageReadParam param,
                                     int srcHeight,
                                     java.awt.Rectangle srcRegion)
Flips the source region vertically. This method should be invoked straight after computeRegions when the image to be read will be flipped vertically, for example when the raster sample values are filled in a "for (y=ymax-1; y>=ymin; y--)" loop instead of "for (y=ymin; y<ymax; y++)".

This method should be invoked as in the example below:

 computeRegions(param, srcWidth, srcHeight, image, srcRegion, destRegion);
 flipVertically(param, srcHeight, srcRegion);
 

Parameters:
param - The param argument given to computeRegions.
srcHeight - The srcHeight argument given to computeRegions.
srcRegion - The srcRegion argument given to computeRegions.

warningOccurred

public void warningOccurred(java.util.logging.LogRecord record)
Invoked when a warning occured. The default implementation make the following choice:

Subclasses may override this method if more processing is wanted, or for throwing exception if some warnings should be considered as fatal errors.



Copyright © 1996-2010 Geotools. All Rights Reserved.