Table of Contents

Class DicomFile

Namespace
Egami.Formats.Extended.Dicom
Assembly
Egami.Formats.Extended.dll

A DICOM file (PS3.10) read into its datasets: the file meta information, and the dataset in the file's transfer syntax, every element kept, sequences as nested datasets, encapsulated pixel data as raw fragments. Implicit and explicit VR little endian, explicit VR big endian and deflated files are read, with or without the preamble. In preview: the API may change before it is stable.

[Experimental("EGAMIX001", UrlFormat = "https://github.com/inexin/Egami/blob/main/docs/articles/formats/dicom.md")]
public sealed class DicomFile
Inheritance
DicomFile
Inherited Members

Examples

// The dataset of a DICOM file, every element kept; the preview API needs EGAMIX001 suppressed.
DicomFile file = DicomFile.Load("scan.dcm");
Console.WriteLine($"{file.TransferSyntax.Name}, {file.Dataset.Count} elements");

// Elements by PS3.6 keyword or by tag, null when the file has none.
string? modality = file.Dataset.GetString("Modality");
double? rows = file.Dataset.GetNumber("Rows");
DicomElement? name = file.Dataset[new DicomTag(0x0010, 0x0010)];
foreach (EgamiDiagnostic warning in file.Warnings)
{
    Console.WriteLine($"{warning.Id}: {warning.Message}");
}

Properties

Dataset

Gets the dataset: every element after the file meta information.

public DicomDataset Dataset { get; }

Property Value

DicomDataset

FileMetaInformation

Gets the file meta information (group 0002); empty for a bare dataset.

public DicomDataset FileMetaInformation { get; }

Property Value

DicomDataset

FrameCount

Gets the number of frames: Number of Frames (0028,0008), 1 when the dataset has none.

public int FrameCount { get; }

Property Value

int

HasPreamble

Gets whether the file starts with the 128-byte preamble and DICM, as PS3.10 requires.

public bool HasPreamble { get; }

Property Value

bool

TransferSyntax

Gets the transfer syntax the dataset was read in: the file meta information's, or the one a bare dataset looked like.

public DicomTransferSyntax TransferSyntax { get; }

Property Value

DicomTransferSyntax

Warnings

Gets the problems a lenient read recovered from and the irregularities it read past, such as Dicom.Truncated.

public IReadOnlyList<EgamiDiagnostic> Warnings { get; }

Property Value

IReadOnlyList<EgamiDiagnostic>

Methods

Load(Stream, EgamiContext?, ReaderOptions?)

Reads a DICOM file from a stream, to its end.

public static DicomFile Load(Stream stream, EgamiContext? context = null, ReaderOptions? options = null)

Parameters

stream Stream

The stream. It is left open.

context EgamiContext

The context whose safety limits apply, or null for the default.

options ReaderOptions

How to read: Recovery chooses between keeping what was read before damage and throwing.

Returns

DicomFile

The file.

Examples

// The dataset of a DICOM file, every element kept; the preview API needs EGAMIX001 suppressed.
DicomFile file = DicomFile.Load("scan.dcm");
Console.WriteLine($"{file.TransferSyntax.Name}, {file.Dataset.Count} elements");

// Elements by PS3.6 keyword or by tag, null when the file has none.
string? modality = file.Dataset.GetString("Modality");
double? rows = file.Dataset.GetNumber("Rows");
DicomElement? name = file.Dataset[new DicomTag(0x0010, 0x0010)];
foreach (EgamiDiagnostic warning in file.Warnings)
{
    Console.WriteLine($"{warning.Id}: {warning.Message}");
}

Exceptions

ArgumentNullException

stream is null.

CorruptDataException

The data is not DICOM, or is damaged and the read is strict.

LimitExceededException

The file breaks a safety limit.

Load(ReadOnlyMemory<byte>, EgamiContext?, ReaderOptions?)

Reads a DICOM file held in memory. The file keeps referring to data instead of copying it.

public static DicomFile Load(ReadOnlyMemory<byte> data, EgamiContext? context = null, ReaderOptions? options = null)

Parameters

data ReadOnlyMemory<byte>

The file's bytes.

context EgamiContext

The context whose safety limits apply, or null for the default.

options ReaderOptions

How to read: Recovery chooses between keeping what was read before damage and throwing.

Returns

DicomFile

The file.

Examples

// The dataset of a DICOM file, every element kept; the preview API needs EGAMIX001 suppressed.
DicomFile file = DicomFile.Load("scan.dcm");
Console.WriteLine($"{file.TransferSyntax.Name}, {file.Dataset.Count} elements");

// Elements by PS3.6 keyword or by tag, null when the file has none.
string? modality = file.Dataset.GetString("Modality");
double? rows = file.Dataset.GetNumber("Rows");
DicomElement? name = file.Dataset[new DicomTag(0x0010, 0x0010)];
foreach (EgamiDiagnostic warning in file.Warnings)
{
    Console.WriteLine($"{warning.Id}: {warning.Message}");
}

Exceptions

CorruptDataException

The data is not DICOM, or is damaged and the read is strict.

LimitExceededException

The file breaks a safety limit.

Load(string, EgamiContext?, ReaderOptions?)

Reads a DICOM file from a path.

public static DicomFile Load(string path, EgamiContext? context = null, ReaderOptions? options = null)

Parameters

path string

The file.

context EgamiContext

The context whose safety limits apply, or null for the default.

options ReaderOptions

How to read: Recovery chooses between keeping what was read before damage and throwing.

