Class EncapsulatedInputStream

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable

    public class EncapsulatedInputStream
    extends java.io.InputStream

    A class that extends InputStream by adding a mechanism for unecapsulating an undefined length DICOM attribute, such as is used for compressed Pixel Data.

    The read methods hide the fact that the data is encapsulated by removing the Items and Item and Sequence delimiter tags, as well as skipping any Basic Offset Table that may be present in the first Item.

    Since an individual frame may be fragmented and padded with 0xff bytes beyond the JPEG EOI marker (0xffd9), and since the codec used for decoding may be "reading ahead" this class also removes any padding 0xff bytes at the end of any fragment, back as far as the EOI marker. Note that this means that theorectically frames could span fragments as long as there was no padding between them.

    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      boolean framesAreSeparated()
      Are frames separated (seperable)?
      protected long getBytesRead()  
      int getOffsetOfNextByteToReadFromStartOfFragment()  
      void nextFrame()
      Skip to the start of a fragment, if not already there.
      int read()
      Extracts the next byte of data from the current or subsequent fragments.
      int read​(byte[] b)
      Extracts byte.length bytes of data from the current or subsequent fragments.
      int read​(byte[] b, int off, int len)
      Extracts len bytes of data from the current or subsequent fragments.
      void readSequenceDelimiter()  
      void readUnsigned16​(short[] w, int offset, int len)
      Read an array of unsigned integer 16 bit values.
      long readUnsigned32LittleEndian()
      Read an unsigned integer 32 bit values little endian regardless of endianness of stream.
      void readUnsigned32LittleEndian​(long[] w, int offset, int len)
      Read an array of unsigned integer 32 bit values little endian regardless of endianness of stream.
      void skipInsistently​(long length)
      Skip as many bytes as requested, unless an exception occurs.
      • Methods inherited from class java.io.InputStream

        available, close, mark, markSupported, nullInputStream, readAllBytes, readNBytes, readNBytes, reset, skip, transferTo
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • EncapsulatedInputStream

        public EncapsulatedInputStream​(BinaryInputStream i,
                                       boolean jpegEOIDetection,
                                       boolean oneFragmentPerFrame)

        Construct a byte ordered stream from the supplied stream.

        The byte order may be changed later.

        Parameters:
        i - the input stream to read from
        jpegEOIDetection - whether or not to detect JPEG EOI, to allow frames to span fragments
        oneFragmentPerFrame - if not using jpegEOIDetection, whether or not to assume one fragment per frame (e.g., for RLE), rather than all fragments in one frame (e.g., for MPEG)
      • EncapsulatedInputStream

        public EncapsulatedInputStream​(BinaryInputStream i)

        Construct a byte ordered stream from the supplied stream.

        The byte order may be changed later.

        JPEG EOI detection is enabled, to allow frames to span fragments.

        Do not use for RLE encapsulated data, since it will assume all fragments are in one frame, rather than one fragment per frame.

        Parameters:
        i - the input stream to read from
    • Method Detail

      • getBytesRead

        protected long getBytesRead()
      • readSequenceDelimiter

        public void readSequenceDelimiter()
                                   throws java.io.IOException
        Throws:
        java.io.IOException - if an I/O error occurs
      • nextFrame

        public void nextFrame()

        Skip to the start of a fragment, if not already there.

      • readUnsigned16

        public final void readUnsigned16​(short[] w,
                                         int offset,
                                         int len)
                                  throws java.io.IOException

        Read an array of unsigned integer 16 bit values.

        Parameters:
        w - an array of sufficient size in which to return the values read
        offset - the offset in the array at which to begin storing values
        len - the number of 16 bit values to read
        Throws:
        java.io.IOException - if an I/O error occurs
      • readUnsigned32LittleEndian

        public final long readUnsigned32LittleEndian()
                                              throws java.io.IOException

        Read an unsigned integer 32 bit values little endian regardless of endianness of stream.

        Returns:
        the value read
        Throws:
        java.io.IOException - if an I/O error occurs
      • readUnsigned32LittleEndian

        public final void readUnsigned32LittleEndian​(long[] w,
                                                     int offset,
                                                     int len)
                                              throws java.io.IOException

        Read an array of unsigned integer 32 bit values little endian regardless of endianness of stream.

        Parameters:
        w - an array of sufficient size in which to return the values read
        offset - the offset in the array at which to begin storing values
        len - the number of 32 bit values to read
        Throws:
        java.io.IOException - if an I/O error occurs
      • skipInsistently

        public void skipInsistently​(long length)
                             throws java.io.IOException

        Skip as many bytes as requested, unless an exception occurs.

        Parameters:
        length - number of bytes to read (no more and no less)
        Throws:
        java.io.IOException - if an I/O error occurs
      • read

        public final int read()
                       throws java.io.IOException

        Extracts the next byte of data from the current or subsequent fragments.

        Specified by:
        read in class java.io.InputStream
        Returns:
        the next byte of data, or -1 if there is no more data because the end of the stream has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • read

        public final int read​(byte[] b)
                       throws java.io.IOException

        Extracts byte.length bytes of data from the current or subsequent fragments.

        This method simply performs the call read(b, 0, b.length) and returns the result.

        Overrides:
        read in class java.io.InputStream
        Parameters:
        b - the buffer into which the data is read.
        Returns:
        the total number of bytes read into the buffer (always whatever was asked for), or -1 if there is no more data because the end of the stream has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
        See Also:
        read(byte[], int, int)
      • read

        public final int read​(byte[] b,
                              int off,
                              int len)
                       throws java.io.IOException

        Extracts len bytes of data from the current or subsequent fragments.

        Overrides:
        read in class java.io.InputStream
        Parameters:
        b - the buffer into which the data is read.
        off - the start offset of the data.
        len - the number of bytes read.
        Returns:
        the total number of bytes read into the buffer (always whatever was asked for), or -1 if there is no more data because the end of a frame has been reached.
        Throws:
        java.io.IOException - if an I/O error occurs.
      • getOffsetOfNextByteToReadFromStartOfFragment

        public int getOffsetOfNextByteToReadFromStartOfFragment()
      • framesAreSeparated

        public boolean framesAreSeparated()

        Are frames separated (seperable)?

        This will be either because the stream contains recognizable end of frame markers (e.g., JEPG) or the Transfer Syntax specifies one fragment per frame (e.g., RLE).

        Returns:
        true if frames are separated rather than being lumped together in one byte stream/array