Class Reader

java.lang.Object
org.apache.sis.storage.geotiff.GeoTIFF
org.apache.sis.storage.geotiff.Reader
All Implemented Interfaces:
Closeable, AutoCloseable

final class Reader extends GeoTIFF
An image reader for GeoTIFF files. This reader duplicates the implementations performed by other libraries, but we nevertheless provide our own reader in Apache SIS for better control on the process of decoding geospatial metadata. We also measured better performance with this reader at least for uncompressed files, and added support for some unusual data layout not supported by other libraries.

This image reader can also process Big TIFF images.

The TIFF format specification version 6.0 (June 3, 1992) is available here.

Since:
0.8
Version:
1.2
  • Field Details

    • input

      final ChannelDataInput input
      The stream from which to read the data.
    • origin

      final long origin
      Stream position of the first byte of the GeoTIFF file. This is usually zero.
    • intSizeExpansion

      final byte intSizeExpansion
      A multiplication factor for the size of pointers, expressed as a power of 2. The pointer size in bytes is given by Integer.BYTES << pointerExpansion.

      Values can be:

      • 0 for the classical TIFF format, which uses 4 bytes.
      • 1 for the BigTIFF format, which uses 8 bytes.
      • 2 for 16 bytes (not yet used, but the BigTIFF specification makes provision for it).
      Those values are defined that way for making easier (like a boolean flag) to test if the file is a BigTIFF format, with statement like if (intSizeExpansion != 0).
    • lastIFD

      private ImageFileDirectory lastIFD
      The last Image File Directory (IFD) read, or null if none. This is used when we detected the end of a pyramid and the beginning of next one.
    • nextIFD

      private long nextIFD
      Offset (relative to the beginning of the TIFF file) of the next Image File Directory (IFD) to read, or 0 if we have finished to read all of them.
      See Also:
    • doneIFD

      private final Set<Long> doneIFD
      Offsets of all Image File Directory (IFD) that have been read so far. This field is used only as a protection against infinite recursivity, by preventing the same offset to appear twice.
      See Also:
    • images

      private final List<GridCoverageResource> images
      Information about each (potentially pyramided) image in this file. Those objects are created when first needed.
      See Also:
    • deferredEntries

      private final LinkedList<DeferredEntry> deferredEntries
      Entries having a value that cannot be read immediately, but instead have a pointer to a value stored elsewhere in the file. Those values will be read only when needed.
      Implementation note: we use a LinkedList because we will perform frequent additions and removals, but no random access.
    • deferredNeedsSort

      private boolean deferredNeedsSort
      Whether deferredEntries needs to be stored. This flag is set to true when at least one new deferred entry has been added, and cleared after the sort has been done.
    • nameFactory

      final org.opengis.util.NameFactory nameFactory
      The factory to use for creating image identifiers.
  • Constructor Details

  • Method Details

    • readNextImageOffset

      private void readNextImageOffset() throws IOException, DataStoreException
      Sets nextIFD to the next offset read from the TIFF file and makes sure that it will not cause an infinite loop.
      Throws:
      IOException
      DataStoreException
    • readUnsignedInt

      private long readUnsignedInt() throws IOException, DataStoreException
      Reads the int or long value (depending if the file is a standard of big TIFF) at the current input position.
      Returns:
      the next pointer value.
      Throws:
      IOException
      DataStoreException
    • readUnsignedShort

      private long readUnsignedShort() throws IOException, DataStoreException
      Reads the short or long value (depending if the file is standard of big TIFF) at the current input position.
      Returns:
      the next directory entry value.
      Throws:
      IOException
      DataStoreException
    • getImageFileDirectory

      private ImageFileDirectory getImageFileDirectory(int index) throws IOException, DataStoreException
      Returns the next Image File Directory (IFD), or null if we reached the last IFD. The IFD consists of a 2 (classical) or 8 (BigTiff)-bytes count of the number of directory entries, followed by a sequence of 12-byte field entries, followed by a pointer to the next IFD (or 0 if none).
      Parameters:
      index - index of the (potentially pyramided) image, not counting reduced-resolution (overview) images.
      Returns:
      the IFD if we found it, or null if there are no more IFDs.
      Throws:
      ArithmeticException - if the pointer to a next IFD is too far.
      IOException
      DataStoreException
      See Also:
    • resolveDeferredEntries

      final void resolveDeferredEntries(ImageFileDirectory dir) throws IOException, DataStoreException
      Reads all entries that were deferred.
      Parameters:
      dir - the IFD for which to resolve deferred entries regardless stream position or ignoreAfter value.
      Throws:
      IOException
      DataStoreException
    • resolveDeferredEntries

      private void resolveDeferredEntries(ImageFileDirectory dir, long ignoreAfter) throws IOException, DataStoreException
      Reads some of the entries that has been deferred. If the given dir argument is non-null, then this method resolves all entries needed by this IFD no matter where the entry value is located. For other entries, this method may opportunistically resolve some values but make no guarantees. Generally, values of IFD other than this will not be resolved if they are located before the current stream position or after the ignoreAfter value.
      Parameters:
      dir - the IFD for which to resolve deferred entries regardless stream position or ignoreAfter value.
      ignoreAfter - offset relative to the beginning of TIFF file at which entries should be ignored. This hint does not apply to the IFD specified by the dir argument.
      Throws:
      IOException
      DataStoreException
    • getImage

      final GridCoverageResource getImage(int index) throws IOException, DataStoreException
      Returns the potentially pyramided Image File Directories (IFDs) at the given index. If the pyramid has already been initialized, then it is returned. Otherwise this method initializes the pyramid now and returns it.

      This method assumes that the first IFD is the full resolution image and all following IFDs having ImageFileDirectory.isReducedResolution() flag set are the same image at lower resolutions. This is the cloud optimized GeoTIFF convention.

      Returns:
      the pyramid if we found it, or null if there is no more pyramid at the given index.
      Throws:
      ArithmeticException - if the pointer to a next IFD is too far.
      IOException
      DataStoreException
    • warning

      private void warning(short tag, Object error)
      Logs a warning about a tag that cannot be read, but does not interrupt the TIFF reading.
      Parameters:
      tag - the tag than cannot be read.
      error - the value than cannot be understand, or the exception that we got while trying to parse it.
    • close

      public void close() throws IOException
      Closes this reader.
      Throws:
      IOException - if an error occurred while closing this reader.