5#include <BufferStream.h>
12 , checksum(modelChecksum)
16 BufferStreamReadOnly reader{pplData.data(), pplData.size()};
19 const auto imageCount = reader.read<uint32_t>();
20 reader.skip<uint32_t>(4);
21 for (uint32_t i = 0; i < imageCount; i++) {
22 const auto lod = reader.read<uint32_t>();
23 const auto offset = reader.read<uint32_t>();
24 const auto length = reader.read<uint32_t>();
25 const auto width = reader.read<uint32_t>();
26 const auto height = reader.read<uint32_t>();
27 reader.skip<uint32_t>(3);
32 .data = {pplData.data() + offset, pplData.data() + offset + length},
38 :
PPL(fs::readFileBuffer(pplPath)) {}
40PPL::operator bool()
const {
41 return !this->images.empty();
65 for (
auto& [lod, image] : this->
images) {
72 return this->
images.contains(lod);
76 auto view = std::views::keys(this->
images);
77 return {view.begin(), view.end()};
84 return &this->
images.at(lod);
91 const auto& [width, height, data] = this->
images.at(lod);
104 if (!width || !height) {
116 if (!width || !height || !resizedWidth || !resizedHeight) {
130 int inputWidth, inputHeight, inputFrameCount;
134 if (inputFormat ==
ImageFormat::EMPTY || !inputWidth || !inputHeight || !inputFrameCount) {
139 if (inputFrameCount == 1) {
140 return this->
setImage(imageData_, inputFormat, inputWidth, inputHeight, lod);
149 int inputWidth, inputHeight, inputFrameCount;
153 if (inputFormat ==
ImageFormat::EMPTY || !inputWidth || !inputHeight || !inputFrameCount) {
158 if (inputFrameCount == 1) {
159 return this->
setImage(imageData_, inputFormat, inputWidth, inputHeight, resizedWidth, resizedHeight, lod, filter);
163 return this->
setImage({imageData_.data(),
ImageFormatDetails::getDataLength(inputFormat, inputWidth, inputHeight)}, inputFormat, inputWidth, inputHeight, resizedWidth, resizedHeight, lod, filter);
174 if (
auto data = this->
saveImageToFile(lod, fileFormat); !data.empty()) {
181 static constexpr auto ALIGNMENT = 512;
183 std::vector<std::byte> out;
184 BufferStream writer{out};
186 static constexpr auto HEADER_SIZE =
sizeof(uint32_t) * 8;
188 writer.write<uint32_t>(this->
images.size());
190 while (writer.tell() < ALIGNMENT) {
191 writer.write<uint32_t>(0);
193 writer.seek(HEADER_SIZE);
195 uint32_t currentOffset = ALIGNMENT;
196 for (
const auto& [lod, image] : this->
images) {
197 writer << lod << currentOffset << static_cast<uint32_t>(image.data.size()) << image.width << image.height;
198 for (
int i = 0; i < 3; i++) {
199 writer.write<uint32_t>(0);
201 const auto seekPoint = writer.tell();
202 writer.seek_u(currentOffset).write(image.data);
204 for (
int i = 0; i < alignment; i++) {
205 writer.write<uint8_t>(0);
207 writer.seek_u(seekPoint);
208 currentOffset += image.data.size() + alignment;
210 writer.seek(0, std::ios::end);
212 out.resize(writer.size());
ImageFormat getFormat() const
const Image * getImageRaw(uint32_t lod=0) const
std::vector< std::byte > saveImageToFile(uint32_t lod=0, ImageConversion::FileFormat fileFormat=ImageConversion::FileFormat::DEFAULT) const
std::optional< Image > getImageAsRGB888(uint32_t lod=0) const
bool hasImageForLOD(uint32_t lod) const
void setFormat(ImageFormat newFormat)
std::vector< std::byte > bake()
bool setImage(std::span< const std::byte > imageData, ImageFormat format_, uint32_t width, uint32_t height, uint32_t lod=0)
uint32_t getVersion() const
std::unordered_map< uint32_t, Image > images
PPL(uint32_t modelChecksum, ImageFormat format_=ImageFormat::RGB888, uint32_t version_=0)
std::optional< Image > getImageAs(ImageFormat newFormat, uint32_t lod=0) const
std::vector< uint32_t > getImageLODs() const
void setVersion(uint32_t newVersion)
uint32_t getModelChecksum() const
void setModelChecksum(uint32_t newChecksum)
std::vector< std::byte > readFileBuffer(const std::string &filepath, std::size_t startOffset=0)
bool writeFileBuffer(const std::string &filepath, std::span< const std::byte > buffer)
constexpr uint16_t paddingForAlignment(uint16_t alignment, uint64_t n)
std::vector< std::byte > convertFileToImageData(std::span< const std::byte > fileData, ImageFormat &format, int &width, int &height, int &frameCount)
std::vector< std::byte > convertImageDataToFile(std::span< const std::byte > imageData, ImageFormat format, uint16_t width, uint16_t height, FileFormat fileFormat=FileFormat::DEFAULT)
Converts image data to the given file format (PNG or EXR by default).
std::vector< std::byte > convertImageDataToFormat(std::span< const std::byte > imageData, ImageFormat oldFormat, ImageFormat newFormat, uint16_t width, uint16_t height)
Converts an image from one format to another.
std::vector< std::byte > resizeImageData(std::span< const std::byte > imageData, ImageFormat format, uint16_t width, uint16_t newWidth, uint16_t height, uint16_t newHeight, bool srgb, ResizeFilter filter, ResizeEdge edge=ResizeEdge::CLAMP)
Resize given image data to the new dimensions.