dcmjs-org/dcmjs/docs

Claude Code and agent skill by dcmjs-org/dcmjs

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Install

npx vskill@latest install dcmjs-org/dcmjs/docs

SKILL.md

AsyncDicomReader Skill Guide

Overview

The AsyncDicomReader is an asynchronous binary DICOM file reader that provides streaming capabilities for parsing DICOM files. It's designed to handle large DICOM files efficiently by reading and processing data incrementally rather than loading entire files into memory at once.

Key Features

  • Asynchronous/Streaming: Reads DICOM files incrementally using async/await patterns
  • Memory Efficient: Uses buffer streaming with automatic clearing to reduce memory footprint
  • Multiple Transfer Syntaxes: Supports Explicit Little Endian, Explicit Big Endian, and Implicit Little Endian as well as compressed syntaxes.
  • Pixel Data Handling: Handles both compressed and uncompressed pixel data
  • Sequence Support: Properly parses DICOM sequences with defined and undefined lengths
  • Character Set Support: Automatically handles different character encodings, but not multiple character encodings.
  • Error Handling: Configurable error handling for malformed files

Current Limitations

  • Files must contain the standard DICM preamble
  • Interface is preliminary and subject to change

Basic Usage

Reading a Complete DICOM File
javascript
import { AsyncDicomReader } from 'dcmjs';
async function readDicomFile(arrayBuffer) {
// Create reader instance
const reader = new AsyncDicomReader();
// Set the data source
reader.stream.setData(arrayBuffer);
// Read the entire file
await reader.readFile();
// Access the metadata and dataset
console.log('Meta information:', reader.meta);
console.log('Dataset:', reader.dict);
return reader;
}
Reading with Custom Options
javascript
async function readDicomFileWithOptions(arrayBuffer) {
const reader = new AsyncDicomReader({
isLittleEndian: true,
clearBuffers: true // Automatically clear consumed buffers
});
reader.stream.setData(arrayBuffer);
// Read with error tolerance and custom meta size limit
await reader.readFile({
ignoreErrors: true,
maxSizeMeta: 1024 * 20, // 20KB max for meta header
listener: customListener // Optional custom listener
});
return reader;
}
Using Custom Listeners

The reader uses a listener pattern to build the DICOM dataset. You can implement custom listeners to control how data is processed:

javascript
import { DicomMetadataListener } from 'dcmjs';
class CustomListener extends DicomMetadataListener {
addTag(tag, tagInfo) {
console.log(`Processing tag: ${tag} (${tagInfo.name})`);
super.addTag(tag, tagInfo);
}
value(val) {
// Process each value as it's read
super.value(val);
}
}
async function readWithCustomListener(arrayBuffer) {
const reader = new AsyncDicomReader();
reader.stream.setData(arrayBuffer);
await reader.readFile({
listener: new CustomListener()
});
return reader;
}

Architecture

Core Components
  1. BufferStream: Manages the underlying data buffer with automatic memory management
  2. Listener Pattern: Uses listeners to build the dataset incrementally
  3. Tag Reading: Parses DICOM tags with proper VR (Value Representation) handling
  4. Transfer Syntax Detection: Automatically detects and adapts to file transfer syntax
Reading Process

The reader follows this sequence:

  1. Preamble & Marker (128 bytes + "DICM")
  2. File Meta Information (Group 0x0002)
  3. Transfer Syntax Detection (from meta info)
  4. Dataset Reading (main DICOM data)
┌─────────────────┐
│ 128B Preamble │
├─────────────────┤
│ DICM Marker │
├─────────────────┤
│ Meta Info │ (Group 0x0002, Explicit Little Endian)
├─────────────────┤
│ Dataset │ (Uses detected Transfer Syntax)
└─────────────────┘

Advanced Usage

Reading Specific Sections
Reading Only Meta Information
javascript
async function readMetaOnly(arrayBuffer) {
const reader = new AsyncDicomReader();
reader.stream.setData(arrayBuffer);
// Read preamble
const hasPreamble = await reader.readPreamble();
if (!hasPreamble) {
throw new Error('No DICM marker found');
}
// Read only meta information
const meta = await reader.readMeta();
console.log('Transfer Syntax:', meta['00020010'].Value[0]);
console.log('SOP Class UID:', meta['00020002'].Value[0]);
return meta;
}
Reading Until Specific Tag
javascript
async function readUntilTag(arrayBuffer, targetTag) {
const reader = new AsyncDicomReader();
reader.stream.setData(arrayBuffer);
await reader.readPreamble();
await reader.readMeta();
const listener = new DicomMetadataListener();
await reader.read(listener, {
untilTag: targetTag,
includeUntilTagValue: false
});
return listener.pop();
}
Handling Pixel Data

The reader automatically detects compressed vs uncompressed pixel data:

Uncompressed Pixel Data
javascript
// Uncompressed pixel data is delivered as arrays
// Each frame is ALWAYS delivered as an array (ArrayBuffer[]), even for single frames
// Binary data can be fragmented - a single frame may be split across multiple ArrayBuffer fragments
// Multiple fragments are combined into one array per frame
// Large frames may be split into multiple fragments based on maxFragmentSize (default 128MB)
class PixelDataListener extends DicomMetadataListener {
constructor() {
super();
this.frames = [];
}
value(val) {
if (val instanceof ArrayBuffer || ArrayBuffer.isView(val)) {
this.frames.push(val);
}
super.value(val);
}
}
Compressed Pixel Data
javascript
// Compressed data is read as encapsulated format
// Each frame is ALWAYS delivered as an array (ArrayBuffer[]), even for single frames
// Video transfer syntaxes are handled as though they were a single frame
// Binary data can be delivered fragmented - a single frame may be split across multiple ArrayBuffer fragments
// Multiple fragments are combined into one array per frame
// Large frames may be split into multiple fragments based on maxFragmentSize (default 128MB)
async function readCompressedImage(arrayBuffer) {
const reader = new AsyncDicomReader();
const listener = new PixelDataListener();
reader.stream.setData(arrayBuffer);
await reader.readFile({ listener });
// listener.frames contains each compressed frame (each frame is an ArrayBuffer[])
return listener.frames;
}
Working with Sequences

