From 30bf591828724b94efa8057ba6537785293bce63 Mon Sep 17 00:00:00 2001 From: J-Donald Tournier Date: Mon, 4 Dec 2023 14:43:11 +0000 Subject: [PATCH 1/5] DICOM: add null imageIO handler to allow parsing of DICOM data even with unsupported transfer syntax This at least allow mrinfo to run. Any operation that attempts to access the voxel data will of course fail. --- core/file/dicom/mapper.cpp | 25 +++++++++++++++++-------- core/image_io/null.cpp | 34 ++++++++++++++++++++++++++++++++++ core/image_io/null.h | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 core/image_io/null.cpp create mode 100644 core/image_io/null.h diff --git a/core/file/dicom/mapper.cpp b/core/file/dicom/mapper.cpp index 8b31c0effe..ca37b3848f 100644 --- a/core/file/dicom/mapper.cpp +++ b/core/file/dicom/mapper.cpp @@ -18,6 +18,7 @@ #include "header.h" #include "phase_encoding.h" +#include "image_io/null.h" #include "image_io/default.h" #include "image_io/mosaic.h" #include "image_io/variable_scaling.h" @@ -68,6 +69,8 @@ namespace MR { // build up sorted list of frames: vector frames; + bool transfer_syntax_supported = true; + // loop over series list: for (const auto& series_it : series) { try { @@ -82,13 +85,9 @@ 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 ("See the MRtrix3 documentation on DICOM handling for details:"); - E.push_back (" http://mrtrix.readthedocs.io/en/latest/tips_and_tricks/dicom_handling.html#error-unsupported-transfer-syntax"); - throw E; - } + if (!image_it->transfer_syntax_supported) + transfer_syntax_supported = false; + // 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()); @@ -209,7 +208,7 @@ namespace MR { } size_t nchannels = image.samples_per_pixel; - if (nchannels == 1 && !image.frames.size()) { + if (nchannels == 1 && !image.frames.size() && transfer_syntax_supported) { // only guess number of samples per pixel if not explicitly set in // DICOM and not using multi-frame: nchannels = image.data_size / (frame.dim[0] * frame.dim[1] * (frame.bits_alloc/8)); @@ -363,6 +362,16 @@ namespace MR { } + if (!transfer_syntax_supported) { + WARN ("unsupported transfer syntax found in DICOM data"); + WARN ("consider using third-party tools to convert your data to standard uncompressed encoding"); + WARN ("See the MRtrix3 documentation on DICOM handling for details:"); + WARN (" http://mrtrix.readthedocs.io/en/latest/tips_and_tricks/dicom_handling.html#error-unsupported-transfer-syntax"); + + io_handler.reset (new MR::ImageIO::Null (H)); + return io_handler; + } + if (image.images_in_mosaic) { INFO ("DICOM image \"" + H.name() + "\" is in mosaic format"); diff --git a/core/image_io/null.cpp b/core/image_io/null.cpp new file mode 100644 index 0000000000..fee07c4dc9 --- /dev/null +++ b/core/image_io/null.cpp @@ -0,0 +1,34 @@ +/* Copyright (c) 2008-2023 the MRtrix3 contributors. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Covered Software is provided under this License on an "as is" + * basis, without warranty of any kind, either expressed, implied, or + * statutory, including, without limitation, warranties that the + * Covered Software is free of defects, merchantable, fit for a + * particular purpose or non-infringing. + * See the Mozilla Public License v. 2.0 for more details. + * + * For more details, see http://www.mrtrix.org/. + */ + +#include "image_io/null.h" +#include "header.h" + +namespace MR { + namespace ImageIO { + + void Null::load(const Header &header, size_t) { + throw Exception("No suitable handler to access data in \"" + header.name() + + "\""); + } + + void Null::unload(const Header &header) { + throw Exception("No suitable handler to access data in \"" + header.name() + + "\""); + } + + } // namespace ImageIO +} // namespace MR diff --git a/core/image_io/null.h b/core/image_io/null.h new file mode 100644 index 0000000000..885dd39ca4 --- /dev/null +++ b/core/image_io/null.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2008-2023 the MRtrix3 contributors. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Covered Software is provided under this License on an "as is" + * basis, without warranty of any kind, either expressed, implied, or + * statutory, including, without limitation, warranties that the + * Covered Software is free of defects, merchantable, fit for a + * particular purpose or non-infringing. + * See the Mozilla Public License v. 2.0 for more details. + * + * For more details, see http://www.mrtrix.org/. + */ + +#ifndef __image_io_null_h__ +#define __image_io_null_h__ + +#include "image_io/base.h" + +namespace MR { + namespace ImageIO { + + class Null : public Base { + NOMEMALIGN + public: + Null(const Header &header) : Base(header) {} + + protected: + virtual void load(const Header &, size_t); + virtual void unload(const Header &); + }; + + } // namespace ImageIO +} // namespace MR + +#endif From aef44bb83a9caf62ffa6d41237a7702ea89b2dc2 Mon Sep 17 00:00:00 2001 From: J-Donald Tournier Date: Tue, 5 Dec 2023 09:58:37 +0000 Subject: [PATCH 2/5] Fix indentation in core/file/dicom/mapper.cpp Co-authored-by: Robert Smith --- core/file/dicom/mapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/file/dicom/mapper.cpp b/core/file/dicom/mapper.cpp index ca37b3848f..4ee446738f 100644 --- a/core/file/dicom/mapper.cpp +++ b/core/file/dicom/mapper.cpp @@ -86,7 +86,7 @@ namespace MR { // loop over images in each series: for (auto image_it : *series_it) { if (!image_it->transfer_syntax_supported) - transfer_syntax_supported = false; + transfer_syntax_supported = false; // if multi-frame, loop over frames in image: if (image_it->frames.size()) { From 57c0579d63a41c660e6d35926fe33b872be16d6d Mon Sep 17 00:00:00 2001 From: Robert Smith Date: Tue, 23 Jan 2024 15:11:45 +1100 Subject: [PATCH 3/5] DICOM: Improve documentation RE unsupported transfer syntaxes --- core/file/dicom/mapper.cpp | 1 + docs/tips_and_tricks/dicom_handling.rst | 87 ++++++++++++++++--------- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/core/file/dicom/mapper.cpp b/core/file/dicom/mapper.cpp index 4ee446738f..709a01e56f 100644 --- a/core/file/dicom/mapper.cpp +++ b/core/file/dicom/mapper.cpp @@ -364,6 +364,7 @@ namespace MR { if (!transfer_syntax_supported) { WARN ("unsupported transfer syntax found in DICOM data"); + WARN ("header information is accessible, but commands requiring access to image intensity data will fail"); WARN ("consider using third-party tools to convert your data to standard uncompressed encoding"); WARN ("See the MRtrix3 documentation on DICOM handling for details:"); WARN (" http://mrtrix.readthedocs.io/en/latest/tips_and_tricks/dicom_handling.html#error-unsupported-transfer-syntax"); diff --git a/docs/tips_and_tricks/dicom_handling.rst b/docs/tips_and_tricks/dicom_handling.rst index af9ff389b5..a9c7cee3d9 100644 --- a/docs/tips_and_tricks/dicom_handling.rst +++ b/docs/tips_and_tricks/dicom_handling.rst @@ -375,44 +375,71 @@ these are: - Explicit VR Big Endian (``1.2.840.10008.1.2.2``) -Any other transfer syntax will be flagged as unsupported, and *MRtrix3* will be -unable to read the data, providing an error message similar to this: +Any other transfer syntax will be flagged as unsupported. When this occurs, +whether or not the *MRtrix3* command can proceed will depend on whether that +command requires access to the underlying image data: + +- If *only header information* is required, then the command will be able to proceed, + albeit with a warning issued: .. code-block:: console - $ mrinfo DICOM - mrinfo: [done] scanning DICOM folder "DICOM" - mrinfo: [ERROR] unable to read DICOM images in "DICOM": - mrinfo: [ERROR] unsupported transfer syntax found in DICOM data - mrinfo: [ERROR] consider using third-party tools to convert your data to standard uncompressed encoding - mrinfo: [ERROR] See the MRtrix3 documentation on DICOM handling for details: - mrinfo: [ERROR] http://mrtrix.readthedocs.io/en/latest/tips_and_tricks/dicom_handling.html#error-unsupported-transfer-syntax - mrinfo: [ERROR] error opening image "DICOM" - -Thankfully, other tools exist that should be able to convert the data to a -format that *MRtrix3* (and other DICOM tools) will read. The `dcmtk -`__ DICOM toolkit in particular provides -the ``dcmdjpeg`` command to decompress data stored using JPEG transfer syntax. -On Linux, a directory of such files can be decompressed as follows (amend the -various ``PATH`` as required for your system): + $ mrinfo DICOM/ + mrinfo: [done] scanning folder "DICOM/" for DICOM data + mrinfo: [100%] Reading DICOM series "SeriesDescription" + mrinfo: [WARNING] unable to read DICOM images in "DICOM/": + mrinfo: [WARNING] unsupported transfer syntax found in DICOM data + mrinfo: [WARNING] consider using third-party tools to convert your data to standard uncompressed encoding + mrinfo: [WARNING] See the MRtrix3 documentation on DICOM handling for details: + mrinfo: [WARNING] http://mrtrix.readthedocs.io/en/latest/tips_and_tricks/dicom_handling.html#error-unsupported-transfer-syntax + ************************************************ + Image name: "SURNAME^FIRSTNAME [MR] SeriesDescription" + ************************************************ + Dimensions: 96 x 96 x 60 x 7 + Voxel size: 2.5 x 2.5 x 2.5 x ? + Data strides: [ -1 -2 3 4 ] + .... + +- If however a command requires *access to the underlying image intensities*, + then *MRtrix3* will be unable to read from such: + .. code-block:: console + + $ mrconvert DICOM/ data.mif + mrconvert: [done] scanning folder "DICOM/" for DICOM data + mrconvert: [100%] Reading DICOM series "SeriesDescription" + mrconvert: [WARNING] unable to read DICOM images in "DICOM/": + mrconvert: [WARNING] unsupported transfer syntax found in DICOM data + mrconvert: [WARNING] consider using third-party tools to convert your data to standard uncompressed encoding + mrconvert: [WARNING] See the MRtrix3 documentation on DICOM handling for details: + mrconvert: [WARNING] http://mrtrix.readthedocs.io/en/latest/tips_and_tricks/dicom_handling.html#error-unsupported-transfer-syntax + mrconvert: [ERROR] No suitable handler to access data in "SURNAME^FIRSTNAME [MR] SeriesDescription" + + Thankfully, other tools exist that should be able to convert the data to a + format that *MRtrix3* (and other DICOM tools) will read. The `dcmtk + `__ DICOM toolkit in particular provides + the ``dcmdjpeg`` command to decompress data stored using JPEG transfer syntax. + On Linux, a directory of such files can be decompressed as follows (amend the + various ``PATH`` as required for your system): + + .. code-block:: console - $ export PATH=/opt/dcmtk/bin:$PATH - $ export DCMDICTPATH=/opt/dcmtk/share/dcmtk/dicom.dic + $ export PATH=/opt/dcmtk/bin:$PATH + $ export DCMDICTPATH=/opt/dcmtk/share/dcmtk/dicom.dic - $ for img in dcmdir/* - > do - > dcmdjpeg $img ${img}.tmp - > mv ${img}.tmp $img - > done + $ for img in dcmdir/* + > do + > dcmdjpeg $img ${img}.tmp + > mv ${img}.tmp $img + > done -*MRtrix3* commands should now be able to read the directory successfully: + *MRtrix3* commands should now be able to read the directory successfully: -.. code-block:: console + .. code-block:: console - $ mrinfo dcmdir - mrinfo: [done] scanning DICOM folder "data/driss/t1" - mrinfo: [100%] reading DICOM series "AX FSPGR 3D ASSET C+" - ... + $ mrinfo dcmdir + mrinfo: [done] scanning DICOM folder "data/driss/t1" + mrinfo: [100%] reading DICOM series "AX FSPGR 3D ASSET C+" + ... From 1e71049044d9e3c0c38c7d15f86e0d42c3793642 Mon Sep 17 00:00:00 2001 From: MRtrixBot Date: Tue, 23 Jan 2024 15:16:41 +1100 Subject: [PATCH 4/5] Update copyright to 2024 for new files in #2767 --- core/image_io/null.cpp | 2 +- core/image_io/null.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/image_io/null.cpp b/core/image_io/null.cpp index fee07c4dc9..584a81afde 100644 --- a/core/image_io/null.cpp +++ b/core/image_io/null.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2023 the MRtrix3 contributors. +/* Copyright (c) 2008-2024 the MRtrix3 contributors. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/core/image_io/null.h b/core/image_io/null.h index 885dd39ca4..bc88606426 100644 --- a/core/image_io/null.h +++ b/core/image_io/null.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2023 the MRtrix3 contributors. +/* Copyright (c) 2008-2024 the MRtrix3 contributors. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this From 6b9957ae588e03c88c329e9062d2f9772cb7261a Mon Sep 17 00:00:00 2001 From: MRtrixBot Date: Mon, 10 Feb 2025 10:28:39 +1100 Subject: [PATCH 5/5] Copyright update for #2767 --- core/image_io/null.cpp | 2 +- core/image_io/null.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/image_io/null.cpp b/core/image_io/null.cpp index 584a81afde..6be05a05f2 100644 --- a/core/image_io/null.cpp +++ b/core/image_io/null.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2024 the MRtrix3 contributors. +/* Copyright (c) 2008-2025 the MRtrix3 contributors. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/core/image_io/null.h b/core/image_io/null.h index bc88606426..3c163c3b67 100644 --- a/core/image_io/null.h +++ b/core/image_io/null.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2024 the MRtrix3 contributors. +/* Copyright (c) 2008-2025 the MRtrix3 contributors. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this