DICOM Basics using Java - Encapsulated Documents

Introduction

This is part of my series of articles on the DICOM standard. In this tutorial, we'll explore DICOM Encapsulated Documents, which allow you to store non-DICOM documents like PDF reports, CDA documents, and 3D models within DICOM objects for storage in PACS alongside images.

This capability is commonly used for radiology reports, pathology reports, consent forms, and other clinical documents that need to be associated with imaging studies.

Prerequisites

Before you begin, ensure you have the following:

  • Java JDK installed (Java 8 or later)
  • PixelMed Java DICOM Toolkit
  • A PDF file to encapsulate (optional)
  • You can find all the code demonstrated in this tutorial on GitHub here

“The soul becomes dyed with the color of its thoughts.” ~ Marcus Aurelius

The Theory Behind Encapsulated Documents

Encapsulated Documents address a fundamental challenge in healthcare IT: document unification. Clinical care generates diverse document types - reports, images, waveforms, PDFs - but patients need a unified longitudinal record.

The Document Heterogeneity Problem

Before DICOM encapsulation, clinical documents lived in separate silos:

  • PACS: Stored images but not text reports
  • RIS: Stored report text but couldn't associate with images
  • Document Management: Stored PDFs without clinical context
  • EMR: Attempted to link everything but with proprietary mechanisms

Encapsulated Documents allow any document type to be stored in PACS with the same patient/study associations as images. A radiology report PDF becomes a DICOM object linked to the imaging study it describes.

The DICOM Wrapper Concept

Encapsulation wraps the original document with DICOM metadata:

  • Patient Module: Links document to correct patient
  • Study Module: Associates with imaging study
  • Series Module: Modality="DOC" identifies as document
  • Encapsulated Document Module: Contains MIME type and the document bytes

The original document is preserved bit-for-bit in the Encapsulated Document attribute - a PDF encapsulated in DICOM can be extracted and will be identical to the original.

XDS-I and Cross-Enterprise Sharing

Encapsulated Documents play a key role in IHE's Cross-Enterprise Document Sharing for Imaging (XDS-I) profile. When sharing imaging data between organizations:

  • Reports can be shared alongside images
  • Both documents and images are retrievable via the same mechanisms
  • Metadata in the DICOM wrapper enables document registry indexing

The 3D Printing Revolution

STL and OBJ encapsulation (added to DICOM recently) enables storing 3D-printable models derived from medical imaging. A surgeon can:

  1. View CT images in PACS
  2. Generate 3D model of patient anatomy
  3. Store model as encapsulated STL in same study
  4. Print physical model for surgical planning

The model is permanently associated with its source imaging and available anywhere the study is accessible.

Encapsulated Document SOP Classes

SOP ClassUIDMIME TypeUse Case
Encapsulated PDF1.2.840.10008.5.1.4.1.1.104.1application/pdfReports, forms
Encapsulated CDA1.2.840.10008.5.1.4.1.1.104.2text/xmlHL7 CDA documents
Encapsulated STL1.2.840.10008.5.1.4.1.1.104.3model/stl3D printing models
Encapsulated OBJ1.2.840.10008.5.1.4.1.1.104.4model/obj3D surface models
Encapsulated MTL1.2.840.10008.5.1.4.1.1.104.5model/mtl3D model materials

Creating an Encapsulated PDF

package com.saravanansubramanian.dicom.pixelmedtutorial;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.pixelmed.dicom.*;

public class CreateEncapsulatedPdfDemo {

