Add basic pfm support
This commit is contained in:
97
openVulkanoCpp/IO/Files/Pfm.hpp
Normal file
97
openVulkanoCpp/IO/Files/Pfm.hpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Base/Utils.hpp"
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
|
||||
namespace openVulkanoCpp
|
||||
{
|
||||
//TODO handle comments
|
||||
class PfmHeader
|
||||
{
|
||||
public:
|
||||
static constexpr std::string_view FILE_TYPE = "PFM";
|
||||
static constexpr std::string_view FILE_EXT = ".pfm";
|
||||
|
||||
uint32_t width, height;
|
||||
float maxValue;
|
||||
bool color, littleEndian;
|
||||
|
||||
PfmHeader() : width(0), height(0), maxValue(0), color(false), littleEndian(Utils::IsLittleEndian()) {}
|
||||
|
||||
PfmHeader(uint32_t width, uint32_t height, float maxValue, bool color) :
|
||||
width(width), height(height), maxValue(maxValue), color(color), littleEndian(Utils::IsLittleEndian())
|
||||
{}
|
||||
|
||||
constexpr PfmHeader(uint32_t width, uint32_t height, float maxValue, bool color, bool littleEndian) :
|
||||
width(width), height(height), maxValue(maxValue), color(color), littleEndian(littleEndian)
|
||||
{}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::stringstream headerStream;
|
||||
headerStream << *this;
|
||||
return headerStream.str();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& outStream, const PfmHeader& pfmHeader)
|
||||
{
|
||||
outStream << (pfmHeader.color ? "PF" : "Pf") << '\n';
|
||||
outStream << pfmHeader.width << ' ' << pfmHeader.height << '\n';
|
||||
if (pfmHeader.littleEndian) outStream << '-';
|
||||
outStream << std::fixed << std::setprecision(1) << pfmHeader.maxValue << '\n';
|
||||
return outStream;
|
||||
}
|
||||
|
||||
friend std::istream& operator>> (std::istream& inStream, PfmHeader& pfmHeader)
|
||||
{
|
||||
std::string marker;
|
||||
inStream >> marker;
|
||||
if (marker == "PF") pfmHeader.color = true;
|
||||
else if (marker == "Pf") pfmHeader.color = false;
|
||||
else throw std::runtime_error("Malformed PFM header!");
|
||||
inStream >> pfmHeader.width >> pfmHeader.height;
|
||||
inStream >> pfmHeader.maxValue;
|
||||
if (pfmHeader.maxValue < 0)
|
||||
{
|
||||
pfmHeader.maxValue *= -1;
|
||||
pfmHeader.littleEndian = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfmHeader.littleEndian = false;
|
||||
}
|
||||
return inStream;
|
||||
}
|
||||
|
||||
constexpr size_t GetImageSize() const
|
||||
{
|
||||
size_t size = height * width * sizeof(float);
|
||||
if (color) size *= 3;
|
||||
return size;
|
||||
}
|
||||
|
||||
static std::pair<PfmHeader, std::unique_ptr<float[]>> ReadImage(std::istream& inStream)
|
||||
{
|
||||
std::pair<PfmHeader, std::unique_ptr<float[]>> image;
|
||||
inStream >> image.first;
|
||||
|
||||
if (Utils::IsLittleEndian() != image.first.littleEndian)
|
||||
throw std::runtime_error("Conversion support for endianness not implemented");
|
||||
|
||||
size_t size = image.first.height * image.first.width;
|
||||
image.second = std::make_unique<float[]>(size);
|
||||
inStream.read(reinterpret_cast<char*>(image.second.get()), size);
|
||||
return image;
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user