element

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2026 License: MIT Imports: 8 Imported by: 0

README

Element

Encoding, decoding, and conversion of DICOM element values with byte order handling, DICOM format parsing (dates, person names, numeric strings), and value padding.

Quick Start

import (
    "github.com/amrshadid/go-dicom/element"
    "github.com/amrshadid/go-dicom/filebase"
)

encoder := element.NewValueEncoder(filebase.LittleEndian)
bytes := encoder.EncodeUint32(0x12345678)
val, _ := encoder.DecodeUint32(bytes)

parser := element.NewValueParser()
name := parser.ParsePersonName("Smith^John^A^Dr^Jr")
date, _ := parser.ParseDate("20231225")

padder := element.NewValuePadder()
padded := padder.Pad([]byte{0x01}, dataelem.AE) // pads to even length

API Reference

// Encoder
func NewValueEncoder(byteOrder filebase.ByteOrder) *ValueEncoder
func (ve *ValueEncoder) EncodeString(value string) []byte
func (ve *ValueEncoder) EncodeUint16/EncodeUint32/EncodeInt16/EncodeInt32/EncodeFloat32/EncodeFloat64
func (ve *ValueEncoder) DecodeString(data []byte) string
func (ve *ValueEncoder) DecodeUint16/DecodeUint32/DecodeInt16/DecodeInt32/DecodeFloat32/DecodeFloat64
func (ve *ValueEncoder) EncodeMultipleValues(values []string) []byte
func (ve *ValueEncoder) DecodeMultipleValues(data []byte) []string

// Parser
func NewValueParser() *ValueParser
func (vp *ValueParser) ParseIntegerString(value string) (int64, error)
func (vp *ValueParser) ParseDecimalString(value string) (float64, error)
func (vp *ValueParser) ParseDate(value string) (string, error)
func (vp *ValueParser) ParseTime(value string) (string, error)
func (vp *ValueParser) ParsePersonName(value string) map[string]string

// Padder
func NewValuePadder() *ValuePadder
func (vp *ValuePadder) Pad(value []byte, vr dataelem.VR) []byte
func (vp *ValuePadder) Unpad(value []byte, vr dataelem.VR) []byte
func (vp *ValuePadder) GetPadByte(vr dataelem.VR) byte
func (vp *ValuePadder) ValueMultiplicity(value []byte, vr dataelem.VR) int

// Converter (combines all three)
func NewValueConverter(byteOrder filebase.ByteOrder) *ValueConverter
func (vc *ValueConverter) ConvertToString(value interface{}, vr dataelem.VR) (string, error)
func (vc *ValueConverter) ConvertToBytes(value interface{}, vr dataelem.VR) ([]byte, error)

func ValidateLength(value []byte, vr dataelem.VR) error

References

  • DICOM PS3.5 - Value encoding, padding rules, date/time/person name formats

Documentation

Overview

    // Pad odd-length value
    padded := padder.Pad([]byte{0x01}, dataelem.AE)
    fmt.Printf("Length: %d\n", len(padded))  // 2

    // Unpad value
    unpadded := padder.Unpad([]byte{0x01, 0x20}, dataelem.AE)
    fmt.Printf("Length: %d\n", len(unpadded))  // 1

    // Get multiplicity
    mult := padder.ValueMultiplicity([]byte("A\\B\\C"), dataelem.AE)
    fmt.Printf("Count: %d\n", mult)  // 3
}

Advanced Usage

## Byte Order Handling

Different DICOM transfer syntaxes use different byte orders:

// Little-endian (Implicit VR, Explicit VR LE)
leEncoder := element.NewValueEncoder(filebase.LittleEndian)
leBytes := leEncoder.EncodeUint32(0x12345678)
// Result: {0x78, 0x56, 0x34, 0x12}

// Big-endian (Explicit VR BE)
beEncoder := element.NewValueEncoder(filebase.BigEndian)
beBytes := beEncoder.EncodeUint32(0x12345678)
// Result: {0x12, 0x34, 0x56, 0x78}

## Value Converter for Complete Processing

Combine encoding, parsing, and padding:

converter := element.NewValueConverter(filebase.LittleEndian)

// Get component encoders
encoder := converter.GetEncoder()
parser := converter.GetParser()
padder := converter.GetPadder()

