dicom

package module
v1.0.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2024 License: MIT Imports: 20 Imported by: 0

README

dicom

High Performance Golang DICOM Medical Image Parser

👀 v1.0 just released!

This is a library and command-line tool to read, write, and generally work with DICOM medical image files in native Go. The goal is to build a full-featured, high-performance, and readable DICOM parser for the Go community.

After a fair bit of work, I've just released v1.0 of this library which is essentially rewritten from the ground up to be more canonical go, better tested, has new features, many bugfixes, and more (though there is always more to come on the roadmap).

Some notable features:

  • Parse multi-frame DICOM imagery (both encapsulated and native pixel data)
  • Channel-based streaming of Frames to a client as they are parsed out of the dicom
  • Cleaner Go Element and Dataset representations (in the absence of Go generics)
  • Better support for icon image sets in addition to primary image sets
  • Write and encode Datasets back to DICOM files
  • Enhanced testing and benchmarking support
  • Modern, canonical Go.

Usage

To use this in your golang project, import github.com/4ynyky/dicom. This repository supports Go modules, and regularly tags releases using semantic versioning. Typical usage is straightforward:


dataset, _ := dicom.ParseFile("testdata/1.dcm", nil) // See also: dicom.Parse which has a generic io.Reader API.

// Dataset will nicely print the DICOM dataset data out of the box.
fmt.Println(dataset)

// Dataset is also JSON serializable out of the box.
j, _ := json.Marshal(dataset)
fmt.Println(j)

More details about the package (and additional examples and APIs) can be found in the godoc.

CLI Tool

A CLI tool that uses this package to parse imagery and metadata out of DICOMs is provided in the cmd/dicomutil package. This tool can take in a DICOM, and dump out all the elements to STDOUT, in addition to writing out any imagery to the current working directory either as PNGs or JPEG (note, it does not perform any automatic color rescaling by default).

Installation

You can download the prebuilt binaries from the releases tab, or use the following to download the binary at the command line using my getbin tool:

wget -qO- "https://getbin.io/4ynyky/dicom" | tar xvz

(This attempts to infer your OS and 301 redirects wget to the latest github release asset for your system. Downloads come from GitHub releases).

Usage

dicomutil -path myfile.dcm

Note: for some DICOMs (with native pixel data) no automatic intensity scaling is applied yet (this is coming). You can apply this in your image viewer if needed (in Preview on mac, go to Tools->Adjust Color).

Build manually

To build manually, ensure you have make and go installed. Clone (or go get) this repo into your $GOPATH and then simply run:

make

Which will build the dicomutil binary and include it in a build/ folder in your current working directory.

You can also built it using Go directly:

go build -o dicomutil ./cmd/dicomutil

History

Here's a little more history on this repository for those who are interested!

v0

The v0 4ynyky/dicom started off as a hard fork of go-dicom which was not being maintained actively anymore (with the original author being supportive of my fork--thank you!). I worked on adding several new capabilities, bug fixes, and general maintainability refactors (like multiframe support, streaming parsing, updated APIs, low-level parsing bug fixes, and more).

That represents the v0 history of the repository.

v1

For v1 I rewrote and redesigned the core library essentially from scratch, and added several new features and bug fixes that only live in v1. The architecture and APIs are completely different, as is some of the underlying parser logic (to be more efficient and correct). Most of the core rewrite work happened at the s/1.0-rewrite branch.

Acknowledgements

Documentation

Overview

