Packages

Pure Elixir DICOM toolkit for P10 files, DICOM JSON, de-identification, and structured reports (all 33 PS3.16 root templates)

Current section

Files

Jump to
dicom lib dicom.ex
Raw

lib/dicom.ex

defmodule Dicom do
@moduledoc """
Pure Elixir DICOM P10 parser and writer.
Provides functions to parse DICOM Part 10 files into structured data sets
and serialize them back. Built on Elixir's binary pattern matching for
fast, streaming-capable parsing.
## Quick Start
# Parse a DICOM file
{:ok, data_set} = Dicom.parse_file("/path/to/image.dcm")
# Access patient name
patient_name = Dicom.DataSet.get(data_set, Dicom.Tag.patient_name())
# Write back to file
:ok = Dicom.write_file(data_set, "/path/to/output.dcm")
## DICOM Standard Coverage
- PS3.5 — Data Structures and Encoding
- PS3.6 — Data Dictionary
- PS3.10 — Media Storage and File Format
"""
@doc """
Parses a DICOM P10 binary into a `Dicom.DataSet`.
The binary must start with the 128-byte preamble followed by the "DICM"
magic bytes, then File Meta Information and the data set.
## Examples
{:ok, data_set} = Dicom.parse(binary)
{:error, :invalid_preamble} = Dicom.parse(<<"not dicom">>)
"""
@spec parse(binary()) :: {:ok, Dicom.DataSet.t()} | {:error, term()}
def parse(binary) when is_binary(binary) do
Dicom.P10.Reader.parse(binary)
end
@doc """
Parses a DICOM P10 file from disk.
## Examples
{:ok, data_set} = Dicom.parse_file("/path/to/image.dcm")
{:error, :enoent} = Dicom.parse_file("/nonexistent.dcm")
"""
@spec parse_file(Path.t()) :: {:ok, Dicom.DataSet.t()} | {:error, term()}
def parse_file(path) do
case File.read(path) do
{:ok, binary} -> parse(binary)
{:error, reason} -> {:error, reason}
end
end
@doc """
Parses a raw DICOM data set binary using the given transfer syntax UID.
Unlike `parse/1`, this expects only the encoded data set payload used by
DIMSE services, not a full Part 10 file with preamble and file meta.
"""
@spec parse_data_set(binary(), String.t()) :: {:ok, Dicom.DataSet.t()} | {:error, term()}
def parse_data_set(binary, transfer_syntax_uid)
when is_binary(binary) and is_binary(transfer_syntax_uid) do
Dicom.P10.Reader.parse_data_set(binary, transfer_syntax_uid)
end
@doc """
Parses a DICOM P10 binary into a lazy stream of events.
Returns an `Enumerable` that emits `Dicom.P10.Stream.Event` values as the
binary is traversed. Use with `Enum` or `Stream` functions.
## Examples
events = Dicom.stream_parse(binary)
tags = events
|> Stream.filter(&match?({:element, _}, &1))
|> Enum.map(fn {:element, elem} -> elem.tag end)
"""
@spec stream_parse(binary()) :: Enumerable.t()
def stream_parse(binary) when is_binary(binary) do
Dicom.P10.Stream.parse(binary)
end
@doc """
Parses a DICOM P10 file into a lazy stream of events.
Opens the file and streams events lazily. The file handle is closed
when the stream is fully consumed or halted.
## Examples
events = Dicom.stream_parse_file("/path/to/image.dcm")
{:ok, data_set} = Dicom.P10.Stream.to_data_set(events)
"""
@spec stream_parse_file(Path.t(), keyword()) :: Enumerable.t()
def stream_parse_file(path, opts \\ []) do
Dicom.P10.Stream.parse_file(path, opts)
end
@doc """
Serializes a `Dicom.DataSet` to DICOM P10 binary format.
"""
@spec write(Dicom.DataSet.t()) :: {:ok, binary()} | {:error, term()}
def write(%Dicom.DataSet{} = data_set) do
Dicom.P10.Writer.serialize(data_set)
end
@doc """
Serializes a `Dicom.DataSet` as a raw DICOM data set using the given transfer syntax UID.
Unlike `write/1`, this writes only the encoded data set payload used by DIMSE
services, without Part 10 preamble or file meta information.
"""
@spec write_data_set(Dicom.DataSet.t(), String.t()) :: {:ok, binary()} | {:error, term()}
def write_data_set(%Dicom.DataSet{} = data_set, transfer_syntax_uid)
when is_binary(transfer_syntax_uid) do
Dicom.P10.Writer.serialize_data_set(data_set, transfer_syntax_uid)
end
@doc """
Writes a `Dicom.DataSet` to a DICOM P10 file on disk.
"""
@spec write_file(Dicom.DataSet.t(), Path.t()) :: :ok | {:error, term()}
def write_file(%Dicom.DataSet{} = data_set, path) do
with {:ok, binary} <- write(data_set) do
File.write(path, binary)
end
end
end