// Convert to string
str, _ := converter.ConvertToString([]byte("Hello"), dataelem.LO)

// Convert to bytes
bytes, _ := converter.ConvertToBytes("Hello", dataelem.LO)

## Validation

Validate value properties before encoding:

// Check even length (except for binary VRs)
if err := element.ValidateLength([]byte("Hello"), dataelem.LO); err != nil {
    log.Fatal(err)
}

Data Structures

## ValueEncoder

type ValueEncoder struct {
    // Unexported field:
    // - byteOrder: ByteOrder (LittleEndian or BigEndian)
}

Encodes/decodes values with byte order support.

## ValueParser

type ValueParser struct {
    // No internal state
}

Parses DICOM-specific string formats (stateless).

## ValuePadder

type ValuePadder struct {
    // No internal state
}

Handles value padding (stateless).

## ValueConverter

type ValueConverter struct {
    // Unexported fields:
    // - encoder: *ValueEncoder
    // - parser: *ValueParser
    // - padder: *ValuePadder
}

Combines encoder, parser, and padder for complete value processing.

API Reference

## ValueEncoder Creation

### NewValueEncoder

func NewValueEncoder(byteOrder filebase.ByteOrder) *ValueEncoder

Creates new ValueEncoder with specified byte order.

**Parameters:** - `byteOrder`: filebase.LittleEndian or filebase.BigEndian

**Returns:** ValueEncoder pointer

**Example:** ```go enc := element.NewValueEncoder(filebase.LittleEndian) ```

## Encoding Methods

### EncodeString

func (ve *ValueEncoder) EncodeString(value string) []byte

Encodes string to bytes (direct conversion).

### EncodeUint16

func (ve *ValueEncoder) EncodeUint16(value uint16) []byte

Encodes uint16 with configured byte order (returns 2 bytes).

### EncodeUint32

func (ve *ValueEncoder) EncodeUint32(value uint32) []byte

Encodes uint32 with configured byte order (returns 4 bytes).

### EncodeInt16

func (ve *ValueEncoder) EncodeInt16(value int16) []byte

Encodes int16 with configured byte order (returns 2 bytes).

### EncodeInt32

func (ve *ValueEncoder) EncodeInt32(value int32) []byte

Encodes int32 with configured byte order (returns 4 bytes).

### EncodeFloat32

func (ve *ValueEncoder) EncodeFloat32(value float32) []byte

Encodes float32 with configured byte order (returns 4 bytes).

### EncodeFloat64

func (ve *ValueEncoder) EncodeFloat64(value float64) []byte

Encodes float64 with configured byte order (returns 8 bytes).

### EncodeMultipleValues

func (ve *ValueEncoder) EncodeMultipleValues(values []string) []byte

Encodes multiple values separated by backslash.

## Decoding Methods

### DecodeString

func (ve *ValueEncoder) DecodeString(data []byte) string

Decodes bytes to string, trimming whitespace.

### DecodeUint16

func (ve *ValueEncoder) DecodeUint16(data []byte) (uint16, error)

Decodes 2 bytes to uint16 with configured byte order.

### DecodeUint32

func (ve *ValueEncoder) DecodeUint32(data []byte) (uint32, error)

Decodes 4 bytes to uint32 with configured byte order.

### DecodeInt16

func (ve *ValueEncoder) DecodeInt16(data []byte) (int16, error)

Decodes 2 bytes to int16 with configured byte order.

### DecodeInt32

func (ve *ValueEncoder) DecodeInt32(data []byte) (int32, error)

Decodes 4 bytes to int32 with configured byte order.

### DecodeFloat32

func (ve *ValueEncoder) DecodeFloat32(data []byte) (float32, error)

Decodes 4 bytes to float32 with configured byte order.

### DecodeFloat64

func (ve *ValueEncoder) DecodeFloat64(data []byte) (float64, error)

Decodes 8 bytes to float64 with configured byte order.

### DecodeMultipleValues

func (ve *ValueEncoder) DecodeMultipleValues(data []byte) []string

Decodes backslash-separated values to string slice.

## ValueParser Methods

### NewValueParser

func NewValueParser() *ValueParser

Creates new ValueParser.

### ParseIntegerString

func (vp *ValueParser) ParseIntegerString(value string) (int64, error)

Parses IS (Integer String) value (e.g., " 123 ").

