Skip to content

Commit

Permalink
ENH: Added saving metadata in NRRD file in more data types
Browse files Browse the repository at this point in the history
     Added test for that
  • Loading branch information
vfonov authored and hjmjohnson committed Mar 8, 2023
1 parent d91d2b1 commit 94368f8
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
Expand Up @@ -19,6 +19,7 @@
#define itkQuadEdgeMeshLineCell_h

#include "itkAutoPointer.h"
#include "itkMesh.h"
#include "itkGeometricalQuadEdge.h"

namespace itk
Expand Down
33 changes: 30 additions & 3 deletions Modules/IO/NRRD/src/itkNrrdImageIO.cxx
Expand Up @@ -23,6 +23,8 @@
#include "itkIOCommon.h"
#include "itkFloatingPointExceptions.h"

#include <sstream>

namespace itk
{
#define KEY_PREFIX "NRRD_"
Expand Down Expand Up @@ -868,6 +870,21 @@ NrrdImageIO::WriteImageInformation()
// Nothing needs doing here.
}


// helper function
template <typename T>
bool
_dump_metadata_to_stream(MetaDataDictionary & thisDic, const std::string & key, std::ostringstream & buffer)
{
T value;
if (ExposeMetaData<T>(thisDic, key, value))
{
buffer << value;
return true;
}
return false;
}

void
NrrdImageIO::Write(const void * buffer)
{
Expand Down Expand Up @@ -1065,9 +1082,19 @@ NrrdImageIO::Write(const void * buffer)
else
{
// not a NRRD field packed into meta data; just a regular key/value
std::string value;
ExposeMetaData<std::string>(thisDic, *keyIt, value);
nrrdKeyValueAdd(nrrd, keyIt->c_str(), value.c_str());
// convert to string and dump to the file
// const char *tname = thisDic.Get(*keyIt)->GetNameOfClass();
std::ostringstream dump;
if (_dump_metadata_to_stream<std::string>(thisDic, *keyIt, dump) ||
_dump_metadata_to_stream<double>(thisDic, *keyIt, dump) ||
_dump_metadata_to_stream<float>(thisDic, *keyIt, dump) ||
_dump_metadata_to_stream<int>(thisDic, *keyIt, dump) ||
_dump_metadata_to_stream<unsigned int>(thisDic, *keyIt, dump) ||
_dump_metadata_to_stream<Array<float>>(thisDic, *keyIt, dump) ||
_dump_metadata_to_stream<Array<double>>(thisDic, *keyIt, dump) ||
_dump_metadata_to_stream<Array<int>>(thisDic, *keyIt, dump) ||
_dump_metadata_to_stream<Array<unsigned int>>(thisDic, *keyIt, dump))
nrrdKeyValueAdd(nrrd, keyIt->c_str(), dump.str().c_str());
}
}

Expand Down
51 changes: 51 additions & 0 deletions Modules/IO/NRRD/test/itkNrrdImageIOTest.h
Expand Up @@ -19,6 +19,7 @@
#define itkNrrdImageIOTest_h

#include <fstream>
#include <string>
#include "itkImageRegionIterator.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
Expand Down Expand Up @@ -99,6 +100,20 @@ itkNrrdImageIOTestReadWriteTest(std::string fn, unsigned int size, std::string i
{
// Generate a random image.
image = itkNrrdImageIOTestGenerateRandomImage<TPixelType, VImageDimension>(size);

// add custom metadata
itk::MetaDataDictionary dictionary;

itk::EncapsulateMetaData(dictionary, "ASimpleString", std::string("a string"));
itk::EncapsulateMetaData(dictionary, "ASimpleFloat", 1.2f);
itk::EncapsulateMetaData(dictionary, "ASimpleDouble", 2.3);
itk::EncapsulateMetaData(dictionary, "ASimpleInt", 3);

itk::EncapsulateMetaData(dictionary, "Array<int>", itk::Array<int>(3, 1));
itk::EncapsulateMetaData(dictionary, "Array<float>", itk::Array<float>(4, 2.2f));
itk::EncapsulateMetaData(dictionary, "Array<double>", itk::Array<double>(5, 3.3));

image->SetMetaDataDictionary(dictionary);
}

// Write, then read the image.
Expand Down Expand Up @@ -153,6 +168,42 @@ itkNrrdImageIOTestReadWriteTest(std::string fn, unsigned int size, std::string i
return EXIT_FAILURE;
}
}
if (inputFile == "null")
{
// check incorporated metadata
itk::MetaDataDictionary dictionary = reader->GetOutput()->GetMetaDataDictionary();

auto check_metadata_entry = [](auto & dict, auto & key, auto & expected) {
std::string val;
if (!itk::ExposeMetaData<std::string>(dict, key, val))
{
std::cerr << "Missing expected metadata entry:" << key << std::endl;
return false;
}
if (val != expected)
{
std::cerr << "Wrong metadata for " << key << ", expected:" << expected << " got:" << val.c_str() << std::endl;
return false;
}
return true;
};

if (!check_metadata_entry(dictionary, "ASimpleString", "a string"))
return EXIT_FAILURE;
if (!check_metadata_entry(dictionary, "ASimpleFloat", "1.2"))
return EXIT_FAILURE;
if (!check_metadata_entry(dictionary, "ASimpleDouble", "2.3"))
return EXIT_FAILURE;
if (!check_metadata_entry(dictionary, "ASimpleInt", "3"))
return EXIT_FAILURE;
if (!check_metadata_entry(dictionary, "Array<int>", "[1, 1, 1]"))
return EXIT_FAILURE;
if (!check_metadata_entry(dictionary, "Array<float>", "[2.2, 2.2, 2.2, 2.2]"))
return EXIT_FAILURE;
if (!check_metadata_entry(dictionary, "Array<double>", "[3.3, 3.3, 3.3, 3.3, 3.3]"))
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

Expand Down

0 comments on commit 94368f8

Please sign in to comment.