Moved header structs and some methods to cpp files, reading pnm images upside-down

This commit is contained in:
Vladyslav Baranovskyi
2025-01-04 14:27:28 +02:00
parent 7ea6edf5d0
commit 295468358f
5 changed files with 179 additions and 149 deletions

View File

@@ -14,6 +14,33 @@
#include <sstream>
#include <stdexcept>
namespace
{
struct PfmImageHeader
{
int width;
int height;
bool isColor;
bool isLittleEndian;
};
PfmImageHeader ParseHeader(std::istringstream& stream)
{
PfmImageHeader header;
std::string magic;
stream >> magic;
header.isColor = (magic == "PF");
float endianess;
stream >> header.width >> header.height >> endianess;
stream.ignore();
header.isLittleEndian = endianess < 0;
return header;
}
}
namespace OpenVulkano::Image
{
std::unique_ptr<Image> ImageLoaderPfm::loadFromFile(const std::string& filePath)
@@ -31,12 +58,21 @@ namespace OpenVulkano::Image
std::unique_ptr<Image> ImageLoaderPfm::loadFromMemory(const std::vector<uint8_t>& buffer)
{
std::istringstream stream(std::string(buffer.begin(), buffer.end()), std::ios::binary);
PfmImageHeader header = parseHeader(stream);
PfmImageHeader header = ParseHeader(stream);
size_t numChannels = header.isColor ? 3 : 1;
size_t dataSize = header.width * header.height * numChannels * sizeof(float);
std::vector<float> data(header.width * header.height * numChannels);
stream.read(reinterpret_cast<char*>(data.data()), dataSize);
Array<float> data(header.width * header.height * numChannels);
size_t rowSize = header.width * numChannels * sizeof(float);
for (int y = header.height - 1; y >= 0; --y)
{
stream.read(reinterpret_cast<char*>(&data[y * header.width * numChannels]), rowSize);
if (!stream)
{
throw std::runtime_error("Error reading PFM image data");
}
}
if (!header.isLittleEndian)
{
@@ -47,20 +83,10 @@ namespace OpenVulkano::Image
}
}
for (int y = 0; y < header.height / 2; ++y)
{
for (int x = 0; x < header.width * numChannels; ++x)
{
std::swap(data[y * header.width * numChannels + x],
data[(header.height - 1 - y) * header.width * numChannels + x]);
}
}
auto image = std::make_unique<Image>();
image->resolution = { static_cast<uint32_t>(header.width), static_cast<uint32_t>(header.height), 1 };
image->dataFormat = header.isColor ? DataFormat::Format::R32G32B32_SFLOAT : DataFormat::Format::R32_SFLOAT;
image->data = Array<uint8_t>(dataSize);
memcpy(image->data.Data(), data.data(), dataSize);
image->data = std::move(*reinterpret_cast<Array<uint8_t>*>(&data));
return image;
}
@@ -74,23 +100,7 @@ namespace OpenVulkano::Image
std::vector<uint8_t> buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
std::istringstream stream(std::string(buffer.begin(), buffer.end()), std::ios::binary);
PfmImageHeader header = parseHeader(stream);
PfmImageHeader header = ParseHeader(stream);
return { header.width, header.height };
}
ImageLoaderPfm::PfmImageHeader ImageLoaderPfm::parseHeader(std::istringstream& stream)
{
ImageLoaderPfm::PfmImageHeader header;
std::string magic;
stream >> magic;
header.isColor = (magic == "PF");
float endianess;
stream >> header.width >> header.height >> endianess;
stream.ignore();
header.isLittleEndian = endianess < 0;
return header;
}
}