### ParseDecimalString

func (vp *ValueParser) ParseDecimalString(value string) (float64, error)

Parses DS (Decimal String) value (e.g., "3.14159").

### ParseDate

func (vp *ValueParser) ParseDate(value string) (string, error)

Validates and returns DA (Date) in YYYYMMDD format.

### ParseTime

func (vp *ValueParser) ParseTime(value string) (string, error)

Validates TM (Time) format (HHMMSS or HHMMSSFFFFFF).

### ParsePersonName

func (vp *ValueParser) ParsePersonName(value string) map[string]string

Parses PN (Person Name) with components: FamilyName, GivenName, MiddleName, NamePrefix, NameSuffix.

## ValuePadder Methods

### NewValuePadder

func NewValuePadder() *ValuePadder

Creates new ValuePadder.

### GetPadByte

func (vp *ValuePadder) GetPadByte(vr dataelem.VR) byte

Returns padding byte for VR (0x20 for text, 0x00 for binary).

### Pad

func (vp *ValuePadder) Pad(value []byte, vr dataelem.VR) []byte

Pads value to even length.

### Unpad

func (vp *ValuePadder) Unpad(value []byte, vr dataelem.VR) []byte

Removes padding from value.

### ValueMultiplicity

func (vp *ValuePadder) ValueMultiplicity(value []byte, vr dataelem.VR) int

Counts values (for backslash-separated values).

## ValueConverter Methods

### NewValueConverter

func NewValueConverter(byteOrder filebase.ByteOrder) *ValueConverter

Creates ValueConverter with encoder, parser, and padder.

### GetEncoder/GetParser/GetPadder

func (vc *ValueConverter) GetEncoder() *ValueEncoder
func (vc *ValueConverter) GetParser() *ValueParser
func (vc *ValueConverter) GetPadder() *ValuePadder

Returns component converters.

### ConvertToString

func (vc *ValueConverter) ConvertToString(value interface{}, vr dataelem.VR) (string, error)

Converts value to string representation.

### ConvertToBytes

func (vc *ValueConverter) ConvertToBytes(value interface{}, vr dataelem.VR) ([]byte, error)

Converts value to binary representation.

### ValidateLength

func ValidateLength(value []byte, vr dataelem.VR) error

Validates value length for VR (even length except for binary VRs).

Performance Characteristics

| Operation | Complexity | Description | |-----------|-----------|-------------| | NewValueEncoder | O(1) | Simple initialization | | NewValueParser | O(1) | Simple initialization | | NewValuePadder | O(1) | Simple initialization | | NewValueConverter | O(1) | Creates 3 components | | EncodeString | O(n) | n = string length | | EncodeUint16/32 | O(1) | Fixed size | | EncodeFloat32/64 | O(1) | Fixed size | | DecodeString | O(n) | n = data length | | DecodeUint16/32 | O(1) | Fixed size + validation | | DecodeFloat32/64 | O(1) | Fixed size + conversion | | ParseIntegerString | O(n) | n = string length | | ParseDecimalString | O(n) | n = string length | | ParseDate | O(1) | Fixed length validation | | ParseTime | O(n) | n = string length | | ParsePersonName | O(n) | n = string length (split on ^) | | Pad | O(1) | Append 1 byte if needed | | Unpad | O(k) | k = trailing padding bytes | | ValueMultiplicity | O(n) | n = data length (count backslashes) | | ValidateLength | O(1) | Length check |

Padding Rules

DICOM requires values to have even length. Padding rules by VR:

  • Text VRs (AE, AS, CS, DA, DS, DT, LO, LT, PN, SH, ST, UC, UI, UR, UT): Pad with 0x20 (space)
  • Binary VRs (OB, OD, OF, OL, OW, UN): Pad with 0x00 (null)
  • Numeric VRs: Pad with 0x20 (space)

Byte Order Handling

Multi-byte integer encoding depends on byte order:

  • LittleEndian (most common): Least significant byte first
  • BigEndian (Explicit VR BE): Most significant byte first

Use Cases

## Value Encoding for DICOM Writing

Encode values when writing DICOM files.

## Value Decoding for DICOM Reading

Decode values when reading DICOM files.

## Format Validation

Validate dates, times, and other specific formats.

## Person Name Parsing

