Skip to content

Commit ec16b6b

Browse files
authored
BUG: Update ITK Image Writer to Use Atomic File API (#918)
1 parent 0fd046b commit ec16b6b

File tree

1 file changed

+36
-35
lines changed

1 file changed

+36
-35
lines changed

src/Plugins/ITKImageProcessing/src/ITKImageProcessing/Filters/ITKImageWriter.cpp

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ bool Is2DFormat(const fs::path& fileName)
5050
template <typename PixelT, uint32 Dimensions>
5151
Result<> WriteAsOneFile(itk::Image<PixelT, Dimensions>& image, const fs::path& filePath /*, const IFilter::MessageHandler& messanger*/)
5252
{
53-
fs::path tempPath(fmt::format("{}/{}", fs::temp_directory_path().string(), filePath.filename().string()));
53+
AtomicFile atomicFile(filePath.string());
54+
auto tempPath = atomicFile.tempFilePath();
5455
try
5556
{
5657
using ImageType = itk::Image<PixelT, Dimensions>;
@@ -65,57 +66,57 @@ Result<> WriteAsOneFile(itk::Image<PixelT, Dimensions>& image, const fs::path& f
6566
writer->Update();
6667
} catch(const itk::ExceptionObject& err)
6768
{
68-
// Handle errors from the writer deleting the directory
69-
fs::remove(tempPath);
70-
7169
return MakeErrorResult(-21011, fmt::format("ITK exception was thrown while writing output file: {}", err.GetDescription()));
7270
}
7371

74-
fs::rename(tempPath, filePath);
72+
if(!atomicFile.commit())
73+
{
74+
return atomicFile.getResult();
75+
}
7576
return {};
7677
}
7778

7879
template <typename PixelT, uint32 Dimensions>
7980
Result<> WriteAs2DStack(itk::Image<PixelT, Dimensions>& image, uint32 z_size, const fs::path& filePath, uint64 indexOffset)
8081
{
81-
// write to temp directory
82-
auto namesGenerator = itk::NumericSeriesFileNames::New();
83-
fs::path parentPath = fs::temp_directory_path();
84-
fs::path fileName = filePath.stem();
85-
fs::path extension = filePath.extension();
86-
std::string format = fmt::format("{}/{}%03d{}", parentPath.string(), fileName.string(), extension.string());
87-
namesGenerator->SetSeriesFormat(format);
88-
namesGenerator->SetIncrementIndex(1);
89-
namesGenerator->SetStartIndex(indexOffset);
90-
namesGenerator->SetEndIndex(z_size - 1);
91-
92-
// generate all the files in that new directory
93-
try
82+
// Create list of AtomicFiles
83+
std::vector<std::unique_ptr<AtomicFile>> atomicFiles = {};
84+
85+
for(uint64 index = indexOffset; index < (z_size - 1); index++)
9486
{
95-
using InputImageType = itk::Image<PixelT, Dimensions>;
96-
using OutputImageType = itk::Image<PixelT, Dimensions - 1>;
97-
using SeriesWriterType = itk::ImageSeriesWriter<InputImageType, OutputImageType>;
98-
auto writer = SeriesWriterType::New();
99-
writer->SetInput(&image);
100-
writer->SetFileNames(namesGenerator->GetFileNames());
101-
writer->UseCompressionOn();
102-
writer->Update();
103-
} catch(const itk::ExceptionObject& err)
87+
atomicFiles.emplace_back(
88+
std::make_unique<AtomicFile>((fs::absolute(fmt::format("{}/{}{:03d}{}", filePath.parent_path().string(), filePath.stem().string(), index, filePath.extension().string())))));
89+
}
10490
{
105-
// Handle errors from the writer deleting the directory
106-
for(const auto& name : namesGenerator->GetFileNames())
91+
std::vector<std::string> fileNames = {};
92+
for(const auto& atomicFile : atomicFiles)
10793
{
108-
fs::remove(name);
94+
fileNames.emplace_back(atomicFile->tempFilePath().string());
10995
}
11096

111-
return MakeErrorResult(-21011, fmt::format("ITK exception was thrown while writing output file: {}", err.GetDescription()));
97+
// generate all the files in that new directory
98+
try
99+
{
100+
using InputImageType = itk::Image<PixelT, Dimensions>;
101+
using OutputImageType = itk::Image<PixelT, Dimensions - 1>;
102+
using SeriesWriterType = itk::ImageSeriesWriter<InputImageType, OutputImageType>;
103+
auto writer = SeriesWriterType::New();
104+
writer->SetInput(&image);
105+
writer->SetFileNames(fileNames);
106+
writer->UseCompressionOn();
107+
writer->Update();
108+
} catch(const itk::ExceptionObject& err)
109+
{
110+
return MakeErrorResult(-21011, fmt::format("ITK exception was thrown while writing output file: {}", err.GetDescription()));
111+
}
112112
}
113113

114-
// Move all the files from the new directory to the users actual directory
115-
for(const auto& name : namesGenerator->GetFileNames())
114+
for(const auto& atomicFile : atomicFiles)
116115
{
117-
fs::path tempFile(name);
118-
fs::rename(tempFile, {fmt::format("{}/{}", filePath.parent_path().string(), tempFile.filename().string())});
116+
if(!atomicFile->commit())
117+
{
118+
return atomicFile->getResult();
119+
}
119120
}
120121

121122
return {};

0 commit comments

Comments
 (0)