Skip to content

Commit

Permalink
DICOM: better handling of unsupported transfer syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
jdtournier committed May 19, 2017
1 parent 2e6a505 commit 7920b43
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 28 deletions.
34 changes: 17 additions & 17 deletions core/file/dicom/element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,13 @@ namespace MR {
namespace File {
namespace Dicom {

const char* Element::error_message = nullptr;

void Element::set (const std::string& filename, bool force_read, bool read_write)
{
group = element = VR = 0;
size = 0;
start = data = next = NULL;
is_BE = is_transfer_syntax_BE = false;
transfer_syntax_supported = true;
parents.clear();

fmap.reset (new File::MMap (filename, read_write));
Expand Down Expand Up @@ -158,35 +157,39 @@ namespace MR {
size = Raw::fetch_<uint32_t> (start+4, is_BE);
}


next = data;

if (size == LENGTH_UNDEFINED) {
if (VR != VR_SQ && !(group == GROUP_SEQUENCE && element == ELEMENT_SEQUENCE_ITEM)) {
if (VR != VR_SQ && !(group == GROUP_SEQUENCE && element == ELEMENT_SEQUENCE_ITEM))
INFO ("undefined length used for DICOM tag " + ( tag_name().size() ? tag_name().substr (2) : "" )
+ MR::printf ("(%04X, %04X) in file \"", group, element) + fmap->name() + "\"");
size = 0;
}
}
else if (next+size > fmap->address() + fmap->size())
throw Exception ("file \"" + fmap->name() + "\" is too small to contain DICOM elements specified");
else {
if (size%2)
DEBUG ("WARNING: odd length (" + str (size) + ") used for DICOM tag " + ( tag_name().size() ? tag_name().substr (2) : "" )
+ " (" + str (group) + ", " + str (element) + ") in file \"" + fmap->name() + "");
if (VR != VR_SQ && ( group != GROUP_SEQUENCE || element != ELEMENT_SEQUENCE_ITEM ) )
next += size;
if (VR != VR_SQ) {
if (group == GROUP_SEQUENCE && element == ELEMENT_SEQUENCE_ITEM) {
if (parents.size() && parents.back().group == GROUP_DATA && parents.back().element == ELEMENT_DATA)
next += size;
}
else
next += size;
}
}



if (parents.size())
if (parents.size())
if ((parents.back().end && data > parents.back().end) ||
(group == GROUP_SEQUENCE && element == ELEMENT_SEQUENCE_DELIMITATION_ITEM))
(group == GROUP_SEQUENCE && element == ELEMENT_SEQUENCE_DELIMITATION_ITEM))
parents.pop_back();

if (VR == VR_SQ) {
if (is_new_sequence()) {
if (size == LENGTH_UNDEFINED)
parents.push_back (Sequence (group, element, NULL));
parents.push_back (Sequence (group, element, nullptr));
else
parents.push_back (Sequence (group, element, data + size));
}
Expand Down Expand Up @@ -214,10 +217,7 @@ namespace MR {
throw Exception ("DICOM deflated explicit VR little endian transfer syntax not supported");
}
else {
error_message =
"unsupported transfer syntax found in DICOM data\n"
"consider using third-party tools to convert your data to standard uncompressed encoding\n"
"e.g. dcmtk: http://dicom.offis.de/dcmtk.php.en";
transfer_syntax_supported = false;
INFO ("unsupported DICOM transfer syntax: \"" + std::string (reinterpret_cast<const char*> (data), size)
+ "\" in file \"" + fmap->name() + "\"");
}
Expand Down Expand Up @@ -376,7 +376,7 @@ namespace MR {
size_t indent = item.level() - ( item.VR == VR_SQ ? 1 : 0 );
for (size_t i = 0; i < indent; i++)
tmp += " ";
if (item.VR == VR_SQ)
if (item.is_new_sequence())
tmp += "> ";
else if (item.group == GROUP_SEQUENCE && item.element == ELEMENT_SEQUENCE_ITEM)
tmp += "- ";
Expand Down
6 changes: 4 additions & 2 deletions core/file/dicom/element.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ namespace MR {
uint32_t size;
uint8_t* data;
vector<Sequence> parents;
bool transfer_syntax_supported;

void set (const std::string& filename, bool force_read = false, bool read_write = false);
bool read ();
Expand Down Expand Up @@ -89,6 +90,9 @@ namespace MR {
bool is_big_endian () const {
return is_BE;
}
bool is_new_sequence () const {
return VR == VR_SQ || ( group == GROUP_DATA && element == ELEMENT_DATA && size == LENGTH_UNDEFINED );
}

Type type () const;
vector<int32_t> get_int () const;
Expand All @@ -104,7 +108,6 @@ namespace MR {
"----- ---- ---- -- ------- ------- ------------------------------------- ---------------------------------------\n";
}

static const char* get_error () { return error_message; }

protected:

Expand All @@ -118,7 +121,6 @@ namespace MR {

vector<uint8_t*> end_seq;

static const char* error_message;

uint16_t get_VR_from_tag_name (const std::string& name) {
union {
Expand Down
3 changes: 2 additions & 1 deletion core/file/dicom/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ namespace MR {
bvalue = G[0] = G[1] = G[2] = NAN;
data = bits_alloc = data_size = frame_offset = 0;
DW_scheme_wrt_image = false;
transfer_syntax_supported = true;
pe_axis = 3;
pe_sign = 0;
pixel_bandwidth = bandwidth_per_pixel_phase_encode = echo_time = NAN;
Expand All @@ -53,7 +54,7 @@ namespace MR {
default_type distance, pixel_size[2], slice_thickness, slice_spacing, scale_slope, scale_intercept, bvalue;
size_t data, bits_alloc, data_size, frame_offset;
std::string filename;
bool DW_scheme_wrt_image;
bool DW_scheme_wrt_image, transfer_syntax_supported;
size_t pe_axis;
int pe_sign;
default_type pixel_bandwidth, bandwidth_per_pixel_phase_encode, echo_time;
Expand Down
6 changes: 6 additions & 0 deletions core/file/dicom/mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ namespace MR {

// loop over images in each series:
for (auto image_it : *series_it) {
if (!image_it->transfer_syntax_supported) {
Exception E ("unsupported transfer syntax found in DICOM data");
E.push_back ("consider using third-party tools to convert your data to standard uncompressed encoding");
E.push_back ("e.g. dcmtk: http://dicom.offis.de/dcmtk.php.en");
throw E;
}
// if multi-frame, loop over frames in image:
if (image_it->frames.size()) {
std::sort (image_it->frames.begin(), image_it->frames.end(), compare_ptr_contents());
Expand Down
3 changes: 3 additions & 0 deletions core/file/dicom/quick_scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace MR {
series_time.clear();
sequence.clear();
series_number = bits_alloc = dim[0] = dim[1] = data = 0;
transfer_syntax_supported = true;

Element item;
try {
Expand Down Expand Up @@ -82,6 +83,8 @@ namespace MR {
}
}

transfer_syntax_supported = item.transfer_syntax_supported;

}
catch (Exception& E) {
E.display (3);
Expand Down
1 change: 1 addition & 0 deletions core/file/dicom/quick_scan.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace MR {
std::string study, study_ID, study_date, study_time;
std::string series, series_date, series_time, sequence;
size_t series_number, bits_alloc, dim[2], data;
bool transfer_syntax_supported;
};

std::ostream& operator<< (std::ostream& stream, const QuickScan& file);
Expand Down
9 changes: 1 addition & 8 deletions core/file/dicom/tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ namespace MR {
image->filename = filename;
image->series = series.get();
image->sequence_name = reader.sequence;
image->transfer_syntax_supported = reader.transfer_syntax_supported;
series->push_back (image);
}

Expand All @@ -125,14 +126,6 @@ namespace MR {
if (size() > 0)
return;

auto error_msg = Element::get_error();
if (error_msg) {
auto lines = split_lines (error_msg);
Exception E ("unable to read DICOM images in \"" + filename + "\":");
for (const auto& line: lines)
E.push_back (" " + line);
throw E;
}
throw Exception ("no DICOM images found in \"" + filename + "\"");
}

Expand Down

0 comments on commit 7920b43

Please sign in to comment.