Class ChannelImageInputStream

All Implemented Interfaces:
Closeable, DataInput, AutoCloseable, ImageInputStream, Markable

public class ChannelImageInputStream extends ChannelDataInput implements ImageInputStream
Adds the missing methods in ChannelDataInput for implementing the ImageInputStream interface. The JDK approach for creating an image input stream from a channel would be as below: However, the standard ImageInputStreamImpl implementation performs many work by itself, including supporting various byte order, which could be more efficiently done by NIO. Furthermore, this class allows us to reuse an existing buffer (especially direct buffer, which are costly to create) and allow subclasses to store additional information, for example the file path.

This class is used when compatibility with ImageReader is needed.

Since:
0.3
Version:
1.3
See Also:
  • Constructor Details

    • ChannelImageInputStream

      public ChannelImageInputStream(String filename, ReadableByteChannel channel, ByteBuffer buffer, boolean filled) throws IOException
      Creates a new input stream for the given channel and using the given buffer.
      Parameters:
      filename - a file identifier used only for formatting error message.
      channel - the channel from where data are read.
      buffer - the buffer where to copy the data.
      filled - true if the buffer already contains data, or false if it needs to be initially filled with some content read from the channel.
      Throws:
      IOException - if an error occurred while reading the channel.
    • ChannelImageInputStream

      public ChannelImageInputStream(String filename, ByteBuffer data)
      Creates a new instance for a buffer filled with the bytes to use. This constructor uses an independent, read-only view of the given buffer. No reference to the given buffer will be retained.
      Parameters:
      filename - a short identifier (typically a filename without path) used for formatting error message.
      data - the buffer filled with all bytes to read.
    • ChannelImageInputStream

      public ChannelImageInputStream(ChannelDataInput input)
      Creates a new input stream from the given ChannelDataInput. This constructor is invoked when we need to change the implementation class from ChannelDataInput to ChannelImageInputStream. The old input should not be used anymore after this constructor has been invoked.
      Parameters:
      input - the existing instance from which to takes the channel and buffer.
  • Method Details

    • setByteOrder

      public final void setByteOrder(ByteOrder byteOrder)
      Sets the desired byte order for future reads of data values from this stream. The default value is ByteOrder.BIG_ENDIAN.
      Specified by:
      setByteOrder in interface ImageInputStream
      Parameters:
      byteOrder - the new buffer byte order.
    • getByteOrder

      public final ByteOrder getByteOrder()
      Returns the byte order with which data values will be read from this stream. This is the buffer byte order.
      Specified by:
      getByteOrder in interface ImageInputStream
      Returns:
      the buffer byte order.
    • readBoolean

      public final boolean readBoolean() throws IOException
      Reads a byte from the stream and returns a true if it is nonzero, false otherwise. The implementation is as below:
      Specified by:
      readBoolean in interface DataInput
      Specified by:
      readBoolean in interface ImageInputStream
      Returns:
      the value of the next boolean from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readUTF

      public final String readUTF() throws IOException
      Reads in a string that has been encoded using a UTF-8 string.
      Specified by:
      readUTF in interface DataInput
      Specified by:
      readUTF in interface ImageInputStream
      Returns:
      the string reads from the stream.
      Throws:
      IOException - if an error (including EOF) occurred while reading the stream.
    • readLine

      public final String readLine() throws IOException
      Reads the new bytes until the next EOL. This method can read only US-ASCII strings. This method is provided for compliance with the DataInput interface, but is generally not recommended.
      Specified by:
      readLine in interface DataInput
      Specified by:
      readLine in interface ImageInputStream
      Returns:
      the next line, or null if the EOF has been reached.
      Throws:
      IOException - if an error occurred while reading.
    • read

      public final int read() throws IOException
      Returns the next byte from the stream as an unsigned integer between 0 and 255, or -1 if we reached the end of stream.
      Specified by:
      read in interface ImageInputStream
      Returns:
      the next byte as an unsigned integer, or -1 on end of stream.
      Throws:
      IOException - if an error occurred while reading the stream.
    • read

      public final int read(byte[] dest) throws IOException
      Reads up to dest.length bytes from the stream, and stores them into dest starting at index 0. The default implementation is as below:
      Specified by:
      read in interface ImageInputStream
      Parameters:
      dest - an array of bytes to be written to.
      Returns:
      the number of bytes actually read, or -1 on EOF.
      Throws:
      IOException - if an error occurred while reading.
    • read

      public final int read(byte[] dest, int offset, int length) throws IOException
      Reads up to length bytes from the stream, and stores them into dest starting at index offset. If no bytes can be read because the end of the stream has been reached, -1 is returned.
      Specified by:
      read in interface ImageInputStream
      Parameters:
      dest - an array of bytes to be written to.
      offset - the starting position within dest to write.
      length - the maximum number of bytes to read.
      Returns:
      the number of bytes actually read, or -1 on EOF.
      Throws:
      IOException - if an error occurred while reading.
    • readBytes

      public final void readBytes(IIOByteBuffer dest, int length) throws IOException
      Reads up to length bytes from the stream, and modifies the supplied IIOByteBuffer to indicate the byte array, offset, and length where the data may be found.
      Specified by:
      readBytes in interface ImageInputStream
      Parameters:
      dest - the buffer to be written to.
      length - the maximum number of bytes to read.
      Throws:
      IOException - if an error occurred while reading.
    • skipBytes

      public final int skipBytes(int n) throws IOException
      Skips over n bytes of data from the input stream. A negative value move backward in the input stream.

      Design note

      A previous version was skipping no more bytes than the buffer capacity. But experience shows that various ImageReader implementations outside Apache SIS expect that we skip exactly the specified amount of bytes and ignore the returned value.
      Specified by:
      skipBytes in interface DataInput
      Specified by:
      skipBytes in interface ImageInputStream
      Parameters:
      n - maximal number of bytes to skip. Can be negative.
      Returns:
      number of bytes actually skipped.
      Throws:
      IOException - if an error occurred while reading.
    • skipBytes

      public final long skipBytes(long n) throws IOException
      Advances the current stream position by the given amount of bytes. The bit offset is reset to 0 by this method.
      Specified by:
      skipBytes in interface ImageInputStream
      Parameters:
      n - the number of bytes to seek forward.
      Returns:
      the number of bytes skipped.
      Throws:
      IOException - if an error occurred while skipping.
    • flush

      public final void flush() throws IOException
      Discards the initial position of the stream prior to the current stream position. The implementation is as below:
      Specified by:
      flush in interface ImageInputStream
      Throws:
      IOException - if an I/O error occurred.
    • isCached

      public final boolean isCached()
      Synonymous of isCachedMemory() since the caching behavior of this class is uniquely determined by the policy that we choose for isCachedMemory(). This class never creates temporary files.
      Specified by:
      isCached in interface ImageInputStream
      See Also:
    • isCachedMemory

      public final boolean isCachedMemory()
      Returns false since this ImageInputStream does not cache data itself in order to allow seeking backwards. Actually, we could consider the ChannelData.buffer as a cache in main memory. But this buffer has a maximal capacity, which would be a violation of ImageInputStream contract.
      Specified by:
      isCachedMemory in interface ImageInputStream
      Returns:
      false since this ImageInputStream does not caches data in main memory (ignoring the ChannelData.buffer).
    • isCachedFile

      public final boolean isCachedFile()
      Returns false since this ImageInputStream does not cache data in a temporary file.
      Specified by:
      isCachedFile in interface ImageInputStream
      Returns:
      false since this ImageInputStream does not cache data in a temporary file.
    • close

      public final void close() throws IOException
      Closes the ChannelDataInput.channel. If the channel is backed by an InputStream, that stream will be closed too.

      Departure from Image I/O standard implementation

      Java Image I/O wrappers around input/output streams do not close the underlying stream (see for example FileCacheImageInputStream.close() specification). But Apache SIS needs the underlying stream to be closed because we do not keep reference to the original input stream. Note that channels created by Channels.newChannel(java.io.InputStream) close the stream, which is the desired behavior for this method.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Specified by:
      close in interface ImageInputStream
      Throws:
      IOException - if an error occurred while closing the channel.