diff --git a/Modules/DataTypesExt/include/mitkCompressedImageContainer.h b/Modules/DataTypesExt/include/mitkCompressedImageContainer.h index 7c19a73086..0e9fd71c6c 100644 --- a/Modules/DataTypesExt/include/mitkCompressedImageContainer.h +++ b/Modules/DataTypesExt/include/mitkCompressedImageContainer.h @@ -1,51 +1,52 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkCompressedImageContainer_h #define mitkCompressedImageContainer_h #include #include #include #include #include namespace mitk { class MITKDATATYPESEXT_EXPORT CompressedImageContainer { public: CompressedImageContainer(); ~CompressedImageContainer(); CompressedImageContainer(const CompressedImageContainer&) = delete; CompressedImageContainer& operator=(const CompressedImageContainer&) = delete; void CompressImage(const Image* image); Image::Pointer DecompressImage() const; private: using CompressedSliceData = std::pair; using CompressedTimeStepData = std::vector; using CompressedImageData = std::vector; void ClearCompressedImageData(); CompressedImageData m_CompressedImageData; std::unique_ptr m_PixelType; TimeGeometry::Pointer m_TimeGeometry; std::array m_SliceDimensions; + unsigned int m_Dimension; }; } #endif diff --git a/Modules/DataTypesExt/src/mitkCompressedImageContainer.cpp b/Modules/DataTypesExt/src/mitkCompressedImageContainer.cpp index a2c1ee8e38..22c4c00fdc 100644 --- a/Modules/DataTypesExt/src/mitkCompressedImageContainer.cpp +++ b/Modules/DataTypesExt/src/mitkCompressedImageContainer.cpp @@ -1,133 +1,136 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include #include #include #include #include mitk::CompressedImageContainer::CompressedImageContainer() + : m_Dimension(0) { } mitk::CompressedImageContainer::~CompressedImageContainer() { this->ClearCompressedImageData(); } void mitk::CompressedImageContainer::ClearCompressedImageData() { for (const auto& image : m_CompressedImageData) { for (auto slice : image) delete[] slice.second; } m_CompressedImageData.clear(); m_PixelType = nullptr; m_TimeGeometry = nullptr; m_SliceDimensions[0] = 0; m_SliceDimensions[1] = 0; + m_Dimension = 0; } void mitk::CompressedImageContainer::CompressImage(const Image* image) { this->ClearCompressedImageData(); if (nullptr == image) return; m_PixelType = std::make_unique(image->GetPixelType()); m_TimeGeometry = image->GetTimeGeometry()->Clone(); m_SliceDimensions[0] = image->GetDimension(0); m_SliceDimensions[1] = image->GetDimension(1); + m_Dimension = image->GetDimension(); const auto numTimeSteps = m_TimeGeometry->CountTimeSteps(); const auto numSlices = image->GetDimension(2); const auto numSliceBytes = image->GetPixelType().GetSize() * image->GetDimension(0) * image->GetDimension(1); m_CompressedImageData.reserve(numTimeSteps); for (std::remove_const_t t = 0; t < numTimeSteps; ++t) { CompressedTimeStepData slices; slices.reserve(numSlices); ImageReadAccessor accessor(image, image->GetVolumeData(t)); for (std::remove_const_t s = 0; s < numSlices; ++s) { const auto* src = reinterpret_cast(accessor.GetData()) + numSliceBytes * s; char* dest = new char[numSliceBytes]; const auto destSize = LZ4_compress_default(src, dest, static_cast(numSliceBytes), static_cast(numSliceBytes)); if (0 == destSize) { MITK_ERROR << "LZ4 compression failed!"; delete[] dest; slices.emplace_back(0, nullptr); } else { char* shrinkedDest = new char[destSize]; std::copy(dest, dest + destSize, shrinkedDest); delete[] dest; slices.emplace_back(destSize, shrinkedDest); } } m_CompressedImageData.push_back(slices); } } mitk::Image::Pointer mitk::CompressedImageContainer::DecompressImage() const { if (m_CompressedImageData.empty()) return nullptr; const auto numSlices = static_cast(m_CompressedImageData[0].size()); const auto numTimeSteps = static_cast(m_CompressedImageData.size()); const auto numSliceBytes = m_PixelType->GetSize() * m_SliceDimensions[0] * m_SliceDimensions[1]; std::array dimensions; dimensions[0] = m_SliceDimensions[0]; dimensions[1] = m_SliceDimensions[1]; dimensions[2] = numSlices; dimensions[3] = numTimeSteps; auto image = Image::New(); - image->Initialize(*m_PixelType, numTimeSteps > 1 ? 4 : 3, dimensions.data()); + image->Initialize(*m_PixelType, m_Dimension, dimensions.data()); for (std::remove_const_t t = 0; t < numTimeSteps; ++t) { ImageWriteAccessor accessor(image, image->GetVolumeData(static_cast(t))); for (std::remove_const_t s = 0; s < numSlices; ++s) { auto* dest = reinterpret_cast(accessor.GetData()) + numSliceBytes * s; const auto& slice = m_CompressedImageData[t][s]; const auto destSize = LZ4_decompress_safe(slice.second, dest, slice.first, static_cast(numSliceBytes)); if (0 > destSize) MITK_ERROR << "LZ4 decompression failed!"; } } image->SetTimeGeometry(m_TimeGeometry->Clone()); return image; }