java.lang.Object
org.apache.sis.internal.storage.inflater.Inflater
All Implemented Interfaces:
Closeable, AutoCloseable
Direct Known Subclasses:
CopyFromBytes

public abstract class Inflater extends Object implements Closeable
Copies values from an input buffer of bytes to the destination image buffer, potentially applying decompression, sub-region, subsampling and band subset on-the-fly. Decompression is applied row-by-row.

If a decompression algorithm can handle all above-cited aspects directly, it can extend this class directly. If it would be too complicated, an easier approach is to extend CompressionChannel instead and wrap that inflater in a CopyFromBytes subclass for managing the sub-region, subsampling and band subset.

Since:
1.1
Version:
1.3
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected final int
    Number of chunk per row, as a strictly positive integer.
    protected final int
    Number of primitive elements per chunk, as a strictly positive integer.
    protected final ChannelDataInput
    The source of data to decompress.
    protected final int[]
    Number of primitive elements to skip between chunks on the same row, or null if none.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    Inflater(ChannelDataInput input, int chunksPerRow, int samplesPerChunk, int[] skipAfterChunks, int pixelsPerElement, int maxChunkSize)
    Creates a new inflater instance.
  • Method Summary

    Modifier and Type
    Method
    Description
    final void
    Releases resources used by this inflater.
    static Inflater
    create(StoreListeners listeners, ChannelDataInput input, Compression compression, Predictor predictor, int sourcePixelStride, int sourceWidth, int chunksPerRow, int samplesPerChunk, int[] skipAfterChunks, int pixelsPerElement, DataType dataType)
    Creates a new instance for the given compression.
    void
    setInputOutput(long start, long byteCount, Buffer bank)
    Sets the input and output and prepares this inflater for reading a new tile or band of a tile.
    abstract void
    skip(long n)
    Reads the given amount of sample values without storing them.
    abstract void
    Reads a row of sample values and stores them in the target buffer.
    unsupportedEncoding(StoreListeners listeners, short key, Enum<?> value)
    Returns the exception to throw for an unsupported compression or predictor.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • input

      protected final ChannelDataInput input
      The source of data to decompress.
    • chunksPerRow

      protected final int chunksPerRow
      Number of chunk per row, as a strictly positive integer. See elementsPerChunk for more details about what is a "chunk".
    • elementsPerChunk

      protected final int elementsPerChunk
      Number of primitive elements per chunk, as a strictly positive integer. An element is a byte, an integer (16, 32 or 64) bits or a floating point number. An element is a sample value except in multi-pixels packed images. A chunk can be:
      • A sample value (samplesPerChunk = 1).
      • A pixel with one sample value per band (samplesPerChunk = number of bands).
      • Multi-pixels (e.g. bilevel image with 8 pixels per byte, which means 8 pixels per "chunk").
      • A full row (optimization when it is possible to read the row in a single I/O method call).
    • skipAfterChunks

      protected final int[] skipAfterChunks
      Number of primitive elements to skip between chunks on the same row, or null if none. If non-null then after reading the chunk at zero-based index x, inflater shall skip skipAfterChunks[x % skipAfterChunks.length] bank elements before to read the next chunk. The x index is reset to zero at the beginning of every new row.

      This array may be shared by various objects; it is usually not cloned. Do not modify.

  • Constructor Details

    • Inflater

      protected Inflater(ChannelDataInput input, int chunksPerRow, int samplesPerChunk, int[] skipAfterChunks, int pixelsPerElement, int maxChunkSize)
      Creates a new inflater instance.

      Note on sample definition

      A "sample" is usually a primitive type such as a byte or a float, but may be a unit smaller than a byte (e.g. 1 bit) if pixelsPerElement is greater than 1. In that case, the elementsPerChunk and skipAfterChunks values will be divided by pixelsPerElement.
      Parameters:
      input - the source of data to decompress.
      chunksPerRow - number of chunks (usually pixels) per row in target image. Must be strictly positive.
      samplesPerChunk - number of sample values per chunk (sample or pixel). Must be strictly positive.
      skipAfterChunks - number of sample values to skip between chunks. May be empty or null.
      pixelsPerElement - number of pixels per primitive element. Always 1 except for multi-pixels packed images.
      maxChunkSize - maximal value (in number of samples) for the elementsPerChunk field.
  • Method Details

    • create

      public static Inflater create(StoreListeners listeners, ChannelDataInput input, Compression compression, Predictor predictor, int sourcePixelStride, int sourceWidth, int chunksPerRow, int samplesPerChunk, int[] skipAfterChunks, int pixelsPerElement, DataType dataType) throws IOException, UnsupportedEncodingException
      Creates a new instance for the given compression. If the given method is unrecognized, then this method returns null.

      Note on sample definition

      A "sample" is usually a primitive type such as a byte or a float, but may be a unit smaller than a byte (e.g. 1 bit) if pixelsPerElement is greater than 1. If that case, the elementsPerChunk and skipAfterChunks values will be divided by pixelsPerElement.
      Parameters:
      listeners - object where to report warnings.
      input - the source of data to decompress.
      compression - the compression method.
      predictor - the mathematical operator to apply after decompression.
      sourcePixelStride - number of sample values per pixel in the source image.
      sourceWidth - number of pixels in a row of source image.
      chunksPerRow - number of chunks (usually pixels) per row in target image. Must be strictly positive.
      samplesPerChunk - number of sample values per chunk (sample or pixel). Must be strictly positive.
      skipAfterChunks - number of sample values to skip between chunks. May be empty or null.
      pixelsPerElement - number of pixels per primitive element. Always 1 except for multi-pixels packed images.
      dataType - primitive type used for storing data elements in the bank.
      Returns:
      the inflater for the given targe type.
      Throws:
      IOException - if an I/O operation was required and failed.
      UnsupportedEncodingException - if the compression, predictor or data type is unsupported.
    • unsupportedEncoding

      private static UnsupportedEncodingException unsupportedEncoding(StoreListeners listeners, short key, Enum<?> value)
      Returns the exception to throw for an unsupported compression or predictor.
    • setInputOutput

      public void setInputOutput(long start, long byteCount, Buffer bank) throws IOException
      Sets the input and output and prepares this inflater for reading a new tile or band of a tile.
      Parameters:
      start - input stream position where to start reading.
      byteCount - number of bytes to read before decompression.
      bank - where to store sample values.
      Throws:
      IOException - if an I/O operation was required and failed.
    • skip

      public abstract void skip(long n) throws IOException
      Reads the given amount of sample values without storing them. The given value is in units of sample values, not in bytes.

      Case of multi-pixels packed image

      If there is more than one sample value per element, then this method may round (at implementation choice) the stream position to the first element boundary after skipping n sample values. For example a bilevel image packs 8 sample values per byte. Consequently, a call to skip(10) may skip 2 bytes: one byte for the first 8 bits, then 2 bits rounded to the next byte boundary.

      The exact rounding mode depends on the compression algorithm. To avoid erratic behavior, callers shall restrict n to multiples of pixelsPerElement before to read the first pixel in a row. This restriction does not apply when skipping remaining data after the last pixels in a row, because the next row will be realigned on an element boundary anyway. The way to perform this realignment depends on the compression, which is the reason why the exact rounding mode may vary with compression algorithms.

      Restricting n to multiples of pixelsPerElement implies the following restrictions:

      • No subsampling on the x axis (however subsampling on other axes is still allowed).
      • No band subset if interleaved sample model, because the effect is similar to subsampling.
      • If GridDerivation is used for computing the sub-region to read, it should have been configured with chunkSize(pixelsPerElement) (unless chunk size is already used for tile size).
      Parameters:
      n - number of uncompressed sample values to ignore.
      Throws:
      IOException - if an error occurred while reading the input channel.
    • uncompressRow

      public abstract void uncompressRow() throws IOException
      Reads a row of sample values and stores them in the target buffer. This is not a complete row; caller may invoke skip(long) for ignoring leading and trailing sample values.
      Throws:
      IOException - if an error occurred while reading the input channel.
    • close

      public final void close() throws IOException
      Releases resources used by this inflater.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException