Add unit test for cross cube images. (#101)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
BIN
tools/cmgen/tests/Footballfield/Footballfield.png
Normal file
BIN
tools/cmgen/tests/Footballfield/Footballfield.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
13
tools/cmgen/tests/Footballfield/Footballfield.txt
Normal file
13
tools/cmgen/tests/Footballfield/Footballfield.txt
Normal 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/
|
||||
BIN
tools/cmgen/tests/Footballfield/m3_nx.rgbm
Normal file
BIN
tools/cmgen/tests/Footballfield/m3_nx.rgbm
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user