/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include #include "IO/Files/Pfm.hpp" #include #include #include #include #include #include using namespace OpenVulkano; namespace { bool almostEqual(float a, float b, float epsilon = 0.001f) { return std::fabs(a - b) < epsilon; } } TEST_CASE("Invalid input", "[Pfm]") { std::stringstream ss("Invalid\n1024 768\n1.0\n"); PfmHeader header; REQUIRE_THROWS_AS(ss >> header, std::runtime_error); } TEST_CASE("Extreme maxValue handling", "[Pfm]") { PfmHeader largeMaxValueHeader(1024, 768, 1000000.0f, true); std::stringstream ss; ss << largeMaxValueHeader; REQUIRE(ss.str() == "PF\n1024 768\n-1000000.0\n"); std::stringstream inputSS("PF\n1024 768\n-1000000.0\n"); PfmHeader parsedHeader; inputSS >> parsedHeader; REQUIRE(parsedHeader.maxValue == 1000000.0f); REQUIRE(parsedHeader.littleEndian == true); } TEST_CASE("Negative maxValue indicating endian", "[Pfm]") { std::stringstream ss("PF\n640 480\n-1.0\n"); PfmHeader header; ss >> header; REQUIRE(header.color == true); REQUIRE(header.width == 640); REQUIRE(header.height == 480); REQUIRE(header.maxValue == 1.0f); REQUIRE(header.littleEndian == true); } TEST_CASE("Operator<< output precision", "[Pfm]") { PfmHeader header(640, 480, 1.234567f, true); std::stringstream ss; ss << header; REQUIRE(ss.str() == "PF\n640 480\n-1.2\n"); } TEST_CASE("Zero width or height", "[Pfm]") { PfmHeader zeroWidth(0, 768, 1.0f, true); PfmHeader zeroHeight(1024, 0, 1.0f, false); REQUIRE(zeroWidth.GetElementCount() == 0); REQUIRE(zeroHeight.GetElementCount() == 0); REQUIRE(zeroWidth.GetImageSize() == 0); REQUIRE(zeroHeight.GetImageSize() == 0); } TEST_CASE("Large width and height", "[Pfm]") { PfmHeader largeHeader(10000, 8000, 1.0f, true); REQUIRE(largeHeader.GetElementCount() == 10000 * 8000 * 3); REQUIRE(largeHeader.GetImageSize() == 10000 * 8000 * 3 * sizeof(float)); } TEST_CASE("Comparing headers", "[Pfm]") { PfmHeader header1(640, 480, 1.0f, true); PfmHeader header2(640, 480, 1.0f, true); PfmHeader header3(640, 480, 1.0f, false); PfmHeader header4(1024, 768, 1.0f, true); REQUIRE(header1.width == header2.width); REQUIRE(header1.height == header2.height); REQUIRE(header1.color == header2.color); REQUIRE(header1.color != header3.color); REQUIRE(header1.width != header4.width); REQUIRE(header1.height != header4.height); } TEST_CASE("Read with incorrect header", "[Pfm]") { std::stringstream ss("Invalid\n800 600\n-1.0\n"); REQUIRE_THROWS_AS(PfmImage::ReadImage(ss), std::runtime_error); } TEST_CASE("Endian little-endian", "[Pfm]") { std::stringstream ss; ss << "Pf\n2 2\n-1.0\n"; std::vector imageData = { 0.1f, 0.2f, 0.3f, 0.4f }; ss.write(reinterpret_cast(imageData.data()), imageData.size() * sizeof(float)); PfmImage image = PfmImage::ReadImage(ss); REQUIRE(image.header.width == 2); REQUIRE(image.header.height == 2); REQUIRE(image.header.color == false); REQUIRE(image.header.maxValue == 1.0f); for (size_t i = 0; i < imageData.size(); ++i) { REQUIRE(almostEqual(image.image[i],imageData[i])); } } TEST_CASE("Read with exact data match", "[Pfm]") { std::stringstream ss; ss << "Pf\n2 2\n-1.0\n"; std::vector imageData = { 0.1f, 0.2f, 0.3f, 0.4f }; ss.write(reinterpret_cast(imageData.data()), imageData.size() * sizeof(float)); PfmImage image = PfmImage::ReadImage(ss); REQUIRE(image.header.width == 2); REQUIRE(image.header.height == 2); REQUIRE(image.header.color == false); REQUIRE(image.header.maxValue == 1.0f); for (size_t i = 0; i < imageData.size(); ++i) { REQUIRE(almostEqual(image.image[i], imageData[i])); } } TEST_CASE("ReadImage with big-endian data", "[Pfm]") { std::stringstream ss; ss << "Pf\n2 2\n1.0\n"; std::vector imageData = { 0.1f, 0.2f, 0.3f, 0.4f }; { std::vector imageDataBigEndian = imageData; char* data = reinterpret_cast(imageDataBigEndian.data()); for (size_t i = 0; i < imageDataBigEndian.size(); i++) { size_t idx = i * sizeof(float); std::reverse(&data[idx], &data[idx + sizeof(float)]); } ss.write(reinterpret_cast(imageDataBigEndian.data()), imageDataBigEndian.size() * sizeof(float)); } PfmImage image = PfmImage::ReadImage(ss); for (size_t i = 0; i < imageData.size(); ++i) { REQUIRE(almostEqual(image.image[i], imageData[i])); } }