Package dicom provides a set of tools to read, write, and generally work with DICOM (https://dicom.nema.org/) medical image files in Go.

dicom.Parse and dicom.Write provide the core functionality to read and write DICOM Datasets. This package provides Go data structures that represent DICOM concepts (for example, dicom.Dataset and dicom.Element). These structures will pretty-print by default and are JSON serializable out of the box.

This package provides some advanced functionality as well, including: streaming image frames to an output channel, reading elements one-by-one (like an iterator pattern), flat iteration over nested elements in a Dataset, and more.

General usage is simple. Check out the package examples below and some function specific examples.

It may also be helpful to take a look at the example cmd/dicomutil program, which is a CLI built around this library to save out image frames from DICOMs and print out metadata to STDOUT.

Example (GetImageFrames)
package main

import (
	"fmt"
	"image/jpeg"
	"os"

	"github.com/4ynyky/dicom/pkg/tag"

	"github.com/4ynyky/dicom"
)

func main() {
	dataset, _ := dicom.ParseFile("testdata/1.dcm", nil)
	pixelDataElement, _ := dataset.FindElementByTag(tag.PixelData)
	pixelDataInfo := dicom.MustGetPixelDataInfo(pixelDataElement.Value)
	for i, fr := range pixelDataInfo.Frames {
		img, _ := fr.GetImage() // The Go image.Image for this frame
		f, _ := os.Create(fmt.Sprintf("image_%d.jpg", i))
		_ = jpeg.Encode(f, img, &jpeg.Options{Quality: 100})
		_ = f.Close()
	}
}
Output:

Example (ReadFile)
package main

import (
	"encoding/json"
	"fmt"

	"github.com/4ynyky/dicom"
)

func main() {
	// See also: dicom.Parse, which uses a more generic io.Reader API.
	dataset, _ := dicom.ParseFile("testdata/1.dcm", nil)

	// Dataset will nicely print the DICOM dataset data out of the box.
	fmt.Println(dataset)

	// Dataset is also JSON serializable out of the box.
	j, _ := json.Marshal(dataset)
	fmt.Println(j)
}
Output:

Example (StreamingFrames)
package main

import (
	"fmt"

	"github.com/4ynyky/dicom/pkg/frame"

	"github.com/4ynyky/dicom"
)

func main() {
	frameChan := make(chan *frame.Frame)

	// Go routine to handle streaming frames as they are parsed. This may be
	// useful when parsing a large DICOM with many frames from a network source,
	// where image frames can start to be processed before the entire DICOM
	// is parsed (or even read from storage).
	go func() {
		for fr := range frameChan {
			fmt.Println(fr)
		}
	}()

	dataset, _ := dicom.ParseFile("testdata/1.dcm", frameChan)
	fmt.Println(dataset) // The full dataset
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrorMagicWord indicates that the magic word was not found in the correct
	// location in the DICOM.
	ErrorMagicWord = errors.New("error, DICM magic word not found in correct location")
	// ErrorMetaElementGroupLength indicates that the MetaElementGroupLength
	// was not found where expected in the metadata.
	ErrorMetaElementGroupLength = errors.New("MetaElementGroupLength tag not found where expected")
	// ErrorEndOfDICOM indicates to the callers of Parser.Next() that the DICOM
	// has been fully parsed. Users using one of the other Parse APIs should not
	// need to use this.
	ErrorEndOfDICOM = errors.New("this indicates to the caller of Next() that the DICOM has been fully parsed")

	// ErrorMismatchPixelDataLength indicates that the size calculated from DICOM mismatch the VL.
	ErrorMismatchPixelDataLength = errors.New("the size calculated from DICOM elements and the PixelData element's VL are mismatched")
)
View Source
var (
	// ErrorOWRequiresEvenVL indicates that an element with VR=OW had a not even
	// value length which is not allowed.
	ErrorOWRequiresEvenVL = errors.New("vr of OW requires even value length")
	// ErrorUnsupportedVR indicates that this VR is not supported.
	ErrorUnsupportedVR = errors.New("unsupported VR")
	// ErrorUnsupportedBitsAllocated indicates that the BitsAllocated in the
	// NativeFrame PixelData is unsupported. In this situation, the rest of the
	// dataset returned is still valid.
	ErrorUnsupportedBitsAllocated = errors.New("unsupported BitsAllocated")

	ErrorExpectedEvenLength = errors.New("field length is not even, in violation of DICOM spec")
)
View Source
var (
	// ErrorUnimplemented is for not yet finished things.
	ErrorUnimplemented = errors.New("this functionality is not yet implemented")
	// ErrorMismatchValueTypeAndVR is for when there's a discrepancy between the ValueType and what the VR specifies.
	ErrorMismatchValueTypeAndVR = errors.New("ValueType does not match the VR required")
	// ErrorUnexpectedValueType indicates an unexpected value type was seen.
	ErrorUnexpectedValueType = errors.New("Unexpected ValueType")
	// ErrorUnsupportedBitsPerSample indicates that the BitsPerSample in this
	// Dataset is not supported when unpacking native PixelData.
	ErrorUnsupportedBitsPerSample = errors.New("unsupported BitsPerSample value")
)
View Source
var ErrorElementNotFound = errors.New("element not found")

ErrorElementNotFound indicates that the requested element was not found in the Dataset.

View Source
var ErrorUnexpectedDataType = errors.New("the type of the data was unexpected or not allowed")

ErrorUnexpectedDataType indicates that an unexpected (not allowed) data type was sent to NewValue.

Functions

func ExhaustElementChannel

func ExhaustElementChannel(c <-chan *Element)

ExhaustElementChannel exhausts the channel iterator returned by Dataset.FlatIterator, ensuring that the underlying Go routine completes. When using Dataset.FlatIterator, if your program will exit for some reason without reading all the elements of the channel, you should be sure to call this function to prevent a phantom Goroutine. Or, if you don't need the channel interface, simply use Dataset.FlatStatefulIterator.

func MustGetBytes

func MustGetBytes(v Value) []byte

MustGetBytes attempts to get a Bytes value out of the provided Value, and will panic if it is unable to do so.

func MustGetFloats

func MustGetFloats(v Value) []float64

MustGetFloats attempts to get a Floats value out of the provided Value, and will panic if it is unable to do so.

func MustGetInts

func MustGetInts(v Value) []int

MustGetInts attempts to get an Ints value out of the provided value, and will panic if it is unable to do so.

func MustGetStrings

func MustGetStrings(v Value) []string

MustGetStrings attempts to get a Strings value out of the provided Value, and will panic if it is unable to do so.

func Write

func Write(out io.Writer, ds Dataset, opts ...WriteOption) error

Write will write the input DICOM dataset to the provided io.Writer as a complete DICOM (including any header information if available).

Types

type Dataset

type Dataset struct {
	Elements []*Element `json:"elements"`
}

Dataset represents a DICOM dataset, see https://dicom.nema.org/medical/dicom/current/output/html/part05.html#chapter_7.

This Dataset representation is JSON serializable out of the box (implements json.Marshaler) and will also pretty print as a string nicely (see String example). This Dataset includes several helper methods to find Elements within this dataset or iterate over every Element within this Dataset (including Elements nested within Sequences).

func Parse

func Parse(in io.Reader, bytesToRead int64, frameChan chan *frame.Frame, opts ...ParseOption) (Dataset, error)

func ParseFile

func ParseFile(filepath string, frameChan chan *frame.Frame, opts ...ParseOption) (Dataset, error)

ParseFile parses the entire DICOM at the given filepath. See dicom.Parse as well for a more generic io.Reader based API.

func ParseUntilEOF

func ParseUntilEOF(in io.Reader, frameChan chan *frame.Frame, opts ...ParseOption) (Dataset, error)

func (*Dataset) Equals added in v1.0.11

func (d *Dataset) Equals(target *Dataset) bool

Equals returns true if this Dataset equals the provided target Dataset, otherwise false.

func (*Dataset) FastFindElementByTagNested added in v1.0.11

func (d *Dataset) FastFindElementByTagNested(tag tag.Tag) bool

func (*Dataset) FastFlatIterator added in v1.0.11

func (d *Dataset) FastFlatIterator(tag tag.Tag) <-chan *Element

func (*Dataset) FindElementByTag

func (d *Dataset) FindElementByTag(tag tag.Tag) (*Element, error)

FindElementByTag searches through the dataset and returns a pointer to the matching element. It DOES NOT search within Sequences as well.

func (*Dataset) FindElementByTagNested

func (d *Dataset) FindElementByTagNested(tag tag.Tag) (*Element, error)

FindElementByTagNested searches through the dataset and returns a pointer to the matching element. This call searches through a flat representation of the dataset, including within sequences.

func (*Dataset) FlatIterator

func (d *Dataset) FlatIterator() <-chan *Element

FlatIterator will be deprecated soon in favor of Dataset.FlatStatefulIterator. Use FlatStatefulIterator instead of this, unless the channel API really makes your life a lot easier (and let the maintainers know on GitHub).

FlatIterator returns a channel upon which every element in this Dataset will be sent, including elements nested inside sequences.

If for some reason your code will not exhaust the iterator (read all elements), be sure to call ExhaustElementChannel to prevent leaving the underlying Goroutine alive (you can safely do this in a defer).

c := dataset.FlatIterator()
defer ExhaustElementChannel(c)
for elem := range c {
    // Even if you exit before reading everything in c (e.g. due to an
    // error)
    // things will be ok.
}

Note that the sequence element itself is sent on the channel in addition to the child elements in the sequence. TODO(4ynyky): decide if the sequence element itself should be sent or not

Example
nestedData := [][]*Element{
	{
		mustNewElement(tag.PatientName, []string{"Bob"}),
	},
}

data := Dataset{
	Elements: []*Element{
		mustNewElement(tag.Rows, []int{100}),
		mustNewElement(tag.Columns, []int{100}),
		makeSequenceElement(tag.AddOtherSequence, nestedData),
	},
}

// Use this style if you will always exhaust all of the elements in the
// channel. Otherwise, you must call ExhaustElementChannel. See the
// FlatIteratorWithExhaustAllElements example for that. If you don't need
// a channel API (just want to loop over items), use FlatStatefulIterator
// instead, which is much simpler.
for elem := range data.FlatIterator() {
	fmt.Println(elem.Tag)
}

// Note the output below includes all three leaf elements __as well as__ the sequence element's tag
Output:

(0028,0010)
(0028,0011)
(0010,0010)
(0046,0102)

func (*Dataset) FlatStatefulIterator

func (d *Dataset) FlatStatefulIterator() *FlatDatasetIterator

FlatStatefulIterator returns a stateful iterator that adheres to FlatDatasetIterator interface. This allows the caller to iterate over every element in the dataset, including elements nested inside sequences.

Important note: if the Dataset changes during the iteration (e.g. if elements are added or removed), those elements will not be included until a new iterator is created.

If you don't need to receive elements on a channel, and don't want to worry about always exhausting this iterator, this is the best and safest way to iterate over a Dataset. Unlike FlatIterator(), no special cleanup or channel exhausting is needed with this iterator.

Example
nestedData := [][]*Element{
	{
		{
			Tag:                 tag.PatientName,
			ValueRepresentation: tag.VRString,
			Value: &stringsValue{
				value: []string{"Bob"},
			},
		},
	},
}

data := Dataset{
	Elements: []*Element{
		{
			Tag:                 tag.Rows,
			ValueRepresentation: tag.VRInt32List,
			Value: &intsValue{
				value: []int{100},
			},
		},
		{
			Tag:                 tag.Columns,
			ValueRepresentation: tag.VRInt32List,
			Value: &intsValue{
				value: []int{200},
			},
		},
		makeSequenceElement(tag.AddOtherSequence, nestedData),
	},
}

for iter := data.FlatStatefulIterator(); iter.HasNext(); {
	fmt.Println(iter.Next().Tag)
}

// Note the output below includes all three leaf elements __as well as__ the sequence element's tag
Output:

(0028,0010)
(0028,0011)
(0010,0010)
(0046,0102)

func (*Dataset) String

func (d *Dataset) String() string

String returns a printable representation of this dataset as a string, including printing out elements nested inside sequence elements.

Example
d := Dataset{
	Elements: []*Element{
		{
			Tag:                    tag.Rows,
			ValueRepresentation:    tag.VRInt32List,
			RawValueRepresentation: "UL",
			Value: &intsValue{
				value: []int{100},
			},
		},
		{
			Tag:                    tag.Columns,
			ValueRepresentation:    tag.VRInt32List,
			RawValueRepresentation: "UL",
			Value: &intsValue{
				value: []int{200},
			},
		},
	},
}

fmt.Println(d.String())
Output:

[
  Tag: (0028,0010)
  Tag Name: Rows
  VR: VRInt32List
  VR Raw: UL
  VL: 0
  Value: [100]
]

[
  Tag: (0028,0011)
  Tag Name: Columns
  VR: VRInt32List
  VR Raw: UL
  VL: 0
  Value: [200]
]

type Element

type Element struct {
	Tag                    tag.Tag    `json:"tag"`
	ValueRepresentation    tag.VRKind `json:"VR"`
	RawValueRepresentation string     `json:"rawVR"`
	ValueLength            uint32     `json:"valueLength"`
	Value                  Value      `json:"value"`
}

Element represents a standard DICOM data element (see the DICOM standard: https://dicom.nema.org/medical/dicom/current/output/html/part05.html#sect_7.1 ). This Element can be serialized to JSON out of the box and pretty printed as a string via the String() method.

func NewElement

func NewElement(t tag.Tag, data any) (*Element, error)

NewElement creates a new DICOM Element with the supplied tag and with a value built from the provided data. The data can be one of the types that is acceptable to NewValue.

func (*Element) Equals added in v1.0.11

func (e *Element) Equals(target *Element) bool

Equals returns true if this Element equals the provided target Element, otherwise false.

func (*Element) String

func (e *Element) String() string

type FlatDatasetIterator

type FlatDatasetIterator struct {
	// contains filtered or unexported fields
}

FlatDatasetIterator is a stateful iterator over a Dataset.

func (*FlatDatasetIterator) HasNext

func (f *FlatDatasetIterator) HasNext() bool

HasNext indicates if the iterator as another element.

func (*FlatDatasetIterator) Next

func (f *FlatDatasetIterator) Next() *Element

Next gets and returns the next element in the iterator.

type ParseOption

type ParseOption func(*parseOptSet)

ParseOption represents an option that can be passed to NewParser.

func AllowMismatchPixelDataLength

func AllowMismatchPixelDataLength() ParseOption

AllowMismatchPixelDataLength allows parser to ignore an error when the length calculated from elements do not match with value length.

func AllowMissingMetaElementGroupLength added in v1.0.11

func AllowMissingMetaElementGroupLength() ParseOption

AllowMissingMetaElementGroupLength allows parser to work around missing metaelement group length tag (0x0002,0x0000) by reading elements only in group 2.

func SkipMetadataReadOnNewParserInit

func SkipMetadataReadOnNewParserInit() ParseOption

SkipMetadataReadOnNewParserInit makes NewParser skip trying to parse metadata. This will make the Parser default to implicit little endian byte order. Any metatata tags found in the dataset will still be available when parsing.

func SkipPixelData

func SkipPixelData() ParseOption

SkipPixelData skips reading data from the PixelData tag, wherever it appears (e.g. even if within an IconSequence). A PixelDataInfo will be added to the Dataset with the IntentionallySkipped property set to true, and no other data. Use this option if you don't need the PixelData value to be in the Dataset at all, and want to save both CPU and Memory. If you need the PixelData value in the Dataset (e.g. so it can be written out identically later) but _don't_ want to process/parse the value, see the SkipProcessingPixelDataValue option below.

func SkipProcessingPixelDataValue

func SkipProcessingPixelDataValue() ParseOption

SkipProcessingPixelDataValue will attempt to skip processing the _value_ of any PixelData elements. Unlike SkipPixelData(), this means the PixelData bytes will still be read into the Dataset, and can be written back out via this library's write functionality. Specifically, if this option is set, a PixelData element will be added to the dataset with the PixelDataInfo.IntentionallyUnprocessed = true, and the raw bytes of the entire PixelData element stored in PixelDataInfo.UnprocessedValueData.

In the future, we may be able to extend this functionality to support on-demand processing of elements elsewhere in the library.

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser is a struct that allows a user to parse Elements from a DICOM element-by-element using Next(), which may be useful for some streaming processing applications. If you instead just want to parse the whole input DICOM at once, just use the dicom.Parse(...) method.

func NewParser

func NewParser(in io.Reader, bytesToRead int64, frameChannel chan *frame.Frame, opts ...ParseOption) (*Parser, error)

NewParser returns a new Parser that points to the provided io.Reader, with bytesToRead bytes left to read. NewParser will read the DICOM header and metadata as part of initialization.

frameChannel is an optional channel (can be nil) upon which DICOM image frames will be sent as they are parsed (if provided).

func (*Parser) GetMetadata

func (p *Parser) GetMetadata() Dataset

GetMetadata returns just the set of metadata elements that have been parsed so far.

func (*Parser) Next

func (p *Parser) Next() (*Element, error)

Next parses and returns the next top-level element from the DICOM this Parser points to.

func (*Parser) SetTransferSyntax

func (p *Parser) SetTransferSyntax(bo binary.ByteOrder, implicit bool)

SetTransferSyntax sets the transfer syntax for the underlying *dicomio.Reader.

type PixelDataInfo

type PixelDataInfo struct {
	// IntentionallySkipped indicates that reading the PixelData value was
	// intentionally skipped and no Value data for this tag was read.
	// This is likely true if the dicom.SkipPixelData option was set. If true,
	// the rest of this PixelDataInfo will be empty.
	IntentionallySkipped bool `json:"intentionallySkipped"`

	// Frames hold the processed PixelData frames (either Native or Encapsulated
	// PixelData).
	Frames []*frame.Frame

	// ParseErr indicates if there was an error when reading this Frame from the DICOM.
	// If this is set, this means fallback behavior was triggered to blindly write the PixelData bytes to an encapsulated frame.
	// The ParseErr will contain details about the specific error encountered.
	ParseErr       error `json:"parseErr"`
	IsEncapsulated bool  `json:"isEncapsulated"`
	Offsets        []uint32

	// IntentionallyUnprocessed indicates that the PixelData Value was actually
	// read (as opposed to skipped over, as in IntentionallySkipped above) and
	// blindly placed into RawData (if possible). Writing this element back out
	// should work. This will be true if the
	// dicom.SkipProcessingPixelDataValue flag is set with a PixelData tag.
	IntentionallyUnprocessed bool `json:"intentionallyUnprocessed"`
	// UnprocessedValueData holds the unprocessed Element value data if
	// IntentionallyUnprocessed=true.
	UnprocessedValueData []byte
}

PixelDataInfo is a representation of DICOM PixelData.

func MustGetPixelDataInfo

func MustGetPixelDataInfo(v Value) PixelDataInfo

MustGetPixelDataInfo attempts to get a PixelDataInfo value out of the provided Value, and will panic if it is unable to do so.

type SequenceItemValue

type SequenceItemValue struct {
	// contains filtered or unexported fields
}

SequenceItemValue is a Value that represents a single Sequence Item. Learn more about Sequences at https://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_7.5.html.

func (*SequenceItemValue) Equals added in v1.0.11

func (s *SequenceItemValue) Equals(target Value) bool

func (*SequenceItemValue) GetValue

func (s *SequenceItemValue) GetValue() any

GetValue returns the underlying value that this Value holds. What type is returned here can be determined exactly from the ValueType() of this Value (see the ValueType godoc).

func (*SequenceItemValue) MarshalJSON

func (s *SequenceItemValue) MarshalJSON() ([]byte, error)

MarshalJSON is the method used to marshal this struct to JSON.

func (*SequenceItemValue) String

func (s *SequenceItemValue) String() string

String is used to get a string representation of this struct.

func (*SequenceItemValue) ValueType

func (s *SequenceItemValue) ValueType() ValueType

ValueType returns the underlying ValueType of this Value. This can be used to unpack the underlying data in this Value.

type Value

type Value interface {

	// ValueType returns the underlying ValueType of this Value. This can be used to unpack the underlying data in this
	// Value.
	ValueType() ValueType
	// GetValue returns the underlying value that this Value holds. What type is returned here can be determined exactly
	// from the ValueType() of this Value (see the ValueType godoc).
	GetValue() any // TODO: rename to Get to read cleaner
	String() string
	MarshalJSON() ([]byte, error)
	// Equals returns true if this value equals the input Value.
	Equals(Value) bool
	// contains filtered or unexported methods
}

Value represents a DICOM value. The underlying data that a Value stores can be determined by inspecting its ValueType. DICOM values typically can be one of many types (ints, strings, bytes, sequences of other elements, etc), so this Value interface attempts to represent this as canoically as possible in Golang (since generics do not exist yet).

Value is JSON serializable out of the box (implements json.Marshaler).

If necessary, a Value's data can be efficiently unpacked by inspecting its underlying ValueType and either using a Golang type assertion or using the helper functions provided (like MustGetStrings). Because for each ValueType there is exactly one underlying Golang type, this should be safe, efficient, and straightforward.

switch(myvalue.ValueType()) {
	case dicom.Strings:
		// We know the underlying Golang type is []string
		fmt.Println(dicom.MustGetStrings(myvalue)[0])
		// or
		s := myvalue.GetValue().([]string)
		break;
	case dicom.Bytes:
		// ...
}

Unpacking the data like above is only necessary if something specific needs to be done with the underlying data. See the Element and Dataset examples as well to see how to work with this kind of data, and common patterns for doing so.

func NewValue

func NewValue(data any) (Value, error)

NewValue creates a new DICOM value for the supplied data. Likely most useful if creating an Element in testing or write scenarios.

Data must be one of the following types, otherwise and error will be returned (ErrorUnexpectedDataType).

Acceptable types: []int, []string, []byte, []float64, PixelDataInfo, [][]*Element (represents a sequence, which contains several items which each contain several elements).

type ValueType

type ValueType int

ValueType is a type that represents the type of a Value. It is an enumerated set, and the set of values can be found below.

const (
	// Strings represents an underlying value of []string
	Strings ValueType = iota
	// Bytes represents an underlying value of []byte
	Bytes
	// Ints represents an underlying value of []int
	Ints
	// PixelData represents an underlying value of PixelDataInfo
	PixelData
	// SequenceItem represents an underlying value of []*Element
	SequenceItem
	// Sequences represents an underlying value of []SequenceItem
	Sequences
	// Floats represents an underlying value of []float64
	Floats
)

Possible ValueTypes that represent the different value types for information parsed into DICOM element values. Each ValueType corresponds to exactly one underlying Golang type.

type WriteOption

type WriteOption func(*writeOptSet)

WriteOption represents an option that can be passed to WriteDataset. Later options will override previous options if applicable.

func DefaultMissingTransferSyntax

func DefaultMissingTransferSyntax() WriteOption

DefaultMissingTransferSyntax returns a WriteOption indicating that a missing transferSyntax should not raise an error, and instead the default LittleEndian Implicit transfer syntax should be used and written out as a Metadata element in the Dataset. TODO(4ynyky): consider deprecating in favor of OverrideMissingTransferSyntax.

func OverrideMissingTransferSyntax added in v1.0.11

func OverrideMissingTransferSyntax(transferSyntaxUID string) WriteOption

OverrideMissingTransferSyntax indicates that if the Dataset to be written does _not_ have a transfer syntax UID in its metadata, the Dataset should be written out with the provided transfer syntax UID if possible. A transfer syntax uid element with the specified transfer syntax will be written to the metadata as well.

If the Writer is unable to recognize or write the dataset using the provided transferSyntaxUID, an error will be returned at initialization time.

func SkipVRVerification

func SkipVRVerification() WriteOption

SkipVRVerification returns a WriteOption that skips VR verification.

func SkipValueTypeVerification

func SkipValueTypeVerification() WriteOption

SkipValueTypeVerification returns WriteOption function that skips checking ValueType for concurrency with VR and casting

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer is a struct that allows element-by element writing to a DICOM writer.

func NewWriter

func NewWriter(out io.Writer, opts ...WriteOption) (*Writer, error)

NewWriter returns a new Writer, that points to the provided io.Writer.

func (*Writer) SetTransferSyntax

func (w *Writer) SetTransferSyntax(bo binary.ByteOrder, implicit bool)

SetTransferSyntax sets the transfer syntax for the underlying dicomio.Writer.

func (*Writer) WriteElement

func (w *Writer) WriteElement(e *Element) error

WriteElement writes a single DICOM element to a Writer.

Directories

Path Synopsis
cmd
dicomutil
Really basic sanity check program
Really basic sanity check program
pkg
dcmtime
Package dcmtime contains functions and data types for converting DICOM date and time values to native go values.
Package dcmtime contains functions and data types for converting DICOM date and time values to native go values.
personname
The personname package provides methods and data types for inspecting Person Name (PN) DICOM Value Representations, as defined here:
The personname package provides methods and data types for inspecting Person Name (PN) DICOM Value Representations, as defined here:
tag
Package tag enumerates element tags defined in the DICOM standard.
Package tag enumerates element tags defined in the DICOM standard.
uid
vrraw
Package vrraw offers aliases to all VR abbreviations as defined here:
Package vrraw offers aliases to all VR abbreviations as defined here:

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL