Class DicomReader

All Implemented Interfaces:
Closeable, AutoCloseable, ICompressedTileReader, IFormatHandler, IFormatReader, IMetadataConfigurable, IPyramidHandler

public class DicomReader extends SubResolutionFormatReader
DicomReader is the file format reader for DICOM files.
  • Field Details

    • DICOM_MAGIC_STRING

      public static final String DICOM_MAGIC_STRING
      See Also:
    • HEADER_LENGTH

      public static final int HEADER_LENGTH
      See Also:
    • DICOM_SUFFIXES

      private static final String[] DICOM_SUFFIXES
    • lut

      private byte[][] lut
    • shortLut

      private short[][] shortLut
    • maxPixelRange

      private int maxPixelRange
    • centerPixelValue

      private int centerPixelValue
    • inverted

      private boolean inverted
    • date

      private String date
    • time

      private String time
    • imageType

      private String imageType
    • pixelSizeX

      private String pixelSizeX
    • pixelSizeY

      private String pixelSizeY
    • pixelSizeZ

      private Double pixelSizeZ
    • positionX

      private List<Double> positionX
    • positionY

      private List<Double> positionY
    • positionZ

      private List<Double> positionZ
    • channelNames

      private List<String> channelNames
    • isJPEG

      private boolean isJPEG
    • isRLE

      private boolean isRLE
    • isJP2K

      private boolean isJP2K
    • isDeflate

      private boolean isDeflate
    • fileList

      private Map<Integer,List<String>> fileList
    • imagesPerFile

      private int imagesPerFile
    • instanceUID

      private String instanceUID
    • originalDate

      private String originalDate
    • originalTime

      private String originalTime
    • originalInstance

      private String originalInstance
    • originalSeries

      private int originalSeries
    • originalX

      private int originalX
    • originalY

      private int originalY
    • originalSpecimen

      private String originalSpecimen
    • originalStudyTime

      private String originalStudyTime
    • wsi

      private boolean wsi
    • companionFiles

      private List<String> companionFiles
    • tilePositions

      private Map<Integer,List<DicomTile>> tilePositions
    • zOffsets

      private Map<Integer,List<Double>> zOffsets
    • concatenationNumber

      private Number concatenationNumber
    • edf

      private boolean edf
    • tags

      private List<DicomTag> tags
    • currentTileFile

      private transient String currentTileFile
    • currentTileStream

      private transient loci.common.RandomAccessInputStream currentTileStream
    • privateContentHighWords

      private Set<Integer> privateContentHighWords
  • Constructor Details

    • DicomReader

      public DicomReader()
      Constructs a new DICOM reader.
  • Method Details

    • getTileRows

      public int getTileRows(int no)
      Description copied from interface: ICompressedTileReader
      Get the number of rows of tiles in the specified plane in the current series.
      Specified by:
      getTileRows in interface ICompressedTileReader
      Overrides:
      getTileRows in class FormatReader
      Parameters:
      no - plane index
      Returns:
      tile row count
    • getTileColumns

      public int getTileColumns(int no)
      Description copied from interface: ICompressedTileReader
      Get the number of columns of tiles in the specified plane in the current series.
      Specified by:
      getTileColumns in interface ICompressedTileReader
      Overrides:
      getTileColumns in class FormatReader
      Parameters:
      no - plane index
      Returns:
      tile column count
    • openCompressedBytes

      public byte[] openCompressedBytes(int no, int x, int y) throws FormatException, IOException
      Description copied from interface: ICompressedTileReader
      Retrieve the specified tile without performing any decompression.
      Parameters:
      no - plane index
      x - tile X index (indexed from 0, @see getTileColumns(int))
      y - tile Y index (indexed from 0, @see getTileRows(int))
      Returns:
      compressed tile bytes
      Throws:
      FormatException
      IOException
    • openCompressedBytes

      public byte[] openCompressedBytes(int no, byte[] buf, int x, int y) throws FormatException, IOException
      Description copied from interface: ICompressedTileReader
      Retrieve the specified tile without performing any decompression.
      Parameters:
      no - plane index
      buf - pre-allocated buffer in which to store compressed bytes
      x - tile X index (indexed from 0, @see getTileColumns(int))
      y - tile Y index (indexed from 0, @see getTileRows(int))
      Returns:
      compressed tile bytes
      Throws:
      FormatException
      IOException
    • getTileCodec

      public Codec getTileCodec(int no) throws FormatException, IOException
      Description copied from interface: ICompressedTileReader
      Retrieve a codec that can be used to decompress compressed tiles.
      Parameters:
      no - plane index
      Returns:
      codec that can be used for compressed tiles in the specified plane
      Throws:
      FormatException
      IOException
      See Also:
    • getTileCodecOptions

      public CodecOptions getTileCodecOptions(int no, int x, int y) throws FormatException, IOException
      Description copied from interface: ICompressedTileReader
      Retrieve codec options that can be used to decompressed the specified tile.
      Parameters:
      no - plane index
      x - tile X index (indexed from 0, @see getTileColumns(int))
      y - tile Y index (indexed from 0, @see getTileRows(int))
      Returns:
      codec options
      Throws:
      FormatException
      IOException
      See Also:
    • isThisType

      public boolean isThisType(String name, boolean open)
      Description copied from class: FormatReader
      Checks if a file matches the type of this format reader. Checks filename suffixes against those known for this format. If the suffix check is inconclusive and the open parameter is true, the file is opened and tested with FormatReader.isThisType(RandomAccessInputStream).
      Specified by:
      isThisType in interface IFormatReader
      Overrides:
      isThisType in class FormatReader
      Parameters:
      open - If true, and the file extension is insufficient to determine the file type, the (existing) file is opened for further analysis.
    • isThisType

      public boolean isThisType(loci.common.RandomAccessInputStream stream) throws IOException
      Description copied from interface: IFormatReader
      Checks if the given stream is a valid stream for this file format. The number of bytes read is format-dependent.
      Specified by:
      isThisType in interface IFormatReader
      Overrides:
      isThisType in class FormatReader
      Parameters:
      stream - A RandomAccessInputStream representing the file to check. The first byte in the stream is assumed to be the first byte in the file.
      Returns:
      true if the file represented by the stream can be read by this reader; false otherwise.
      Throws:
      IOException
    • getRequiredDirectories

      public int getRequiredDirectories(String[] files) throws FormatException, IOException
      Description copied from interface: IFormatReader
      Returns the number of parent directories that are important when processing the given list of files. The number of directories is relative to the common parent. For example, given a list with these two files: /path/to/file/foo /path/to/file/that/is/related A return value of 0 indicates that "/path/to/file/" is irrelevant. A return value of 1 indicates that "/path/to/" is irrelevant. Return values less than 0 are invalid. All listed files are assumed to belong to datasets of the same format.
      Specified by:
      getRequiredDirectories in interface IFormatReader
      Overrides:
      getRequiredDirectories in class FormatReader
      Throws:
      FormatException
      IOException
    • get8BitLookupTable

      public byte[][] get8BitLookupTable()
      Description copied from interface: IFormatReader
      Gets the 8-bit color lookup table associated with the most recently opened image. If no image planes have been opened, or if IFormatReader.isIndexed() returns false, then this may return null. Also, if IFormatReader.getPixelType() returns anything other than FormatTools.INT8 or FormatTools.UINT8, this method will return null.
      Specified by:
      get8BitLookupTable in interface IFormatReader
      Overrides:
      get8BitLookupTable in class FormatReader
    • get16BitLookupTable

      public short[][] get16BitLookupTable()
      Description copied from interface: IFormatReader
      Gets the 16-bit color lookup table associated with the most recently opened image. If no image planes have been opened, or if IFormatReader.isIndexed() returns false, then this may return null. Also, if IFormatReader.getPixelType() returns anything other than FormatTools.INT16 or FormatTools.UINT16, this method will return null.
      Specified by:
      get16BitLookupTable in interface IFormatReader
      Overrides:
      get16BitLookupTable in class FormatReader
    • getSeriesUsedFiles

      public String[] getSeriesUsedFiles(boolean noPixels)
      Description copied from interface: IFormatReader
      Returns an array of filenames needed to open the current series. If the 'noPixels' flag is set, then only files that do not contain pixel data will be returned. The first element in the array is expected to be the path passed to IFormatHandler.setId(String), if appropriate based upon 'noPixels'. The remaining elements are expected to be in a consistent order; if a directory listing is necessary to build the list then it should be sorted first.
      Specified by:
      getSeriesUsedFiles in interface IFormatReader
      Overrides:
      getSeriesUsedFiles in class FormatReader
    • fileGroupOption

      public int fileGroupOption(String id) throws FormatException, IOException
      Description copied from interface: IFormatReader
      Returns an indication of whether the files in a multi-file dataset can be handled individually. This method is only useful for formats and datasets which contain multiple files.
      Specified by:
      fileGroupOption in interface IFormatReader
      Overrides:
      fileGroupOption in class FormatReader
      Parameters:
      id - a file in the multi-file dataset
      Returns:
      an int indicating that we cannot, must, or might group the files. A return value of FormatTools.MUST_GROUP indicates that the files cannot be handled separately; the reader will always detect and read all files in the dataset. FormatTools.CAN_GROUP indicates that the files may be handled separately, but file grouping must then be disabled via IFormatReader.setGroupFiles(boolean). FormatTools.CANNOT_GROUP indicates that the files must be handled separately; the reader will not attempt to read all files in the dataset (this is rare).
      Throws:
      FormatException
      IOException
      See Also:
    • getOptimalTileWidth

      public int getOptimalTileWidth()
      Description copied from interface: IFormatReader
      Returns the optimal sub-image width for use with openBytes.
      Specified by:
      getOptimalTileWidth in interface IFormatReader
      Overrides:
      getOptimalTileWidth in class FormatReader
    • getOptimalTileHeight

      public int getOptimalTileHeight()
      Description copied from interface: IFormatReader
      Returns the optimal sub-image height for use with openBytes.
      Specified by:
      getOptimalTileHeight in interface IFormatReader
      Overrides:
      getOptimalTileHeight in class FormatReader
    • openBytes

      public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException
      Description copied from interface: IFormatReader
      Obtains a sub-image of the specified image plane into a pre-allocated byte array.
      Specified by:
      openBytes in interface IFormatReader
      Specified by:
      openBytes in class FormatReader
      Parameters:
      no - the plane index within the current series.
      buf - a pre-allocated buffer.
      x - X coordinate of the upper-left corner of the sub-image
      y - Y coordinate of the upper-left corner of the sub-image
      w - width of the sub-image
      h - height of the sub-image
      Returns:
      the pre-allocated buffer buf for convenience.
      Throws:
      FormatException - if there was a problem parsing the metadata of the file.
      IOException - if there was a problem reading the file.
      See Also:
    • close

      public void close(boolean fileOnly) throws IOException
      Description copied from interface: IFormatReader
      Closes the currently open file. If the flag is set, this is all that happens; if unset, it is equivalent to calling Closeable.close().
      Specified by:
      close in interface IFormatReader
      Overrides:
      close in class SubResolutionFormatReader
      Throws:
      IOException
    • initFile

      protected void initFile(String id) throws FormatException, IOException
      Description copied from class: SubResolutionFormatReader
      Initializes the given file (parsing header information, etc.). Most subclasses should override this method to perform initialization operations such as parsing metadata.
      Overrides:
      initFile in class SubResolutionFormatReader
      Throws:
      FormatException - if a parsing error occurs processing the file.
      IOException - if an I/O error occurs processing the file
    • addInfo

      private void addInfo(DicomTag info) throws IOException
      Throws:
      IOException
    • addOriginalMetadata

      private void addOriginalMetadata(String key, DicomTag info)
      Store the given tag's value (if present) in the original metadata hashtable using the provided key. Any children of the tag will be added to the table as well. Note that the "Per-Frame Functional Groups Sequence" and "Referenced Image Navigation Sequence" and any children will be omitted, as will any values that are byte or short arrays (e.g. lookup tables). This is necessary to prevent memory exhaustion. Applications that need to traverse the complete hierarchy of DICOM tags should use getTags() to access tags directly and not rely upon the original metadata table.
    • makeFileList

      private void makeFileList() throws FormatException, IOException
      Build a list of files that belong with the current file.
      Throws:
      FormatException
      IOException
    • scanDirectory

      private void scanDirectory(loci.common.Location dir, boolean checkSeries) throws FormatException, IOException
      Scan the given directory for files that belong to this dataset.
      Throws:
      FormatException
      IOException
    • addFileToList

      private void addFileToList(String file, boolean checkSeries) throws FormatException, IOException
      Determine if the given file belongs in the same dataset as this file.
      Throws:
      FormatException
      IOException
    • parseIntValue

      private int parseIntValue(Number v, int defaultValue)
    • getTimestampMicroseconds

      private long getTimestampMicroseconds(String v)
      Convert the timestamp from a TM value to microseconds. The timestamp format defined in the standard is HHMMSS.FFFFFF but HH:MM:SS.FFFFFF is supported as well since some files incorrectly use that format.
    • attachCompanionFiles

      private void attachCompanionFiles() throws IOException
      DICOM datasets produced by: http://www.ct-imaging.de/index.php/en/ct-systeme-e/mikro-ct-e.html contain a bunch of extra metadata and log files. We do not parse these extra files, but do locate and attach them to the DICOM file(s).
      Throws:
      IOException
    • getStream

      private loci.common.RandomAccessInputStream getStream(String path) throws IOException
      Throws:
      IOException
    • getTileCodec

      private Codec getTileCodec(DicomTile tile)
      Get a Codec that can be used to decompress the given tile.
    • getTileCodecOptions

      private CodecOptions getTileCodecOptions(DicomTile tile)
      Get a CodecOptions that can be used to decompress the given tile.
    • getTileList

      public List<DicomTile> getTileList(int no, loci.common.Region boundingBox, boolean firstTileOnly)
      Get a list of tiles corresponding to the given plane. If the bounding box is not null, then only tiles intersecting with the bounding box will be returned. If the "firstTileOnly" flag is set, then this will return as soon as one matching tile is found.
    • calculateTilePlaneIndexes

      private void calculateTilePlaneIndexes()
    • getTile

      private void getTile(DicomTile tile, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException
      Decompress pixel data associated with the given DicomTile.
      Throws:
      FormatException
      IOException
    • parsePixelSpacing

      private void parsePixelSpacing(String value)
    • handleReferencedFile

      private void handleReferencedFile(DicomTag tag, String currentType)
    • calculatePixelsOffsets

      private void calculatePixelsOffsets(long baseOffset) throws FormatException, IOException
      Calculate offsets to all pixel data (tiles or planes) in the file, starting from the given offset.
      Throws:
      FormatException
      IOException
    • createFileInfo

      private DicomFileInfo createFileInfo(String file) throws FormatException, IOException
      Construct a DicomFileInfo for the given file. If the file is the currently initialized file, don't parse it again.
      Throws:
      FormatException
      IOException
    • encloses

      private boolean encloses(loci.common.Region a, loci.common.Region b)
    • updateCoreMetadata

      private void updateCoreMetadata(CoreMetadata ms)
    • getImageType

      public String getImageType()
    • getTiles

      public List<DicomTile> getTiles()
    • getTiles

      public List<DicomTile> getTiles(int coreIndex)
    • addZOffset

      private void addZOffset(int coreIndex, Double z)
    • getZOffsets

      public List<Double> getZOffsets()
    • getZOffsets

      public List<Double> getZOffsets(int coreIndex)
    • getConcatenationIndex

      public int getConcatenationIndex()
    • getPixelSizeX

      public ome.units.quantity.Length getPixelSizeX()
    • getPixelSizeY

      public ome.units.quantity.Length getPixelSizeY()
    • getPixelSizeZ

      public ome.units.quantity.Length getPixelSizeZ()
    • getPositionX

      public List<Double> getPositionX()
    • getPositionY

      public List<Double> getPositionY()
    • getPositionZ

      public List<Double> getPositionZ()
    • getChannelNames

      public List<String> getChannelNames()
    • isExtendedDepthOfField

      public boolean isExtendedDepthOfField()
    • getTimestamp

      public ome.xml.model.primitives.Timestamp getTimestamp()
    • getTags

      public List<DicomTag> getTags()
      Provide the complete hierarchy of DICOM tags. Applications that need to query or display the complete tag structure should use this method to retrieve tags instead of relying upon original metadata.
    • stopWatch

      protected org.perf4j.slf4j.Slf4JStopWatch stopWatch()