| 98 | } |
| 99 | |
| 100 | mitk::Image::Pointer mitk::CompressedImageContainer::DecompressImage() const |
| 101 | { |
| 102 | if (m_CompressedImageData.empty()) |
| 103 | return nullptr; |
| 104 | |
| 105 | const auto numSlices = static_cast<unsigned int>(m_CompressedImageData[0].size()); |
| 106 | const auto numTimeSteps = static_cast<unsigned int>(m_CompressedImageData.size()); |
| 107 | const auto numSliceBytes = m_PixelType->GetSize() * m_SliceDimensions[0] * m_SliceDimensions[1]; |
| 108 | |
| 109 | std::array<unsigned int, 4> dimensions; |
| 110 | dimensions[0] = m_SliceDimensions[0]; |
| 111 | dimensions[1] = m_SliceDimensions[1]; |
| 112 | dimensions[2] = numSlices; |
| 113 | dimensions[3] = numTimeSteps; |
| 114 | |
| 115 | auto image = Image::New(); |
| 116 | image->Initialize(*m_PixelType, m_Dimension, dimensions.data()); |
| 117 | |
| 118 | for (std::remove_const_t<decltype(numTimeSteps)> t = 0; t < numTimeSteps; ++t) |
| 119 | { |
| 120 | ImageWriteAccessor accessor(image, image->GetVolumeData(static_cast<int>(t))); |
| 121 | |
| 122 | for (std::remove_const_t<decltype(numSlices)> s = 0; s < numSlices; ++s) |
| 123 | { |
| 124 | auto* dest = reinterpret_cast<char*>(accessor.GetData()) + numSliceBytes * s; |
| 125 | const auto& slice = m_CompressedImageData[t][s]; |
| 126 | const auto destSize = LZ4_decompress_safe(slice.second, dest, slice.first, static_cast<int>(numSliceBytes)); |
| 127 | |
| 128 | if (0 > destSize) |
| 129 | MITK_ERROR << "LZ4 decompression failed!"; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | image->SetTimeGeometry(m_TimeGeometry->Clone()); |
| 134 | |
| 135 | return image; |
| 136 | } |