add image class serialization

This commit is contained in:
2019-09-03 08:08:31 +02:00
parent 486d2a4eeb
commit 6639414e54
3 changed files with 156 additions and 10 deletions

View File

@@ -4,6 +4,7 @@
#include "asset.h"
#include <stb/stb_image.h>
#include <stb/stb_image_write.h>
bool Image::load(std::string filename)
{
@@ -15,6 +16,16 @@ bool Image::load(std::string filename)
file.close();
return false;
}
std::string name, base, ext;
std::regex r(R"((.*)[\\/]([^\\/]+)\.(\w+)$)");
std::smatch m;
if (!std::regex_search(filename, m, r))
return false;
file_base = m[1].str();
file_name = m[2].str();
file_ext = m[3].str();
stbi_set_flip_vertically_on_load(false);
uint8_t* buffer = stbi_load_from_memory(file.m_data, file.m_len, &width, &height, nullptr, 4);
file.close();
@@ -36,6 +47,16 @@ bool Image::load_file(std::string filename)
return false;
comp = 4;
m_data = std::unique_ptr<uint8_t[]>(buffer);
std::string name, base, ext;
std::regex r(R"((.*)[\\/]([^\\/]+)\.(\w+)$)");
std::smatch m;
if (!std::regex_search(filename, m, r))
return false;
file_base = m[1].str();
file_name = m[2].str();
file_ext = m[3].str();
return true;
}
@@ -86,6 +107,9 @@ Image Image::resize(int w, int h) const
{
Image ret;
ret.create(w, h);
ret.file_base = file_base;
ret.file_name = file_name;
ret.file_ext = file_ext;
auto temp = (glm::u8vec4*)ret.data();
auto pixels = (glm::u8vec4*)data();
float x_ratio = ((float)(width - 1)) / w;
@@ -122,6 +146,9 @@ Image Image::resize_power2() const
{
Image i;
i.create(width, height);
i.file_base = file_base;
i.file_name = file_name;
i.file_ext = file_ext;
std::copy(m_data.get(), m_data.get() + width * height * comp, i.m_data.get());
return i;
}
@@ -134,6 +161,9 @@ Image Image::resize_squared(const glm::u8vec4& bg) const
if (width == height)
{
ret.create(width, height);
ret.file_base = file_base;
ret.file_name = file_name;
ret.file_ext = file_ext;
std::copy(m_data.get(), m_data.get() + width * height * comp, ret.m_data.get());
}
else
@@ -152,6 +182,9 @@ Image Image::resize_squared(const glm::u8vec4& bg) const
pad_y = (size - height) / 2;
}
ret.create(size, size);
ret.file_base = file_base;
ret.file_name = file_name;
ret.file_ext = file_ext;
auto ptr_src = reinterpret_cast<glm::u8vec4*>(m_data.get());
auto ptr_dst = reinterpret_cast<glm::u8vec4*>(ret.m_data.get());
std::fill_n(ptr_dst, size * size, bg);
@@ -160,3 +193,44 @@ Image Image::resize_squared(const glm::u8vec4& bg) const
}
return ret;
}
bool Image::read(BinaryStreamReader& r)
{
Serializer::Descriptor d;
if (d.class_id != "image_png")
return false;
r >> d;
d.value<Serializer::Integer>("width", width);
d.value<Serializer::Integer>("height", height);
d.value<Serializer::Integer>("comp", comp);
file_base = wstr2str(d.value<Serializer::String>("file_base"));
file_name = wstr2str(d.value<Serializer::String>("file_name"));
file_ext = wstr2str(d.value<Serializer::String>("file_ext"));
auto img_raw = d.get<Serializer::RawData>("data");
int png_width, png_height, png_comp;
m_data = std::unique_ptr<uint8_t[]>(stbi_load_from_memory(
img_raw->data.data(), img_raw->data.size(), &png_width, &png_height, &png_comp, 4));
return true;
}
void Image::write(BinaryStreamWriter& w) const
{
Serializer::Descriptor d;
d.class_id = "image_png";
d.name = L"Image class";
d.props["width"] = std::make_shared<Serializer::Integer>(width);
d.props["height"] = std::make_shared<Serializer::Integer>(height);
d.props["comp"] = std::make_shared<Serializer::Integer>(comp);
d.props["file_base"] = std::make_shared<Serializer::String>(file_base);
d.props["file_name"] = std::make_shared<Serializer::String>(file_name);
d.props["file_ext"] = std::make_shared<Serializer::String>(file_ext);
// really ugly way to compress the png and store it with a lambda
stbi_write_png_to_func([](void* context, void* data, int size) {
Serializer::Descriptor& d = *static_cast<Serializer::Descriptor*>(context);
d.props["data"] = std::make_shared<Serializer::RawData>(std::vector<uint8_t>((uint8_t*)data, (uint8_t*)data + size));
}, &d, width, height, comp, m_data.get(), 0);
w << d;
}