mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 10:35:42 +00:00
HDF5 unit tests
Move HDF5ImageWriter/Reader to its own unit test. Use user supplied field name as HDF5 dataset name.
This commit is contained in:
parent
03cb5cb43c
commit
fac489644f
@ -23,22 +23,31 @@ void ImageReaderHDF5::Read()
|
|||||||
// need to find width, height and pixel type.
|
// need to find width, height and pixel type.
|
||||||
auto fileid = H5Fopen(this->FileName.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
|
auto fileid = H5Fopen(this->FileName.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
|
||||||
|
|
||||||
if (!H5IMis_image(fileid, "image"))
|
const auto fieldName = this->PointFieldName.c_str();
|
||||||
|
if (!H5IMis_image(fileid, fieldName))
|
||||||
throw vtkm::io::ErrorIO{ "Not an HDF5 image file" };
|
throw vtkm::io::ErrorIO{ "Not an HDF5 image file" };
|
||||||
|
|
||||||
hsize_t width, height, nplanes;
|
hsize_t width, height, nplanes;
|
||||||
hssize_t npals;
|
hssize_t npals;
|
||||||
char interlace[16];
|
char interlace[16];
|
||||||
if (H5IMget_image_info(fileid, "image", &width, &height, &nplanes, interlace, &npals) < 0)
|
if (H5IMget_image_info(fileid, fieldName, &width, &height, &nplanes, interlace, &npals) < 0)
|
||||||
throw vtkm::io ::ErrorIO{ "Can not get image info" };
|
throw vtkm::io ::ErrorIO{ "Can not get image info" };
|
||||||
|
|
||||||
// We don't use the H5IMread_image() since it only supports 8 bit pixel.
|
// We don't use the H5IMread_image() since it only supports 8 bit pixel.
|
||||||
hid_t did;
|
hid_t did;
|
||||||
if ((did = H5Dopen2(fileid, "image", H5P_DEFAULT)) < 0)
|
if ((did = H5Dopen2(fileid, fieldName, H5P_DEFAULT)) < 0)
|
||||||
throw vtkm::io::ErrorIO{ "Can not open image dataset" };
|
throw vtkm::io::ErrorIO{ "Can not open image dataset" };
|
||||||
|
|
||||||
if (strncmp(interlace, "INTERLACE_PIXEL", 15) != 0)
|
if (strncmp(interlace, "INTERLACE_PIXEL", 15) != 0)
|
||||||
throw vtkm::io::ErrorIO{ "Unsupported interlace mode" };
|
{
|
||||||
|
std::string message = "Unsupported interlace mode: ";
|
||||||
|
message += interlace;
|
||||||
|
message +=
|
||||||
|
". Currently, only the INTERLACE_PIXEL mode is supported. See "
|
||||||
|
"https://portal.hdfgroup.org/display/HDF5/HDF5+Image+and+Palette+Specification%2C+Version+1.2"
|
||||||
|
" for more details on the HDF5 image convention.";
|
||||||
|
throw vtkm::io::ErrorIO{ message };
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<unsigned char> buffer;
|
std::vector<unsigned char> buffer;
|
||||||
auto type_size = H5LDget_dset_type_size(did, nullptr);
|
auto type_size = H5LDget_dset_type_size(did, nullptr);
|
||||||
|
@ -29,11 +29,6 @@ ImageWriterBase::ImageWriterBase(const std::string& filename)
|
|||||||
|
|
||||||
ImageWriterBase::~ImageWriterBase() noexcept {}
|
ImageWriterBase::~ImageWriterBase() noexcept {}
|
||||||
|
|
||||||
void ImageWriterBase::WriteDataSet(const vtkm::cont::DataSet& dataSet)
|
|
||||||
{
|
|
||||||
this->WriteDataSet(dataSet, std::string{});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageWriterBase::WriteDataSet(const vtkm::cont::DataSet& dataSet,
|
void ImageWriterBase::WriteDataSet(const vtkm::cont::DataSet& dataSet,
|
||||||
const std::string& colorFieldName)
|
const std::string& colorFieldName)
|
||||||
{
|
{
|
||||||
|
@ -52,8 +52,8 @@ public:
|
|||||||
/// `ArrayHandle` of `vtkm::Vec4f_32`). If no color field name is given,
|
/// `ArrayHandle` of `vtkm::Vec4f_32`). If no color field name is given,
|
||||||
/// the first point field that matches this criteria is written.
|
/// the first point field that matches this criteria is written.
|
||||||
///
|
///
|
||||||
VTKM_CONT void WriteDataSet(const vtkm::cont::DataSet& dataSet);
|
VTKM_CONT void WriteDataSet(const vtkm::cont::DataSet& dataSet,
|
||||||
VTKM_CONT void WriteDataSet(const vtkm::cont::DataSet& dataSet, const std::string& colorField);
|
const std::string& colorField = {});
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
enum class PixelDepth
|
enum class PixelDepth
|
||||||
|
@ -35,6 +35,13 @@ namespace io
|
|||||||
{
|
{
|
||||||
ImageWriterHDF5::~ImageWriterHDF5() noexcept = default;
|
ImageWriterHDF5::~ImageWriterHDF5() noexcept = default;
|
||||||
|
|
||||||
|
void ImageWriterHDF5::WriteDataSet(const vtkm::cont::DataSet& dataSet,
|
||||||
|
const std::string& colorField)
|
||||||
|
{
|
||||||
|
this->fieldName = colorField;
|
||||||
|
Superclass::WriteDataSet(dataSet, colorField);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename PixelType>
|
template <typename PixelType>
|
||||||
herr_t ImageWriterHDF5::WriteToFile(vtkm::Id width, vtkm::Id height, const ColorArrayType& pixels)
|
herr_t ImageWriterHDF5::WriteToFile(vtkm::Id width, vtkm::Id height, const ColorArrayType& pixels)
|
||||||
{
|
{
|
||||||
@ -56,7 +63,7 @@ herr_t ImageWriterHDF5::WriteToFile(vtkm::Id width, vtkm::Id height, const Color
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Shamelessly copied from H5IMmake_image_24bit() implementation.
|
// Shamelessly copied from H5IMmake_image_24bit() implementation.
|
||||||
auto dset_name = "image";
|
auto dset_name = this->fieldName.c_str();
|
||||||
|
|
||||||
// The image is stored as height*width*3 array of UCHAR/UINT16, i.e. INTERLACE_PIXEL
|
// The image is stored as height*width*3 array of UCHAR/UINT16, i.e. INTERLACE_PIXEL
|
||||||
hsize_t dims[] = { hsize_t(height), hsize_t(width), 3 };
|
hsize_t dims[] = { hsize_t(height), hsize_t(width), 3 };
|
||||||
|
@ -35,6 +35,9 @@ public:
|
|||||||
ImageWriterHDF5(const ImageWriterHDF5&) = delete;
|
ImageWriterHDF5(const ImageWriterHDF5&) = delete;
|
||||||
ImageWriterHDF5& operator=(const ImageWriterHDF5&) = delete;
|
ImageWriterHDF5& operator=(const ImageWriterHDF5&) = delete;
|
||||||
|
|
||||||
|
VTKM_CONT void WriteDataSet(const vtkm::cont::DataSet& dataSet,
|
||||||
|
const std::string& colorField = {});
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VTKM_CONT void Write(vtkm::Id width, vtkm::Id height, const ColorArrayType& pixels) override;
|
VTKM_CONT void Write(vtkm::Id width, vtkm::Id height, const ColorArrayType& pixels) override;
|
||||||
|
|
||||||
@ -43,6 +46,8 @@ private:
|
|||||||
VTKM_CONT herr_t WriteToFile(vtkm::Id width, vtkm::Id height, const ColorArrayType& pixels);
|
VTKM_CONT herr_t WriteToFile(vtkm::Id width, vtkm::Id height, const ColorArrayType& pixels);
|
||||||
|
|
||||||
hid_t fileid = 0;
|
hid_t fileid = 0;
|
||||||
|
// FIXME: a hack for the moment, design a better API.
|
||||||
|
std::string fieldName;
|
||||||
|
|
||||||
static constexpr auto IMAGE_CLASS = "IMAGE";
|
static constexpr auto IMAGE_CLASS = "IMAGE";
|
||||||
static constexpr auto IMAGE_VERSION = "1.2";
|
static constexpr auto IMAGE_VERSION = "1.2";
|
||||||
|
@ -23,6 +23,11 @@ if(VTKm_ENABLE_RENDERING)
|
|||||||
UnitTestImageWriter.cxx
|
UnitTestImageWriter.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (VTKm_ENABLE_HDF5_IO)
|
||||||
|
set(unit_tests ${unit_tests}
|
||||||
|
UnitTestHDF5Image.cxx)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(unit_test_libraries ${unit_test_libraries} vtkm_rendering)
|
set(unit_test_libraries ${unit_test_libraries} vtkm_rendering)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
109
vtkm/io/testing/UnitTestHDF5Image.cxx
Normal file
109
vtkm/io/testing/UnitTestHDF5Image.cxx
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
//============================================================================
|
||||||
|
// Copyright (c) Kitware, Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
// See LICENSE.txt for details.
|
||||||
|
//
|
||||||
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
#include <vtkm/io/ImageReaderHDF5.h>
|
||||||
|
#include <vtkm/io/ImageWriterHDF5.h>
|
||||||
|
#include <vtkm/rendering/Canvas.h>
|
||||||
|
#include <vtkm/rendering/Color.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
using namespace vtkm::io;
|
||||||
|
using namespace vtkm::rendering;
|
||||||
|
|
||||||
|
void TestFilledImage(vtkm::cont::DataSet& dataSet,
|
||||||
|
const std::string& fieldName,
|
||||||
|
const vtkm::rendering::Canvas& canvas)
|
||||||
|
{
|
||||||
|
VTKM_TEST_ASSERT(dataSet.HasPointField(fieldName), "Point Field Not Found: " + fieldName);
|
||||||
|
|
||||||
|
auto pointField = dataSet.GetPointField(fieldName);
|
||||||
|
VTKM_TEST_ASSERT(pointField.GetNumberOfValues() == canvas.GetWidth() * canvas.GetHeight(),
|
||||||
|
"wrong image dimensions");
|
||||||
|
VTKM_TEST_ASSERT(pointField.GetData().template IsType<vtkm::cont::ArrayHandle<vtkm::Vec4f_32>>(),
|
||||||
|
"wrong ArrayHandle type");
|
||||||
|
auto pixelPortal =
|
||||||
|
pointField.GetData().template Cast<vtkm::cont::ArrayHandle<vtkm::Vec4f_32>>().ReadPortal();
|
||||||
|
|
||||||
|
auto colorPortal = canvas.GetColorBuffer().ReadPortal();
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(test_equal_portals(pixelPortal, colorPortal));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCreateImageDataSet(const vtkm::rendering::Canvas& canvas)
|
||||||
|
{
|
||||||
|
std::cout << "TestCreateImageDataSet" << std::endl;
|
||||||
|
auto dataSet = canvas.GetDataSet("pixel-color");
|
||||||
|
TestFilledImage(dataSet, "pixel-color", canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestReadAndWriteHDF5(const vtkm::rendering::Canvas& canvas,
|
||||||
|
std::string filename,
|
||||||
|
vtkm::io::ImageWriterBase::PixelDepth pixelDepth)
|
||||||
|
{
|
||||||
|
std::cout << "TestReadAndWriteHDF5 - " << filename << std::endl;
|
||||||
|
bool throws = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vtkm::io::ImageWriterHDF5 writer(filename);
|
||||||
|
vtkm::cont::DataSet dataSet;
|
||||||
|
writer.WriteDataSet(dataSet, "color");
|
||||||
|
}
|
||||||
|
catch (const vtkm::cont::Error&)
|
||||||
|
{
|
||||||
|
throws = true;
|
||||||
|
}
|
||||||
|
VTKM_TEST_ASSERT(throws, "Fill Image did not throw with empty data");
|
||||||
|
|
||||||
|
{
|
||||||
|
vtkm::io::ImageWriterHDF5 writer(filename);
|
||||||
|
writer.SetPixelDepth(pixelDepth);
|
||||||
|
writer.WriteDataSet(canvas.GetDataSet(), "color");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vtkm::io::ImageReaderHDF5 reader(filename);
|
||||||
|
vtkm::cont::DataSet dataSet = reader.ReadDataSet();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vtkm::io::ImageWriterHDF5 writer(filename);
|
||||||
|
writer.SetPixelDepth(pixelDepth);
|
||||||
|
writer.WriteDataSet(canvas.GetDataSet(), "color");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vtkm::io::ImageReaderHDF5 reader(filename);
|
||||||
|
vtkm::cont::DataSet dataSet = reader.ReadDataSet();
|
||||||
|
TestFilledImage(dataSet, reader.GetPointFieldName(), canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestHDF5Image()
|
||||||
|
{
|
||||||
|
vtkm::rendering::Canvas canvas(16, 16);
|
||||||
|
canvas.SetBackgroundColor(vtkm::rendering::Color::red);
|
||||||
|
canvas.Clear();
|
||||||
|
// Line from top left to bottom right, ensures correct transposedness
|
||||||
|
canvas.AddLine(-0.9, 0.9, 0.9, -0.9, 2.0f, vtkm::rendering::Color::black);
|
||||||
|
vtkm::Bounds colorBarBounds(-0.8, -0.6, -0.8, 0.8, 0, 0);
|
||||||
|
canvas.AddColorBar(colorBarBounds, vtkm::cont::ColorTable("inferno"), false);
|
||||||
|
canvas.BlendBackground();
|
||||||
|
|
||||||
|
TestReadAndWriteHDF5(canvas, "hdf5RGB8Test.h5", vtkm::io::ImageWriterBase::PixelDepth::PIXEL_8);
|
||||||
|
TestReadAndWriteHDF5(canvas, "hdf5RGB16Test.h5", vtkm::io::ImageWriterBase::PixelDepth::PIXEL_16);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int UnitTestHDF5Image(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::Testing::Run(TestHDF5Image, argc, argv);
|
||||||
|
}
|
@ -11,7 +11,6 @@
|
|||||||
#include <vtkm/cont/testing/Testing.h>
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
#include <vtkm/io/ImageReaderPNG.h>
|
#include <vtkm/io/ImageReaderPNG.h>
|
||||||
#include <vtkm/io/ImageReaderPNM.h>
|
#include <vtkm/io/ImageReaderPNM.h>
|
||||||
#include <vtkm/io/ImageWriterHDF5.h>
|
|
||||||
#include <vtkm/io/ImageWriterPNG.h>
|
#include <vtkm/io/ImageWriterPNG.h>
|
||||||
#include <vtkm/io/ImageWriterPNM.h>
|
#include <vtkm/io/ImageWriterPNM.h>
|
||||||
#include <vtkm/io/PixelTypes.h>
|
#include <vtkm/io/PixelTypes.h>
|
||||||
@ -19,7 +18,6 @@
|
|||||||
#include <vtkm/rendering/Color.h>
|
#include <vtkm/rendering/Color.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vtkm/io/ImageReaderHDF5.h>
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -131,45 +129,6 @@ void TestReadAndWritePNM(const vtkm::rendering::Canvas& canvas,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestReadAndWriteHDF5(const vtkm::rendering::Canvas& canvas,
|
|
||||||
std::string filename,
|
|
||||||
vtkm::io::ImageWriterBase::PixelDepth pixelDepth)
|
|
||||||
{
|
|
||||||
std::cout << "TestReadAndWriteHDF5 - " << filename << std::endl;
|
|
||||||
bool throws = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
vtkm::io::ImageWriterHDF5 writer(filename);
|
|
||||||
vtkm::cont::DataSet dataSet;
|
|
||||||
writer.WriteDataSet(dataSet);
|
|
||||||
}
|
|
||||||
catch (const vtkm::cont::Error&)
|
|
||||||
{
|
|
||||||
throws = true;
|
|
||||||
}
|
|
||||||
VTKM_TEST_ASSERT(throws, "Fill Image did not throw with empty data");
|
|
||||||
|
|
||||||
{
|
|
||||||
vtkm::io::ImageWriterHDF5 writer(filename);
|
|
||||||
writer.SetPixelDepth(pixelDepth);
|
|
||||||
writer.WriteDataSet(canvas.GetDataSet());
|
|
||||||
}
|
|
||||||
{
|
|
||||||
vtkm::io::ImageReaderHDF5 reader(filename);
|
|
||||||
vtkm::cont::DataSet dataSet = reader.ReadDataSet();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
vtkm::io::ImageWriterHDF5 writer(filename);
|
|
||||||
writer.SetPixelDepth(pixelDepth);
|
|
||||||
writer.WriteDataSet(canvas.GetDataSet());
|
|
||||||
}
|
|
||||||
{
|
|
||||||
vtkm::io::ImageReaderHDF5 reader(filename);
|
|
||||||
vtkm::cont::DataSet dataSet = reader.ReadDataSet();
|
|
||||||
TestFilledImage(dataSet, reader.GetPointFieldName(), canvas);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestBaseImageMethods(const vtkm::rendering::Canvas& canvas)
|
void TestBaseImageMethods(const vtkm::rendering::Canvas& canvas)
|
||||||
{
|
{
|
||||||
TestCreateImageDataSet(canvas);
|
TestCreateImageDataSet(canvas);
|
||||||
@ -187,12 +146,6 @@ void TestPNGImage(const vtkm::rendering::Canvas& canvas)
|
|||||||
TestReadAndWritePNG(canvas, "pngRGB16Test.png", vtkm::io::ImageWriterBase::PixelDepth::PIXEL_16);
|
TestReadAndWritePNG(canvas, "pngRGB16Test.png", vtkm::io::ImageWriterBase::PixelDepth::PIXEL_16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestHDF5Image(const vtkm::rendering::Canvas& canvas)
|
|
||||||
{
|
|
||||||
TestReadAndWriteHDF5(canvas, "hdf5RGB8Test.h5", vtkm::io::ImageWriterBase::PixelDepth::PIXEL_8);
|
|
||||||
TestReadAndWriteHDF5(canvas, "hdf5RGB16Test.h5", vtkm::io::ImageWriterBase::PixelDepth::PIXEL_16);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestImage()
|
void TestImage()
|
||||||
{
|
{
|
||||||
vtkm::rendering::Canvas canvas(16, 16);
|
vtkm::rendering::Canvas canvas(16, 16);
|
||||||
@ -208,7 +161,6 @@ void TestImage()
|
|||||||
TestBaseImageMethods(canvas);
|
TestBaseImageMethods(canvas);
|
||||||
TestPNMImage(canvas);
|
TestPNMImage(canvas);
|
||||||
TestPNGImage(canvas);
|
TestPNGImage(canvas);
|
||||||
TestHDF5Image(canvas);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user