diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dcaad90..ef5d16c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,6 +31,8 @@ add_executable(tomato ./texture_cache.cpp ./tox_avatar_loader.hpp ./tox_avatar_loader.cpp + ./message_image_loader.hpp + ./message_image_loader.cpp ./sdl_clipboard_utils.hpp ./sdl_clipboard_utils.cpp ./file_selector.hpp diff --git a/src/chat_gui4.cpp b/src/chat_gui4.cpp index 65bbb5c..5507e68 100644 --- a/src/chat_gui4.cpp +++ b/src/chat_gui4.cpp @@ -27,7 +27,7 @@ ChatGui4::ChatGui4( RegistryMessageModel& rmm, Contact3Registry& cr, TextureUploaderI& tu -) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu) { +) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu), _msg_tc(_mil, tu) { } void ChatGui4::render(void) { diff --git a/src/chat_gui4.hpp b/src/chat_gui4.hpp index 43e62b3..3df59b4 100644 --- a/src/chat_gui4.hpp +++ b/src/chat_gui4.hpp @@ -6,6 +6,7 @@ #include "./texture_uploader.hpp" #include "./texture_cache.hpp" #include "./tox_avatar_loader.hpp" +#include "./message_image_loader.hpp" #include "./file_selector.hpp" #include @@ -18,7 +19,8 @@ class ChatGui4 { ToxAvatarLoader _tal; TextureCache _contact_tc; - //TextureCache _msg_tc; + MessageImageLoader _mil; + TextureCache _msg_tc; FileSelector _fss; diff --git a/src/message_image_loader.cpp b/src/message_image_loader.cpp new file mode 100644 index 0000000..1662655 --- /dev/null +++ b/src/message_image_loader.cpp @@ -0,0 +1,70 @@ +#include "./message_image_loader.hpp" + +#include "./image_loader_sdl_bmp.hpp" +#include "./image_loader_stb.hpp" +#include "./image_loader_webp.hpp" + +#include + +#include +#include +#include +#include + +MessageImageLoader::MessageImageLoader(void) { + _image_loaders.push_back(std::make_unique()); + _image_loaders.push_back(std::make_unique()); + _image_loaders.push_back(std::make_unique()); +} + +std::optional MessageImageLoader::load(TextureUploaderI& tu, Message3Handle m) { + if (!static_cast(m)) { + return std::nullopt; + } + + if (m.all_of()) { + const auto& file_list = m.get().file_list; + assert(!file_list.empty()); + const auto& file_path = file_list.front(); + + std::ifstream file(file_path, std::ios::binary); + if (file.is_open()) { + std::vector tmp_buffer; + while (file.good()) { + auto ch = file.get(); + if (ch == EOF) { + break; + } else { + tmp_buffer.push_back(ch); + } + } + + // try all loaders after another + for (auto& il : _image_loaders) { + auto res = il->loadFromMemoryRGBA(tmp_buffer.data(), tmp_buffer.size()); + if (res.frames.empty() || res.height == 0 || res.width == 0) { + continue; + } + + TextureEntry new_entry; + new_entry.timestamp_last_rendered = getNowMS(); + new_entry.current_texture = 0; + for (const auto& [ms, data] : res.frames) { + const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height); + new_entry.textures.push_back(n_t); + new_entry.frame_duration.push_back(ms); + } + + new_entry.width = res.width; + new_entry.height = res.height; + + std::cout << "MIL: loaded image file " << file_path << "\n"; + + return new_entry; + } + } + } + + return std::nullopt; +} + diff --git a/src/message_image_loader.hpp b/src/message_image_loader.hpp new file mode 100644 index 0000000..7210157 --- /dev/null +++ b/src/message_image_loader.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +#include "./image_loader.hpp" +#include "./texture_cache.hpp" + +#include + +class MessageImageLoader { + std::vector> _image_loaders; + + public: + MessageImageLoader(void); + std::optional load(TextureUploaderI& tu, Message3Handle c); +}; + +// TODO: move to rmm +template<> +struct std::hash { + std::size_t operator()(Message3Handle const& m) const noexcept { + const std::size_t h1 = reinterpret_cast(m.registry()); + const std::size_t h2 = entt::to_integral(m.entity()); + return (h1 << 3) ^ (h2 * 11400714819323198485llu); + } +}; +