Class SparseTIFFImageReader

java.lang.Object
javax.imageio.ImageReader
it.geosolutions.imageioimpl.plugins.tiff.TIFFImageReader
nz.org.riskscape.engine.tiff.SparseTIFFImageReader

public class SparseTIFFImageReader extends it.geosolutions.imageioimpl.plugins.tiff.TIFFImageReader

Extends the default TIFFImageReader to add support for querying empty tiles, so that sampling operations can avoid initializing and indexing tiles (float[]s) full of zeroes.

Some hazard rasters, particularly water based, will be very fine resolution but very sparse. The raw amount of RAM required to represent these images is huge, but small on disk. Being able to skip generating image tiles for these empty tiles makes a big difference to performance.

Can only be used with a single image from a TIFF, which should be fine as I can't see any code in the GeoTiffReader that would do anything but decide on a single image from the container to use. See read(int, ImageReadParam) for information on why it is this way {@link https://gdal.org/en/stable/drivers/raster/gtiff.html#sparse-files}

  • Constructor Details

    • SparseTIFFImageReader

      public SparseTIFFImageReader(ImageReaderSpi originatingProvider)
  • Method Details

    • initialize

      public static SparseTIFFImageReader initialize(SparseTiffCoverage coverage)

      Initialize and return the SparseTIFFImageReader that is being used by the given coverage so that it is correctly setup with the right image index from the TIFF.

    • isEmptyTile

      public boolean isEmptyTile(int tileX, int tileY)
      Returns:
      true if the given tile is empty. Querying pixels from this tile will always result in no_data being returned
    • hasEmptyTiles

      public boolean hasEmptyTiles()
      Returns:
      true if this image reader has any knowledge of any empty (no-data) tiles
    • read

      public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException

      Override's the default method to aid in our kludge for supporting the isEmptyTile tile method without an image index, e.g. isEmptyTile(imageIndex, tileX, tileY) vs isEmptyTile(tileX, tileY).

      From my reckons, there's no API way to access the index of the image that a coverage is actually sampling. The JAI Image API doesn't surface it, and neither does the GridCoverage2D API. That left me in a bind when implementing this: Do I use reflection to access the index from the JAI Image class, monkey patch the very large GeoTiffReader#read method to store the index that was picked? In the end I decided neither. In practice, it looks like it's always going to be one image in a TIFF that gets used, so this mild kludge seemed the lesser of all the evils.

      Overrides:
      read in class it.geosolutions.imageioimpl.plugins.tiff.TIFFImageReader
      Throws:
      IOException