Sequences are automatically parsed with proper nesting:

javascript
// Sequences are represented as arrays of objects
// Example: Referenced Series Sequence
async function readWithSequences(arrayBuffer) {
const reader = new AsyncDicomReader();
reader.stream.setData(arrayBuffer);
await reader.readFile();
// Access sequence items
const referencedSeries = reader.dict['00081115']; // Referenced Series Seq
if (referencedSeries) {
referencedSeries.Value.forEach((item, index) => {
console.log(`Series ${index}:`, item['0020000E']); // Series Instance UID
});
}
return reader;
}

Performance Considerations

Memory Management

The reader uses automatic buffer clearing to minimize memory usage:

javascript
// Enable buffer clearing (default)
const reader = new AsyncDicomReader({
clearBuffers: true
});
// The stream automatically calls consume() to clear processed data
// This prevents memory buildup during large file reads
Streaming Large Files

For very large files, the async nature prevents blocking:

javascript
async function streamLargeFile(fileHandle) {
const reader = new AsyncDicomReader();
// Read file in chunks
const chunkSize = 1024 * 1024; // 1MB chunks
let offset = 0;
const chunks = [];
while (true) {
const { done, value } = await fileHandle.read(chunkSize);
if (done) break;
chunks.push(value);
offset += value.byteLength;
}
// Combine chunks
const fullBuffer = new Uint8Array(offset);
let position = 0;
for (const chunk of chunks) {
fullBuffer.set(new Uint8Array(chunk), position);
position += chunk.byteLength;
}
reader.stream.setData(fullBuffer.buffer);
await reader.readFile();
return reader;
}

Error Handling

Handling Malformed Files
javascript
async function readWithErrorHandling(arrayBuffer) {
const reader = new AsyncDicomReader();
reader.stream.setData(arrayBuffer);
try {
await reader.readFile({
ignoreErrors: true, // Continue reading despite errors
maxSizeMeta: 1024 * 50 // Allow larger meta headers
});
} catch (error) {
console.error('Failed to read DICOM file:', error);
// Partial data may still be available
if (reader.meta) {
console.log('Meta information was read:', reader.meta);
}
throw error;
}
return reader;
}
Validation
javascript
async function validateDicomFile(arrayBuffer) {
const reader = new AsyncDicomReader();
reader.stream.setData(arrayBuffer);
// Check for DICM marker
const hasPreamble = await reader.readPreamble();
if (!hasPreamble) {
return {
valid: false,
error: 'Missing DICM preamble'
};
}
// Validate meta information
try {
const meta = await reader.readMeta();
if (!meta['00020010']) {
return {
valid: false,
error: 'Missing Transfer Syntax UID'
};
}
return {
valid: true,
transferSyntax: meta['00020010'].Value[0]
};
} catch (error) {
return {
valid: false,
error: error.message
};
}
}

API Reference

Constructor
javascript
new AsyncDicomReader(options)

Options:

  • isLittleEndian (boolean): Force specific endianness
  • clearBuffers (boolean): Enable automatic buffer clearing (default: true)
  • Additional options passed to ReadBufferStream
Methods
async readPreamble()

Reads the 128-byte preamble and DICM marker.

Returns: Promise<boolean> - true if DICM marker found

async readFile(options)

Reads the entire DICOM file including meta information and dataset.

Options:

  • listener (DicomMetadataListener): Custom listener for dataset building
  • ignoreErrors (boolean): Continue reading despite errors
  • maxSizeMeta (number): Maximum bytes to read for meta header

Returns: Promise<AsyncDicomReader> - The reader instance

async readMeta(options)

Reads only the file meta information (Group 0x0002).

Options:

  • maxSizeMeta (number): Maximum bytes for meta header (default: 10KB)
  • ignoreErrors (boolean): Allow reading files with malformed meta

Returns: Promise<Object> - Meta information dictionary

async read(listener, options)

Reads the dataset portion using the provided listener.

Parameters:

  • listener (DicomMetadataListener): Listener to build dataset
  • options.untilOffset (number): Stop reading at specific byte offset

Returns: Promise<Object> - Parsed dataset

readTagHeader(options)

Reads a single tag header (tag, VR, length).

Options:

  • untilTag (string): Stop when reaching this tag
  • includeUntilTagValue (boolean): Include the stop tag's value

Returns: Object - Tag information with structure:

javascript
{
tag: string, // Tag as hex string (e.g., "00100010")
tagObj: Tag, // Tag object
vr: string, // VR as string (e.g., "PN")
vrObj: VR, // ValueRepresentation object
length: number, // Value length (-1 for undefined)
vm: string, // Value multiplicity
name: string // Tag name from dictionary
}
Properties
  • syntax (string): Current transfer syntax UID
  • meta (Object): File meta information dictionary
  • dict (Object): Dataset dictionary
  • stream (ReadBufferStream): Underlying buffer stream
  • listener (DicomMetadataListener): Current listener instance

Common Patterns

Extract Specific Tags

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
345
Repository forks
131
Repository npm downloads, 7 days
36,133
7-day trend score
53

Stars and forks are for the whole GitHub repository, not this skill alone. Downloads are for the repository's npm package. Refreshed 19 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/dcmjs-org/dcmjs/docs/badge)](https://verified-skill.com/skills/dcmjs-org/dcmjs/docs)

Something wrong with this skill or its page? Tell us.