-
Notifications
You must be signed in to change notification settings - Fork 75
[BUG] DICOM channels with a filter/transformer fail with IllegalStateException: state:EXPECT_FRAG on private undefined-length sequences #430
Description
Describe the bug
Any DICOM-typed connector that has a filter or transformer attached fails to process messages containing an undefined-length sequence under a private tag that dcm4che2 resolves to VR UN (implicit VR, tag not in its dictionary). Common real-world producers: FujiFILM (0029,E131) and Siemens MEDCOM (0029,1140). Messages with no filter/transformer pass through fine, because they never go through the XML round trip.
com.mirth.connect.donkey.model.message.MessageSerializerException: Error converting XML to DICOM
Caused by: java.lang.IllegalStateException: state:EXPECT_FRAG
at org.dcm4che2.io.ContentHandlerAdapter.startElement(...)
at com.mirth.connect.plugins.datatypes.dicom.DICOMSerializer.fromXML(...)
Root cause
dcm4che2 2.0.29's XML round trip is asymmetric:
DicomInputStreamreads aUNelement with undefined length whose items hold dataset elements and represents it asSQin memory.toXMLuses the streamingSAXWriter, which emits the wire VR:<tag0029E131 vr="UN" len="-1">with structured<item>children.fromXMLhands that toContentHandlerAdapter, which only enters its sequence state forvr="SQ"and otherwise expects fragments; the first<attr>inside the item throwsstate:EXPECT_FRAG.
dcm4che2 has had no release since 2015, so this cannot be fixed at the library.
To Reproduce
Programmatic, no fixtures needed (this is what the accompanying test does):
- Build a
BasicDicomObject,putNestedDicomObject(0x0029E131, item)with any element in the item, write it as Implicit VR Little Endian. new DICOMSerializer().toXML(base64)— note the output carriesvr="UN"with an<item>child.fromXML(thatXml)throws.
Or in a running engine: DICOM Listener → any transformer step → send a Fuji or Siemens CR/CT object carrying a private sequence.
Expected behavior
fromXML accepts the XML toXML produced, and the re-encoded DICOM is identical to what the engine emits without a transformer.
Proposed fix
Reader-side, in DICOMSerializer.fromXML's existing DOM pre-pass (the one that renames <tagXXXXXXXX> back to <attr>): when an element's <item> children contain renamed <attr> elements, set vr="SQ" before the SAX parse. That is the same content-based decision DicomInputStream makes for the binary form. toXML output is unchanged, so transformer scripts see identical XML; fragment containers (encapsulated pixel data) are untouched; every input that parses today produces an identical DicomObject; and the rewrite is a no-op if a future dcm4che emits SQ itself.
Verified byte-for-byte that the transformer round trip now produces the same DICOM as the no-transformer pass-through path, for implicit and explicit VR LE. PR to follow.
Environment
- OIE
mainat 423df18 (also reproduces on 4.6.0-based builds) - dcm4che2 2.0.29 as bundled