Add unit test for cross cube images. (#101)

This commit is contained in:
Philip Rideout
2018-08-15 15:36:17 -07:00
committed by GitHub
parent 7547cd9ee5
commit 6d9668ccf6
8 changed files with 88 additions and 22 deletions

View File

@@ -4,4 +4,4 @@ libs/math/test_math
libs/image/test_image compare libs/image/tests/reference/
libs/utils/test_utils
tools/matc/test_matc
tools/cmgen/test_cmgen compare
tools/cmgen/test_cmgen compare

View File

@@ -320,7 +320,6 @@ static LinearImage toLinearWithAlpha(size_t w, size_t h, size_t bpr,
return result;
}
// Constructs a 4-channel LinearImage from an untyped data blob.
// The "proc" lambda converts a single color component into a float.
// the "transform" lambda performs an arbitrary float-to-float transformation.
@@ -330,6 +329,18 @@ static LinearImage toLinearWithAlpha(size_t w, size_t h, size_t bpr,
return toLinearWithAlpha<T>(w, h, bpr, src.get(), proc, transform);
}
// Constructs a 3-channel LinearImage from RGBM data.
inline LinearImage toLinearFromRGBM(math::float4 const* src, uint32_t w, uint32_t h) {
LinearImage result(w, h, 3);
math::float3* dst = reinterpret_cast<math::float3*>(result.getPixelRef());
for (uint32_t row = 0; row < h; ++row) {
for (uint32_t col = 0; col < w; ++col, ++src, ++dst) {
*dst = RGBMtoLinear(*src);
}
}
return result;
}
}
#endif // IMAGE_COLORTRANSFORM_H_

View File