    public static void main(String[] args) {

        try {

            System.out.println("=== DICOM Encapsulated PDF Creation Demo ===\n");

            String pdfFilePath = "C:\\path\\to\\report.pdf";
            String outputFile = "C:\\temp\\encapsulated_pdf.dcm";

            // Read the PDF file
            byte[] pdfData = readFileBytes(pdfFilePath);
            System.out.println("PDF file size: " + pdfData.length + " bytes");

            // Create the encapsulated PDF DICOM object
            AttributeList list = createEncapsulatedPdf(
                pdfData,
                "Doe^John",
                "PAT123",
                "19700101",
                "M",
                "ACC456",
                "Chest CT Report",
                "1.2.3.4.5.6.7.8.9" // Study Instance UID to link to
            );

            // Add file meta information
            FileMetaInformation.addFileMetaInformation(
                list,
                TransferSyntax.ExplicitVRLittleEndian,
                "OurAET"
            );

            // Write the file
            list.write(outputFile);

            System.out.println("\nEncapsulated PDF created: " + outputFile);

        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
    }

    private static byte[] readFileBytes(String filePath) throws Exception {
        File file = new File(filePath);
        byte[] data = new byte[(int) file.length()];
        try (FileInputStream fis = new FileInputStream(file)) {
            fis.read(data);
        }
        return data;
    }
}

Building the Encapsulated PDF Attributes

private static AttributeList createEncapsulatedPdf(
        byte[] pdfData, String patientName, String patientId,
        String patientBirthDate, String patientSex,
        String accessionNumber, String documentTitle,
        String studyInstanceUID) throws Exception {

    AttributeList list = new AttributeList();

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
    SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
    Date now = new Date();
    String currentDate = dateFormat.format(now);
    String currentTime = timeFormat.format(now);

    // === SOP Common Module ===
    Attribute sopClass = new UniqueIdentifierAttribute(TagFromName.SOPClassUID);
    sopClass.addValue(SOPClass.EncapsulatedPDFStorage);
    list.put(sopClass);

    Attribute sopInstance = new UniqueIdentifierAttribute(TagFromName.SOPInstanceUID);
    sopInstance.addValue(UniqueIdentifierAttribute.createUID());
    list.put(sopInstance);

    // === Patient Module ===
    Attribute patNameAttr = new PersonNameAttribute(TagFromName.PatientName);
    patNameAttr.addValue(patientName);
    list.put(patNameAttr);

    Attribute patIdAttr = new LongStringAttribute(TagFromName.PatientID);
    patIdAttr.addValue(patientId);
    list.put(patIdAttr);

    // === Encapsulated Document Series Module ===
    Attribute modalityAttr = new CodeStringAttribute(TagFromName.Modality);
    modalityAttr.addValue("DOC"); // Document modality
    list.put(modalityAttr);

    // === Encapsulated Document Module ===
    Attribute burnedIn = new CodeStringAttribute(TagFromName.BurnedInAnnotation);
    burnedIn.addValue("YES"); // PDF likely contains patient info
    list.put(burnedIn);

    Attribute docTitleAttr = new LongStringAttribute(TagFromName.DocumentTitle);
    docTitleAttr.addValue(documentTitle);
    list.put(docTitleAttr);

    Attribute mimeType = new LongStringAttribute(TagFromName.MIMETypeOfEncapsulatedDocument);
    mimeType.addValue("application/pdf");
    list.put(mimeType);

    // === The actual PDF data ===
    OtherByteAttribute encapDoc = new OtherByteAttribute(TagFromName.EncapsulatedDocument);
    encapDoc.setValues(pdfData);
    list.put(encapDoc);

    return list;
}

Key Attributes for Encapsulated Documents

TagNameDescription
(0008,0016)SOP Class UID1.2.840.10008.5.1.4.1.1.104.1 for PDF
(0008,0060)ModalityDOC
(0008,0064)Conversion TypeWSD (Workstation)
(0028,0301)Burned In AnnotationYES if contains PHI
(0042,0010)Document TitleUser-friendly title
(0042,0012)MIME Typeapplication/pdf
(0042,0011)Encapsulated DocumentThe document bytes

Privacy Considerations

Encapsulated documents require special attention for privacy:

  • Burned In Annotation: Set to YES if the document contains PHI
  • De-identification: Standard DICOM anonymization tools cannot modify PDF content
  • Document Title: Should not contain PHI
  • Redaction: Consider using redacted PDFs for teaching/research

Common Use Cases

Use CaseDocument TypeNotes
Radiology ReportsPDFFinal signed reports
Pathology ReportsPDF/CDADiagnostic findings
Consent FormsPDFPatient consent documentation
Prior Exam ReportsPDFHistorical reports
Referral LettersPDFReferring physician letters
Lab ResultsCDAHL7 CDA structured documents
3D Print ModelsSTLSurgical planning models

Conclusion

DICOM Encapsulated Documents provide a standardized way to store non-image documents alongside medical images in PACS. This enables a unified archive for all patient-related clinical documents, improving workflow efficiency and data accessibility.

When implementing encapsulated documents, pay careful attention to privacy considerations, as the document content is not directly accessible to standard DICOM anonymization tools. In the next tutorial in this series, I will cover DICOM Presentation States for storing display settings separately from images. See you then!