Skip to content
Merged
Show file tree
Hide file tree
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
17 changes: 17 additions & 0 deletions Modules/Core/Common/include/itkMetaProgrammingLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,23 @@ struct Not : NotC<TF::Value>
using Type = typename NotC<TF::Value>::Type;
};

/** MPL type trait to check if type is a SmartPointer.
*/
template <typename T>
struct IsSmartPointer : FalseType
{};


/// \cond SPECIALIZATION_IMPLEMENTATION
Comment thread
dzenanz marked this conversation as resolved.
template <typename T>
struct IsSmartPointer<SmartPointer<T>> : TrueType
{};

template <typename T>
struct IsSmartPointer<const SmartPointer<T>> : TrueType
{};
/// \endcond

/** MPL relational type trait to check if a static_cast conversion
* exists.
*
Expand Down
1 change: 1 addition & 0 deletions Modules/IO/ImageBase/ITKKWStyleOverwrite.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
itkConvertPixelBuffer\.hxx Namespace Disable
test/itkWriteImageFunctionGTest.cxx Namespace Disable
63 changes: 15 additions & 48 deletions Modules/IO/ImageBase/include/itkImageFileWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "itkProcessObject.h"
#include "itkImageIOBase.h"
#include "itkMacro.h"
#include "itkMetaProgrammingLibrary.h"

namespace itk
{
Expand Down Expand Up @@ -237,61 +238,27 @@ class ITK_TEMPLATE_EXPORT ImageFileWriter : public ProcessObject
};


/** Convenience function for writing an image. */
template <typename TImage>
/** Convenience function for writing an image.
*
* The image parameter may be a either SmartPointer or a raw pointer and const or non-const.
* */
template <typename TImagePointer>
ITK_TEMPLATE_EXPORT void
WriteImage(const TImage * image, const char * filename, bool compress = false)
WriteImage(TImagePointer && image, const std::string & filename, bool compress = false)
{
using WriterType = ImageFileWriter<TImage>;
typename WriterType::Pointer writer = WriterType::New();
using NonReferenceImagePointer = typename std::remove_reference<TImagePointer>::type;
static_assert(std::is_pointer<NonReferenceImagePointer>::value ||
mpl::IsSmartPointer<NonReferenceImagePointer>::Value,
"WriteImage requires a raw pointer or SmartPointer.");

using ImageType = typename std::remove_const<typename std::remove_reference<decltype(*image)>::type>::type;
auto writer = ImageFileWriter<ImageType>::New();
writer->SetInput(image);
writer->SetFileName(filename);
writer->SetUseCompression(compress);
writer->Update();
}
template <typename TImage>
ITK_TEMPLATE_EXPORT void
WriteImage(const SmartPointer<const TImage> image, const char * filename, bool compress = false)
{
WriteImage(image.GetPointer(), filename, compress);
}
template <typename TImage>
ITK_TEMPLATE_EXPORT void
WriteImage(TImage * image, const char * filename, bool compress = false)
{
const TImage * constImage = image;
WriteImage(constImage, filename, compress);
}
template <typename TImage>
ITK_TEMPLATE_EXPORT void
WriteImage(SmartPointer<TImage> image, const char * filename, bool compress = false)
{
WriteImage(image.GetPointer(), filename, compress);
}
template <typename TImage>
ITK_TEMPLATE_EXPORT void
WriteImage(const TImage * image, const std::string & filename, bool compress = false)
{
WriteImage(image, filename.c_str(), compress);
}
template <typename TImage>
ITK_TEMPLATE_EXPORT void
WriteImage(const SmartPointer<const TImage> image, const std::string & filename, bool compress = false)
{
WriteImage(image, filename.c_str(), compress);
}
template <typename TImage>
ITK_TEMPLATE_EXPORT void
WriteImage(TImage * image, const std::string & filename, bool compress = false)
{
WriteImage(image, filename.c_str(), compress);
}
template <typename TImage>
ITK_TEMPLATE_EXPORT void
WriteImage(SmartPointer<TImage> image, const std::string & filename, bool compress = false)
{
WriteImage(image, filename.c_str(), compress);
}

} // end namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
Expand Down
8 changes: 8 additions & 0 deletions Modules/IO/ImageBase/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -355,3 +355,11 @@ itk_add_test(NAME itkVectorImageReadWriteTest2
add_executable(itkUnicodeIOTest itkUnicodeIOTest.cxx)
itk_module_target_label(itkUnicodeIOTest)
itk_add_test(NAME itkUnicodeIOTest COMMAND itkUnicodeIOTest)


set(ITKIOImageBaseGTests
itkWriteImageFunctionGTest.cxx
)
CreateGoogleTestDriver(ITKIOImageBase "${ITKIOImageBase-Test_LIBRARIES}" "${ITKIOImageBaseGTests}")

target_compile_definitions(ITKIOImageBaseGTestDriver PRIVATE "-DITK_TEST_OUTPUT_DIR=${ITK_TEST_OUTPUT_DIR}")
77 changes: 77 additions & 0 deletions Modules/IO/ImageBase/test/itkWriteImageFunctionGTest.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#include "itkImageFileWriter.h"
#include "itkImage.h"

#include "itkGTest.h"
#include "itksys/SystemTools.hxx"
#include "itkTestDriverIncludeRequiredIOFactories.h"

#define STRING(s) #s

namespace
{

struct ITKWriteImageFunctionTest : public ::testing::Test
{
void
SetUp() override
{
RegisterRequiredFactories();
itksys::SystemTools::ChangeDirectory(STRING(ITK_TEST_OUTPUT_DIR_STR));
}
using ImageType = itk::Image<float, 2>;

ImageType::Pointer
MakeImage()
{
auto image = ImageType::New();

ImageType::RegionType region({ 3, 2 });

image->SetRegions(region);

image->Allocate(true);
return image;
}
};


} // namespace

TEST_F(ITKWriteImageFunctionTest, ImageTypes)
{
ImageType::Pointer image_ptr = MakeImage();
itk::WriteImage(image_ptr, "test1.mha");
itk::WriteImage(std::move(image_ptr), "test1.mha");

ImageType::ConstPointer image_cptr = MakeImage();
itk::WriteImage(image_cptr, "test1.mha");
itk::WriteImage(std::move(image_cptr), "test1.mha");

const ImageType::ConstPointer image_ccptr = MakeImage();
itk::WriteImage(image_ccptr, "test1.mha");
itk::WriteImage(std::move(image_ccptr), "test1.mha");

image_ptr = MakeImage();
Comment thread
dzenanz marked this conversation as resolved.
ImageType * image_rptr = image_ptr.GetPointer();
itk::WriteImage(image_rptr, "test1.mha");

const ImageType * image_crptr = image_ptr.GetPointer();
itk::WriteImage(image_crptr, "test1.mha");
}