@@ -16,6 +16,7 @@
#include <imageio/ImageDiffer.h>
#include <image/ColorTransform.h>
#include <image/ImageOps.h>
#include <imageio/ImageDecoder.h>
#include <imageio/ImageEncoder.h>
@@ -35,12 +36,17 @@ void updateOrCompare(LinearImage limgResult, const utils::Path& fnameGolden,
// Regenerate the PNG file at the given path.
if (mode == ComparisonMode::UPDATE) {
std::ofstream out(fnameGolden, std::ios::binary | std::ios::trunc);
auto format = ImageEncoder::Format::PNG_LINEAR;
const size_t width = limgResult.getWidth();
const size_t height = limgResult.getHeight();
const size_t nchan = limgResult.getChannels();
const size_t bpp = nchan * sizeof(float), bpr = width * bpp, nbytes = bpr * height;
std::unique_ptr<uint8_t[]> data(new uint8_t[nbytes]);
auto format = ImageEncoder::Format::PNG_LINEAR;
if (fnameGolden.getExtension() == "rgbm" && nchan == 3) {
format = ImageEncoder::Format::RGBM;
}
if (nchan != 1) {
memcpy(data.get(), limgResult.getPixelRef(), nbytes);
Image im(std::move(data), width, height, bpr, bpp, nchan);
@@ -60,8 +66,18 @@ void updateOrCompare(LinearImage limgResult, const utils::Path& fnameGolden,
Image imgGolden = ImageDecoder::decode(in, fnameGolden, ImageDecoder::ColorSpace::LINEAR);
const size_t width = imgGolden.getWidth(), height = imgGolden.getHeight();
const size_t nchan = imgGolden.getChannelsCount();
LinearImage limgGolden(width, height, nchan);
memcpy(limgGolden.getPixelRef(), imgGolden.getData(), width * height * sizeof(float) * nchan);
// Convert 4-channel RGBM into proper RGB.
LinearImage limgGolden;
if (fnameGolden.getExtension() == "rgbm" && nchan == 4) {
limgGolden = toLinearFromRGBM(
static_cast<math::float4 const*>(imgGolden.getData()),
imgGolden.getWidth(), imgGolden.getHeight());
} else {
limgGolden = LinearImage(width, height, nchan);
memcpy(limgGolden.getPixelRef(), imgGolden.getData(),
width * height * sizeof(float) * nchan);
}
// Expand the result image from L to RGB.
if (limgResult.getChannels() == 1) {

View File

@@ -100,7 +100,7 @@ bool IBL::loadCubemapLevel(filament::Texture** texture, const utils::Path& path,
}
stbi_info(facePath.getAbsolutePath().c_str(), &w, &h, nullptr);
if (w != h) {
std::cerr << "with != height" << std::endl;
std::cerr << "width != height" << std::endl;
return false;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

View File

@@ -0,0 +1,13 @@
Author
======
This is the work of Emil Persson, aka Humus.
http://www.humus.name
License
=======
This work is licensed under a Creative Commons Attribution 3.0 Unported License.
http://creativecommons.org/licenses/by/3.0/

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -43,30 +43,56 @@ class CmgenTest : public testing::Test {};
static ComparisonMode g_comparisonMode;
TEST_F(CmgenTest, WhiteFurnace) { // NOLINT
static void checkFileExistence(string path) {
std::ifstream s(path.c_str(), std::ios::binary);
if (!s) {
std::cerr << "ERROR file does not exist: " << path << std::endl;
exit(1);
}
}
Path comparisonPath = "../../samples/envs/white_furnace";
Path inputPath = "../../assets/environments/white_furnace/white_furnace.exr";
// This spawns cmgen, telling it to process the environment map located at "inputPath". It creates
// an output folder in the same location as the test executable, which lets us avoid polluting our
// local source tree with output files. The given "resultPath" points the specific newly-generated
// output image that we'd like to compare or update, and the "goldenPath" points to the golden image
// (which lives in our source tree).
static void spawnTool(string inputPath, string resultPath, string goldenPath) {
const string executableFolder = Path::getCurrentExecutable().getParent();
inputPath = Path::getCurrentDirectory() + inputPath;
resultPath = Path::getCurrentExecutable().getParent() + resultPath;
goldenPath = Path::getCurrentDirectory() + goldenPath;
const string resultImageFilename = "white_furnace/nx.rgbm";
const string goldenImageFilename = comparisonPath + "nx.rgbm";
std::cerr << "Running cmgen on " << inputPath << "...\n";
string cmdline = string("tools/cmgen/cmgen -x . ") + inputPath.c_str();
std::cout << "Running cmgen on " << inputPath << std::endl;
checkFileExistence(inputPath);
string cmdline = executableFolder + "cmgen -x " + executableFolder + " " + inputPath;
ASSERT_EQ(std::system(cmdline.c_str()), 0);
std::cerr << "Reading result image from " << resultImageFilename << "...\n";
std::ifstream resultStream(resultImageFilename.c_str(), std::ios::binary);
Image resultImage = ImageDecoder::decode(resultStream, resultImageFilename);
std::cout << "Reading result image from " << resultPath << std::endl;
checkFileExistence(resultPath);
std::ifstream resultStream(resultPath.c_str(), std::ios::binary);
Image resultImage = ImageDecoder::decode(resultStream, resultPath);
ASSERT_EQ(resultImage.isValid(), true);
ASSERT_EQ(resultImage.getChannelsCount(), 4);
LinearImage resultLImage = toLinearFromRGBM(
static_cast<math::float4 const*>(resultImage.getData()),
resultImage.getWidth(), resultImage.getHeight());
std::cerr << "Golden image is at " << goldenImageFilename << "\n";
LinearImage resultLImage(resultImage.getWidth(), resultImage.getHeight(), 4);
memcpy(resultLImage.getPixelRef(), resultImage.getData(),
resultImage.getWidth() * resultImage.getHeight() * sizeof(float) * 4);
std::cout << "Golden image is at " << goldenPath << std::endl;
updateOrCompare(resultLImage, goldenPath, g_comparisonMode, 0.01f);
}
updateOrCompare(resultLImage, goldenImageFilename, g_comparisonMode, 0.01f);
TEST_F(CmgenTest, HdrLatLong) { // NOLINT
const string inputPath = "assets/environments/white_furnace/white_furnace.exr";
const string resultPath = "white_furnace/nx.rgbm";
const string goldenPath = "samples/envs/white_furnace/nx.rgbm";
spawnTool(inputPath, resultPath, goldenPath);
}
TEST_F(CmgenTest, LdrCrossCube) { // NOLINT
const string inputPath = "tools/cmgen/tests/Footballfield/Footballfield.png";
const string resultPath = "Footballfield/m3_nx.rgbm";
const string goldenPath = "tools/cmgen/tests/Footballfield/m3_nx.rgbm";
spawnTool(inputPath, resultPath, goldenPath);
}
int main(int argc, char** argv) {