Skip to content

Commit edf5418

Browse files
authored
Merge pull request #4168 from melissalinkert/gh-4165
DICOM reader: better handling of nested sequences that include pixel data
2 parents 6fa35f6 + daaa2f9 commit edf5418

2 files changed

Lines changed: 44 additions & 4 deletions

File tree

components/formats-bsd/src/loci/formats/dicom/DicomTag.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,15 +310,33 @@ else if (elementLength <= 44) {
310310
break;
311311
}
312312
else if (child.attribute == PIXEL_DATA) {
313-
stop = fp;
314-
break;
313+
child.parent = this;
314+
children.add(child);
315+
if (child.elementLength == -1) {
316+
// look for end of sequence
317+
long seek = fp - 2;
318+
int nextTag = 0;
319+
while (seek < in.length() && (nextTag != SEQUENCE_DELIMITATION_ITEM.getTag() && nextTag != ITEM_DELIMITATION_ITEM.getTag())) {
320+
seek += 2;
321+
in.seek(seek);
322+
try {
323+
nextTag = getNextTag(in);
324+
}
325+
catch (Exception e) {
326+
}
327+
if (nextTag == 0xfeffdde0 || nextTag == 0xfeff0d0e) {
328+
in.order(!in.isLittleEndian());
329+
break;
330+
}
331+
}
332+
}
315333
}
316334
else if (child.attribute != ITEM && child.attribute != ITEM_DELIMITATION_ITEM) {
317335
child.parent = this;
318336
children.add(child);
319337
}
320338
}
321-
if (elementLength == 0) {
339+
if (elementLength <= 0) {
322340
elementLength = (int) (stop - start);
323341
}
324342
in.seek(stop);
@@ -438,6 +456,7 @@ private int getLength(RandomAccessInputStream in) throws IOException {
438456

439457
switch (vr) {
440458
case OB:
459+
case OV:
441460
case OW:
442461
case SQ:
443462
case UN:
@@ -700,6 +719,17 @@ else if (!(value instanceof long[])) {
700719
}
701720
}
702721

722+
/**
723+
* See https://dicom.nema.org/dicom/2013/output/chtml/part05/sect_7.8.html
724+
*
725+
* @return true if this is a private content creator tag
726+
*/
727+
public boolean isPrivateContentCreator() {
728+
int highWord = (tag >> 16) & 0xffff;
729+
int lowWord = tag & 0xffff;
730+
return highWord % 2 == 1 && lowWord == 0x0010;
731+
}
732+
703733
@Override
704734
public String toString() {
705735
if (key == null) {

components/formats-bsd/src/loci/formats/in/DicomReader.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737
import java.util.ArrayList;
3838
import java.util.Arrays;
3939
import java.util.HashMap;
40+
import java.util.HashSet;
4041
import java.util.Iterator;
4142
import java.util.List;
4243
import java.util.Map;
44+
import java.util.Set;
4345

4446
import com.google.common.collect.ImmutableMap;
4547
import com.google.common.collect.ImmutableMap.Builder;
@@ -127,6 +129,8 @@ public class DicomReader extends SubResolutionFormatReader {
127129

128130
private List<DicomTag> tags;
129131

132+
private Set<Integer> privateContentHighWords = new HashSet<Integer>();
133+
130134
// -- Constructor --
131135

132136
/** Constructs a new DICOM reader. */
@@ -368,6 +372,7 @@ public void close(boolean fileOnly) throws IOException {
368372
concatenationNumber = null;
369373
edf = false;
370374
tags = null;
375+
privateContentHighWords.clear();
371376
}
372377
}
373378

@@ -1168,6 +1173,10 @@ else if (infoString.startsWith("MONOCHROME")) {
11681173
* rely upon the original metadata table.
11691174
*/
11701175
private void addOriginalMetadata(String key, DicomTag info) {
1176+
if (info.isPrivateContentCreator()) {
1177+
privateContentHighWords.add(info.tag >> 16);
1178+
}
1179+
11711180
if (info.value != null && !(info.value instanceof byte[]) &&
11721181
!(info.value instanceof short[]))
11731182
{
@@ -1179,7 +1188,8 @@ private void addOriginalMetadata(String key, DicomTag info) {
11791188
}
11801189
}
11811190
if (info.attribute != PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE &&
1182-
info.attribute != REFERENCED_IMAGE_NAVIGATION_SEQUENCE)
1191+
info.attribute != REFERENCED_IMAGE_NAVIGATION_SEQUENCE &&
1192+
!privateContentHighWords.contains(info.tag >> 16))
11831193
{
11841194
for (DicomTag child : info.children) {
11851195
String childKey = DicomAttribute.formatTag(child.tag);

0 commit comments

Comments
 (0)