Returns

DicomFile

The file.

Examples

// The dataset of a DICOM file, every element kept; the preview API needs EGAMIX001 suppressed.
DicomFile file = DicomFile.Load("scan.dcm");
Console.WriteLine($"{file.TransferSyntax.Name}, {file.Dataset.Count} elements");

// Elements by PS3.6 keyword or by tag, null when the file has none.
string? modality = file.Dataset.GetString("Modality");
double? rows = file.Dataset.GetNumber("Rows");
DicomElement? name = file.Dataset[new DicomTag(0x0010, 0x0010)];
foreach (EgamiDiagnostic warning in file.Warnings)
{
    Console.WriteLine($"{warning.Id}: {warning.Message}");
}

Exceptions

ArgumentNullException

path is null.

CorruptDataException

The data is not DICOM, or is damaged and the read is strict.

LimitExceededException

The file breaks a safety limit.

LoadFrame(int, DicomReaderOptions?, EgamiContext?)

Decodes one frame of the file's pixel data, as Load(Stream, EgamiContext?, ReaderOptions?) of the file would, without reading the file again.

public Raster LoadFrame(int frame = 0, DicomReaderOptions? options = null, EgamiContext? context = null)

Parameters

frame int

The frame, from 0; it replaces Frame.

options DicomReaderOptions

What to give and how, or null for what a viewer shows.

context EgamiContext

The context whose safety limits apply, or null for the default.

Returns

Raster

The frame, in the pixel type that fits it (see DicomValues).

Examples

// Each frame of a multi-frame file is an image: LoadAll gives them all, DicomReaderOptions.Frame one of them.
using RasterList frames = Raster.LoadAll("scan.dcm", context);

// With the file read once, LoadFrame decodes frame after frame without reading it again.
DicomFile file = DicomFile.Load("scan.dcm");
for (int i = 0; i < file.FrameCount; i++)
{
    using Raster frame = file.LoadFrame(i);
    Console.WriteLine($"frame {i}: {frame.Width}x{frame.Height}");
}

Exceptions

ArgumentOutOfRangeException

frame is negative or not below FrameCount.

UnsupportedFormatException

The dataset has no image or no pixel data.

NotSupportedException

The pixel data is in a transfer syntax or layout that is not decoded, such as MPEG.

CorruptDataException

The pixel data is damaged and the read is strict, or cannot be read at all.

LimitExceededException

The frame breaks a safety limit.

Save(Stream, DicomWriterOptions?, EgamiContext?)

Writes the file again in the transfer syntax of options, keeping every element (group lengths, which would no longer be right, are left out). Pixel data already in that transfer syntax, or native in a little-endian file written native, is copied as it is; any other is decoded and encoded again, with the photometric interpretation and bit depth it then has. A lossy transfer syntax records itself in Lossy Image Compression, its ratio and method, and gives the image a new SOP Instance UID (PS3.3 C.7.6.1.1.5). The file meta information is made anew, keeping its other elements.

public void Save(Stream stream, DicomWriterOptions? options = null, EgamiContext? context = null)

Parameters

stream Stream

Where to write. It is left open.

options DicomWriterOptions

The transfer syntax and its settings, or null for Explicit VR Little Endian.

context EgamiContext

The context whose safety limits apply while the pixel data is decoded, or null for the default.

Examples

// An opened file saves again in another transfer syntax, every element kept and the pixel data coded anew.
DicomFile file = DicomFile.Load("scan.dcm");
file.Save("scan-rle.dcm", new DicomWriterOptions { TransferSyntax = DicomTransferSyntax.RleLossless });

// Lossy syntaxes record themselves (Lossy Image Compression) and give the image a new SOP Instance UID.
file.Save("scan-jpegls.dcm", new DicomWriterOptions
{
    TransferSyntax = DicomTransferSyntax.JpegLsNearLossless,
    Near = 2,
    OffsetTable = DicomOffsetTable.Extended,
});

Exceptions

ArgumentNullException

stream is null.

NotSupportedException

The pixel data cannot be decoded, or the transfer syntax cannot hold it, such as signed values in JPEG Baseline or more than 8 bits in lossy JPEG XL.

CorruptDataException

The pixel data is damaged.

Save(string, DicomWriterOptions?, EgamiContext?)

Writes the file again to a path, as Save(Stream, DicomWriterOptions?, EgamiContext?) does.

public void Save(string path, DicomWriterOptions? options = null, EgamiContext? context = null)

Parameters

path string

The file to write.

options DicomWriterOptions

The transfer syntax and its settings, or null for Explicit VR Little Endian.

context EgamiContext

The context whose safety limits apply while the pixel data is decoded, or null for the default.

Examples

// An opened file saves again in another transfer syntax, every element kept and the pixel data coded anew.
DicomFile file = DicomFile.Load("scan.dcm");
file.Save("scan-rle.dcm", new DicomWriterOptions { TransferSyntax = DicomTransferSyntax.RleLossless });

// Lossy syntaxes record themselves (Lossy Image Compression) and give the image a new SOP Instance UID.
file.Save("scan-jpegls.dcm", new DicomWriterOptions
{
    TransferSyntax = DicomTransferSyntax.JpegLsNearLossless,
    Near = 2,
    OffsetTable = DicomOffsetTable.Extended,
});

Exceptions

ArgumentNullException

path is null.

NotSupportedException

The pixel data cannot be decoded, or the transfer syntax cannot hold it.

CorruptDataException

The pixel data is damaged.