Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: fixed memory leaks in MINC IO #3548

Merged
merged 1 commit into from
Aug 15, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion Modules/IO/MINC/src/itkMINCImageIO.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,37 @@

#include "itk_minc2.h"

extern "C"
{
void
MINCIOFreeTmpDimHandle(unsigned int size, midimhandle_t * ptr)
{
int error = 0;
unsigned int x = 0;
if (!ptr)
{
/*
* Should never happen.
*/
#ifndef NDEBUG
printf("MINCIOFreeTmpDimHandle: ptr is null pointer");
#endif
return;
}
for (; x < size; ++x)
{
error = mifree_dimension_handle(ptr[x]);
#ifndef NDEBUG
if (error != MI_NOERROR)
{
printf("MINCIOFreeTmpDimHandle: mifree_dimension_handle(ptr[%u]) returned %d", x, error);
}
#else
(void)error;
#endif
}
}
}

namespace itk
{
Expand Down Expand Up @@ -955,6 +986,7 @@ MINCImageIO::WriteImageInformation()

if (nDims > 3)
{
MINCIOFreeTmpDimHandle(minc_dimensions, this->m_MINCPImpl->m_MincApparentDims);
itkExceptionMacro(<< "Unfortunately, only up to 3D volume are supported now.");
}

Expand Down Expand Up @@ -1038,6 +1070,7 @@ MINCImageIO::WriteImageInformation()
this->m_MINCPImpl->m_Volume_type = MI_TYPE_DOUBLE;
break;
default:
MINCIOFreeTmpDimHandle(minc_dimensions, this->m_MINCPImpl->m_MincApparentDims);
itkExceptionMacro(<< "Could read datatype " << this->GetComponentType());
}

Expand Down Expand Up @@ -1165,25 +1198,32 @@ MINCImageIO::WriteImageInformation()
mivolumeprops_t hprops;
if (minew_volume_props(&hprops) < 0)
{
MINCIOFreeTmpDimHandle(minc_dimensions, this->m_MINCPImpl->m_MincApparentDims);
itkExceptionMacro(<< "Could not allocate MINC properties");
}

if (this->m_UseCompression)
{
if (miset_props_compression_type(hprops, MI_COMPRESS_ZLIB) < 0)
{
MINCIOFreeTmpDimHandle(minc_dimensions, this->m_MINCPImpl->m_MincApparentDims);
mifree_volume_props(hprops);
itkExceptionMacro(<< "Could not set MINC compression");
}

if (miset_props_zlib_compression(hprops, this->GetCompressionLevel()) < 0)
{
MINCIOFreeTmpDimHandle(minc_dimensions, this->m_MINCPImpl->m_MincApparentDims);
mifree_volume_props(hprops);
itkExceptionMacro(<< "Could not set MINC compression level");
}
}
else
{
if (miset_props_compression_type(hprops, MI_COMPRESS_NONE) < 0)
{
MINCIOFreeTmpDimHandle(minc_dimensions, this->m_MINCPImpl->m_MincApparentDims);
mifree_volume_props(hprops);
itkExceptionMacro(<< "Could not set MINC compression");
}
}
Expand All @@ -1197,23 +1237,28 @@ MINCImageIO::WriteImageInformation()
&this->m_MINCPImpl->m_Volume) < 0)
{
// Error opening the volume
MINCIOFreeTmpDimHandle(minc_dimensions, this->m_MINCPImpl->m_MincApparentDims);
mifree_volume_props(hprops);
itkExceptionMacro(<< "Could not open file \"" << m_FileName.c_str() << "\".");
}

if (micreate_volume_image(this->m_MINCPImpl->m_Volume) < 0)
{
// Error opening the volume
mifree_volume_props(hprops);
itkExceptionMacro(<< "Could not create image in file \"" << m_FileName.c_str() << "\".");
}

if (miset_apparent_dimension_order(
this->m_MINCPImpl->m_Volume, minc_dimensions, this->m_MINCPImpl->m_MincApparentDims) < 0)
{
mifree_volume_props(hprops);
itkExceptionMacro(<< " Can't set apparent dimension order!");
}

if (miset_slice_scaling_flag(this->m_MINCPImpl->m_Volume, 0) < 0)
{
mifree_volume_props(hprops);
itkExceptionMacro(<< "Could not set slice scaling flag");
}

Expand Down Expand Up @@ -1396,7 +1441,17 @@ MINCImageIO::Write(const void * buffer)
delete[] count;
itkExceptionMacro(<< "Could not read datatype " << this->GetComponentType());
}
this->WriteImageInformation();

try
{
this->WriteImageInformation();
}
catch (const itk::ExceptionObject &)
{
delete[] start;
delete[] count;
throw;
}

// by default valid range will be equal to range, to avoid scaling
if (volume_data_type == this->m_MINCPImpl->m_Volume_type)
Expand Down