/* * 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/Pnm.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("Default constructor initializes with expected values", "[Pnm]") { PnmHeader header; REQUIRE(header.width == 0); REQUIRE(header.height == 0); REQUIRE(header.maxValue == 0); REQUIRE(header.color == PnmHeader::ColorMode::GRAY); REQUIRE(header.ascii == false); } TEST_CASE("Constructor initializes with correct values", "[Pnm]") { PnmHeader header; header = PnmHeader(100, 200, true); REQUIRE(header.width == 100); REQUIRE(header.height == 200); REQUIRE(header.maxValue == 255); REQUIRE(header.color == PnmHeader::ColorMode::COLOR); REQUIRE(header.ascii == false); header = PnmHeader(100, 200, PnmHeader::ColorMode::BW, 127, true); REQUIRE(header.width == 100); REQUIRE(header.height == 200); REQUIRE(header.maxValue == 127); REQUIRE(header.color == PnmHeader::ColorMode::BW); REQUIRE(header.ascii == true); } TEST_CASE("GetFileType returns correct file type", "[Pnm]") { PnmHeader header; header = PnmHeader(100, 200, PnmHeader::ColorMode::BW); REQUIRE(header.GetFileType() == "PBM"); header = PnmHeader(100, 200, PnmHeader::ColorMode::GRAY); REQUIRE(header.GetFileType() == "PGM"); header = PnmHeader(100, 200, PnmHeader::ColorMode::COLOR); REQUIRE(header.GetFileType() == "PPM"); } TEST_CASE("GetFileExtension returns correct file extension", "[Pnm]") { PnmHeader header; header = PnmHeader(100, 200, PnmHeader::ColorMode::BW); REQUIRE(header.GetFileExtension() == ".pbm"); header = PnmHeader(100, 200, PnmHeader::ColorMode::GRAY); REQUIRE(header.GetFileExtension() == ".pgm"); header = PnmHeader(100, 200, PnmHeader::ColorMode::COLOR); REQUIRE(header.GetFileExtension() == ".ppm"); } TEST_CASE("GetMagicNumberValue and GetMagicNumberChar return correct values", "[Pnm]") { PnmHeader header; header = PnmHeader(100, 200, PnmHeader::ColorMode::BW, 255, true); REQUIRE(header.GetMagicNumberValue() == 1); REQUIRE(header.GetMagicNumberChar() == '1'); header = PnmHeader(100, 200, PnmHeader::ColorMode::COLOR, 255, false); REQUIRE(header.GetMagicNumberValue() == 6); REQUIRE(header.GetMagicNumberChar() == '6'); } TEST_CASE("GetImageSize returns correct size", "[Pnm]") { PnmHeader header; header = PnmHeader(8, 8, PnmHeader::ColorMode::BW); REQUIRE(header.GetImageSize() == 8); header = PnmHeader(100, 100, PnmHeader::ColorMode::GRAY); REQUIRE(header.GetImageSize() == 10000); header = PnmHeader(50, 50, PnmHeader::ColorMode::COLOR); REQUIRE(header.GetImageSize() == 7500); header = PnmHeader(50, 50, PnmHeader::ColorMode::COLOR, 65535); REQUIRE(header.GetImageSize() == 15000); } TEST_CASE("Ostream operator<< outputs correct header", "[Pnm]") { PnmHeader header(100, 200, PnmHeader::ColorMode::COLOR, 255, false); std::stringstream ss; ss << header; std::string expectedOutput = "P6\n100 200\n255\n"; REQUIRE(ss.str() == expectedOutput); } TEST_CASE("Istream operator>> reads correctly formatted PNM header", "[Pnm]") { std::string pnmData = "P6\n100 200\n255\n"; std::stringstream ss(pnmData); PnmHeader header; ss >> header; REQUIRE(header.width == 100); REQUIRE(header.height == 200); REQUIRE(header.maxValue == 255); REQUIRE(header.color == PnmHeader::ColorMode::COLOR); REQUIRE(header.ascii == false); } TEST_CASE("Istream operator>> throws on malformed header", "[Pnm]") { { std::string malformedData = "X6\n100 200\n255\n"; std::stringstream ss(malformedData); PnmHeader header; REQUIRE_THROWS_AS(ss >> header, std::runtime_error); } { std::string malformedData = "P9\n100 200\n255\n"; std::stringstream ss(malformedData); PnmHeader header; REQUIRE_THROWS_AS(ss >> header, std::runtime_error); } { std::string malformedData = "P6\n100\n255\n"; std::stringstream ss(malformedData); PnmHeader header; REQUIRE_THROWS_AS(ss >> header, std::runtime_error); } { std::string malformedData = "GarbageInput"; std::stringstream ss(malformedData); PnmHeader header; REQUIRE_THROWS_AS(ss >> header, std::runtime_error); } } TEST_CASE("Read throws on unsupported ascii mode", "[Pnm]") { std::string pnmData = "P3\n100 100\n255\n"; std::stringstream ss(pnmData); PnmImage image; REQUIRE_THROWS_AS(image.Read(ss), std::runtime_error); } TEST_CASE("Read successfully reads binary image data", "[Pnm]") { std::string pnmHeader = "P6\n2 2\n255\n"; std::string pnmImage = "\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\x00\x00"; std::stringstream ss(pnmHeader + pnmImage); PnmImage image; REQUIRE_NOTHROW(image.Read(ss)); REQUIRE(image.header.width == 2); REQUIRE(image.header.height == 2); REQUIRE(image.header.maxValue == 255); REQUIRE(image.header.color == PnmHeader::ColorMode::COLOR); REQUIRE(image.image[0] == '\xFF'); REQUIRE(image.image[1] == '\x00'); REQUIRE(image.image[2] == '\x00'); }