diff --git a/core/file/dicom/mapper.cpp b/core/file/dicom/mapper.cpp index b277425291..1418a61672 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,17 @@ 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"); + + 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..584a81afde --- /dev/null +++ b/core/image_io/null.cpp @@ -0,0 +1,34 @@ +/* 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 + * 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..bc88606426 --- /dev/null +++ b/core/image_io/null.h @@ -0,0 +1,38 @@ +/* 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 + * 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 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+" + ...