Skip to content

Commit

Permalink
Fix conversion on Stack reader and Image reader
Browse files Browse the repository at this point in the history
  • Loading branch information
nyoungbq committed Aug 2, 2024
1 parent 5e20b28 commit e39f40a
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@

using namespace nx::core;

DataType ITK::detail::ConvertChoiceToDataType(types::usize choice)
{
switch(choice)
{
case 0:
return DataType::uint8;
case 1:
return DataType::uint16;
case 2:
return DataType::uint32;
}
return DataType::uint8;
}

bool ITK::DoTuplesMatch(const IDataStore& dataStore, const ImageGeom& imageGeom)
{
return imageGeom.getNumberOfCells() == dataStore.getNumberOfTuples();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,45 @@

namespace nx::core::ITK
{
namespace detail
{
template <typename OriginT>
struct TypeConversionValidateFunctor
{
template <typename DestT>
bool operator()()
{
if constexpr(std::is_same_v<OriginT, DestT>)
{
// This won't actually fail, but it prevents an unnecessary copy
return false;
}
if constexpr(std::is_signed_v<OriginT> || std::is_signed_v<DestT>)
{
return false;
}
if constexpr(std::is_same_v<OriginT, bool> || std::is_same_v<DestT, bool>)
{
return false;
}

// Currently only works on uint8, uint16, or uint32
return true;
}
};

struct PreflightTypeConversionValidateFunctor
{
template <typename OriginT>
bool operator()(const DataType& destType)
{
return ExecuteNeighborFunction(TypeConversionValidateFunctor<OriginT>{}, destType);
}
};

DataType ConvertChoiceToDataType(usize choice);
} // namespace detail

struct ImageGeomData
{
SizeVec3 dims{};
Expand Down Expand Up @@ -344,11 +383,11 @@ DataStore<UnderlyingType_t<PixelT>> ConvertImageToDataStore(itk::Image<PixelT, D
return dataStore;
}

template<typename T>
template <typename T>
concept NotBoolT = !std::is_same_v<T, bool>;

template <NotBoolT NewStoreT, class PixelT, uint32 Dimension>
Result<> ConvertImageToDataStore(AbstractDataStore<NewStoreT>& dataStore, itk::Image<PixelT, Dimension>& image)
Result<> ConvertImageToDataStore(DataStore<NewStoreT>& dataStore, itk::Image<PixelT, Dimension>& image)
{
using ImageType = itk::Image<PixelT, Dimension>;
using T = UnderlyingType_t<PixelT>;
Expand All @@ -366,23 +405,19 @@ Result<> ConvertImageToDataStore(AbstractDataStore<NewStoreT>& dataStore, itk::I
pixelContainer->ContainerManageMemoryOff();
if constexpr(std::is_same_v<NewStoreT, T>)
{
std::unique_ptr<T[]> newData(rawBufferPtr);
dataStore = DataStore<T>(std::move(newData), std::move(tDims), std::move(cDims));
std::copy(rawBufferPtr, rawBufferPtr + pixelContainer->Size(), dataStore.data());
}
else
{
std::unique_ptr<NewStoreT[]> newData = std::make_unique<NewStoreT[]>(sizeof(NewStoreT) * pixelContainer->Size());
if constexpr(!std::is_signed_v<NewStoreT> && !std::is_signed_v<T>) // bool would slip through, but it is disallowed
{
constexpr auto destMaxV = static_cast<float64>(std::numeric_limits<NewStoreT>::max());
constexpr auto originMaxV = std::numeric_limits<T>::max();
std::transform(rawBufferPtr, rawBufferPtr + pixelContainer->Size(), newData.get(), [](auto value) {
std::transform(rawBufferPtr, rawBufferPtr + pixelContainer->Size(), dataStore.data(), [](auto value) {
float64 ratio = static_cast<float64>(value) / originMaxV;

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]

Check warning on line 417 in src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Common/ITKArrayHelper.hpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

implicit conversion from 'const unsigned long' to 'double' changes value from 18446744073709551615 to 18446744073709551616 [-Wimplicit-const-int-float-conversion]
return static_cast<NewStoreT>(ratio * destMaxV);
});
}

dataStore = DataStore<NewStoreT>(std::move(newData), std::move(tDims), std::move(cDims));
}

return {};
Expand All @@ -394,7 +429,7 @@ struct ConvertImageToDatastoreFunctor
Result<> operator()(DataStructure& dataStructure, const DataPath& arrayPath, Args&&... args)
{
auto& dataArray = dataStructure.getDataRefAs<DataArray<T>>(arrayPath);
auto& dataStore = dataArray.template getIDataStoreRefAs<DataStore<T>>();
DataStore<T>& dataStore = dataArray.template getIDataStoreRefAs<DataStore<T>>();

return ConvertImageToDataStore(dataStore, std::forward<Args>(args)...);
}
Expand Down Expand Up @@ -881,4 +916,4 @@ Result<detail::ITKFilterFunctorResult_t<FilterCreationFunctorT>> Execute(DataStr
return MakeErrorResult<ResultT>(-222, exception.GetDescription());
}
}
} // namespace nx::core
} // namespace nx::core::ITK
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Result<OutputActions> ReadImagePreflight(const std::string& fileName, DataPath i
actions.appendAction(std::make_unique<CreateImageGeometryAction>(std::move(imageGeomPath), std::move(dims), origin.toContainer<CreateImageGeometryAction::OriginType>(),
spacing.toContainer<CreateImageGeometryAction::SpacingType>(), cellDataName));

if(imageReaderOptions.ChangeDataType)
if(imageReaderOptions.ChangeDataType && ExecuteNeighborFunction(ITK::detail::PreflightTypeConversionValidateFunctor{}, *numericType, imageReaderOptions.ImageDataType))
{
actions.appendAction(
std::make_unique<CreateArrayAction>(imageReaderOptions.ImageDataType, std::move(arrayDims), std::move(cDims), imageGeomPath.createChildPath(cellDataName).createChildPath(arrayName)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#include "simplnx/Common/Result.hpp"
#include "simplnx/Common/Types.hpp"
#include "simplnx/Utilities/FilterUtilities.hpp"
#include "simplnx/Filter/Actions/CreateImageGeometryAction.hpp"
#include "simplnx/Utilities/FilterUtilities.hpp"

#include "ITKImageProcessing/Common/ITKArrayHelper.hpp"

Expand Down Expand Up @@ -58,13 +58,20 @@ struct ReadImageIntoArrayFunctor
using ImageType = itk::Image<PixelT, Dimension>;
using ReaderType = itk::ImageFileReader<ImageType>;

if(!ExecuteNeighborFunction(ITK::detail::TypeConversionValidateFunctor<typename itk::NumericTraits<PixelT>::ValueType>{}, dataType))
{
// Not valid for conversion executing overload
return operator()<PixelT, Dimension>(dataStructure, arrayPath, filePath);
}

typename ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(filePath);

reader->Update();
typename ImageType::Pointer outputImage = reader->GetOutput();

return ExecuteNeighborFunction(ITK::ConvertImageToDatastoreFunctor{}, dataType, dataStructure, arrayPath, *outputImage);;
return ExecuteNeighborFunction(ITK::ConvertImageToDatastoreFunctor{}, dataType, dataStructure, arrayPath, *outputImage);
;
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,6 @@ namespace fs = std::filesystem;

using namespace nx::core;

namespace
{
DataType ConvertChoiceToDataType(ChoicesParameter::ValueType choice)
{
switch(choice)
{
case 0:
return DataType::uint8;
case 1:
return DataType::uint16;
case 2:
return DataType::uint32;
}
return DataType::uint8;
}
} // namespace

namespace nx::core
{
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -145,7 +128,7 @@ IFilter::PreflightResult ITKImageReaderFilter::preflightImpl(const DataStructure
imageReaderOptions.Origin = FloatVec3(static_cast<float32>(origin[0]), static_cast<float32>(origin[1]), static_cast<float32>(origin[2]));
imageReaderOptions.Spacing = FloatVec3(static_cast<float32>(spacing[0]), static_cast<float32>(spacing[1]), static_cast<float32>(spacing[2]));
imageReaderOptions.ChangeDataType = pChangeDataType;
imageReaderOptions.ImageDataType = ConvertChoiceToDataType(choiceType);
imageReaderOptions.ImageDataType = ITK::detail::ConvertChoiceToDataType(choiceType);

Result<OutputActions> result = cxItkImageReaderFilter::ReadImagePreflight(fileNameString, imageGeomPath, cellDataName, imageDataArrayName, imageReaderOptions);

Expand All @@ -166,7 +149,7 @@ Result<> ITKImageReaderFilter::executeImpl(DataStructure& dataStructure, const A
auto origin = filterArgs.value<VectorFloat64Parameter::ValueType>(k_Origin_Key);
auto spacing = filterArgs.value<VectorFloat64Parameter::ValueType>(k_Spacing_Key);
auto pChangeDataType = filterArgs.value<bool>(k_ChangeDataType_Key);
auto newDataType = ConvertChoiceToDataType(filterArgs.value<ChoicesParameter::ValueType>(k_ImageDataType_Key));
auto newDataType = ITK::detail::ConvertChoiceToDataType(filterArgs.value<ChoicesParameter::ValueType>(k_ImageDataType_Key));

DataPath imageDataArrayPath = imageGeometryPath.createChildPath(cellDataName).createChildPath(imageDataArrayName);
const IDataArray* inputArrayPtr = dataStructure.getDataAs<IDataArray>(imageDataArrayPath);
Expand Down
Loading

0 comments on commit e39f40a

Please sign in to comment.