Parse person names into components for display/search.

## Value Padding Handling

Ensure values meet DICOM even-length requirement.

Limitations

- No support for fractional values in IS (Integer String) - Limited Unicode support (assumes ASCII/UTF-8) - No automatic timezone handling for time values - Person name parsing limited to first 5 components

- **filebase**: Byte order handling - **dataelem**: Data element and VR definitions - **dataset**: Dataset operations using element values - **filereader**: Reading DICOM with element value decoding - **filewriter**: Writing DICOM with element value encoding

Best Practices

## Use ValueConverter for Complete Processing

ValueConverter provides integrated access to all value processing:

converter := element.NewValueConverter(byteOrder)
encoder := converter.GetEncoder()
parser := converter.GetParser()
padder := converter.GetPadder()

## Validate Before Encoding

Check value properties before encoding:

if err := element.ValidateLength(data, vr); err != nil {
    log.Fatal(err)
}

## Handle Byte Order Properly

Use correct byte order for transfer syntax:

// Implicit VR or Explicit VR LE: LittleEndian
// Explicit VR BE: BigEndian
encoder := element.NewValueEncoder(byteOrder)

DICOM Compliance

Implements DICOM standard (PS3.5) for: - Value encoding/decoding - Value Representation (VR) handling - Value padding rules - Date/Time/Person Name formats - Character set handling - Backslash-separated multiple values

See: https://www.dicomstandard.org/

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExecuteDecodingHook

func ExecuteDecodingHook(vr dataelem.VR, bytesLength int, byteOrder filebase.ByteOrder) map[string]interface{}

ExecuteDecodingHook executes a hook for value decoding operations.

func ExecuteEncodingHook

func ExecuteEncodingHook(vr dataelem.VR, value interface{}, byteOrder filebase.ByteOrder) map[string]interface{}

ExecuteEncodingHook executes a hook for value encoding operations.

func ExecutePaddingHook

func ExecutePaddingHook(vr dataelem.VR, originalLength, paddedLength int) map[string]interface{}

ExecutePaddingHook executes a hook for padding operations.

func ExecuteValidationHook

func ExecuteValidationHook(vr dataelem.VR, value []byte, valid bool, errorMsg string) map[string]interface{}

ExecuteValidationHook executes a hook for validation operations.

func ValidateLength

func ValidateLength(value []byte, vr dataelem.VR) error

ValidateLength validates a value length for a VR.

Types

type ValueConverter

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

ValueConverter converts values between different representations.

func NewValueConverter

func NewValueConverter(byteOrder filebase.ByteOrder) *ValueConverter

NewValueConverter creates a new ValueConverter.

func (*ValueConverter) ConvertToBytes

func (vc *ValueConverter) ConvertToBytes(value interface{}, vr dataelem.VR) ([]byte, error)

ConvertToBytes converts a value to bytes.

func (*ValueConverter) ConvertToString

func (vc *ValueConverter) ConvertToString(value interface{}, vr dataelem.VR) (string, error)

ConvertToString converts a value to string.

func (*ValueConverter) GetEncoder

func (vc *ValueConverter) GetEncoder() *ValueEncoder

GetEncoder returns the encoder.

func (*ValueConverter) GetPadder

func (vc *ValueConverter) GetPadder() *ValuePadder

GetPadder returns the padder.

func (*ValueConverter) GetParser

func (vc *ValueConverter) GetParser() *ValueParser

GetParser returns the parser.

type ValueEncoder

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

ValueEncoder encodes values to bytes according to DICOM standards.

func NewValueEncoder

func NewValueEncoder(byteOrder filebase.ByteOrder) *ValueEncoder

NewValueEncoder creates a new ValueEncoder.

func (*ValueEncoder) DecodeFloat32

func (ve *ValueEncoder) DecodeFloat32(data []byte) (float32, error)

DecodeFloat32 decodes bytes to a float32.

func (*ValueEncoder) DecodeFloat64

func (ve *ValueEncoder) DecodeFloat64(data []byte) (float64, error)

DecodeFloat64 decodes bytes to a float64.

func (*ValueEncoder) DecodeInt16

func (ve *ValueEncoder) DecodeInt16(data []byte) (int16, error)

DecodeInt16 decodes bytes to an int16.

func (*ValueEncoder) DecodeInt32

func (ve *ValueEncoder) DecodeInt32(data []byte) (int32, error)

DecodeInt32 decodes bytes to an int32.

func (*ValueEncoder) DecodeMultipleValues

func (ve *ValueEncoder) DecodeMultipleValues(data []byte) []string

DecodeMultipleValues decodes bytes to multiple string values.

func (*ValueEncoder) DecodeString

func (ve *ValueEncoder) DecodeString(data []byte) string

DecodeString decodes bytes to a string.

func (*ValueEncoder) DecodeUint16

func (ve *ValueEncoder) DecodeUint16(data []byte) (uint16, error)

DecodeUint16 decodes bytes to a uint16.

func (*ValueEncoder) DecodeUint32

func (ve *ValueEncoder) DecodeUint32(data []byte) (uint32, error)

DecodeUint32 decodes bytes to a uint32.

func (*ValueEncoder) EncodeFloat32

func (ve *ValueEncoder) EncodeFloat32(value float32) []byte

EncodeFloat32 encodes a float32 to bytes.

func (*ValueEncoder) EncodeFloat64

func (ve *ValueEncoder) EncodeFloat64(value float64) []byte

EncodeFloat64 encodes a float64 to bytes.

func (*ValueEncoder) EncodeInt16

func (ve *ValueEncoder) EncodeInt16(value int16) []byte

EncodeInt16 encodes an int16 to bytes.

func (*ValueEncoder) EncodeInt32

func (ve *ValueEncoder) EncodeInt32(value int32) []byte

EncodeInt32 encodes an int32 to bytes.

func (*ValueEncoder) EncodeMultipleValues

func (ve *ValueEncoder) EncodeMultipleValues(values []string) []byte

EncodeMultipleValues encodes multiple values separated by backslash.

func (*ValueEncoder) EncodeString

func (ve *ValueEncoder) EncodeString(value string) []byte

EncodeString encodes a string to bytes.

func (*ValueEncoder) EncodeUint16

func (ve *ValueEncoder) EncodeUint16(value uint16) []byte

EncodeUint16 encodes a uint16 to bytes.

func (*ValueEncoder) EncodeUint32

func (ve *ValueEncoder) EncodeUint32(value uint32) []byte

EncodeUint32 encodes a uint32 to bytes.

type ValuePadder

type ValuePadder struct{}

ValuePadder handles padding of DICOM values according to VR rules.

func NewValuePadder

func NewValuePadder() *ValuePadder

NewValuePadder creates a new ValuePadder.

func (*ValuePadder) GetPadByte

func (vp *ValuePadder) GetPadByte(vr dataelem.VR) byte

GetPadByte returns the padding byte for a VR.

func (*ValuePadder) Pad

func (vp *ValuePadder) Pad(value []byte, vr dataelem.VR) []byte

Pad pads a value to even length.

func (*ValuePadder) Unpad

func (vp *ValuePadder) Unpad(value []byte, vr dataelem.VR) []byte

Unpad removes trailing padding from a value.

func (*ValuePadder) ValueMultiplicity

func (vp *ValuePadder) ValueMultiplicity(value []byte, vr dataelem.VR) int

ValueMultiplicity calculates the value multiplicity.

type ValueParser

type ValueParser struct{}

ValueParser parses DICOM values according to VR rules.

func NewValueParser

func NewValueParser() *ValueParser

NewValueParser creates a new ValueParser.

func (*ValueParser) ParseDate

func (vp *ValueParser) ParseDate(value string) (string, error)

ParseDate parses a date in format YYYYMMDD.

func (*ValueParser) ParseDecimalString

func (vp *ValueParser) ParseDecimalString(value string) (float64, error)

ParseDecimalString parses a decimal string (DS) value.

func (*ValueParser) ParseIntegerString

func (vp *ValueParser) ParseIntegerString(value string) (int64, error)

ParseIntegerString parses an integer string (IS) value.

func (*ValueParser) ParsePersonName

func (vp *ValueParser) ParsePersonName(value string) map[string]string

ParsePersonName parses a person name (component groups separated by ^).

func (*ValueParser) ParseTime

func (vp *ValueParser) ParseTime(value string) (string, error)

ParseTime parses a time in format HHMMSS or HHMMSSFFFFFF.

Jump to

Keyboard shortcuts

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