From 5ecec267311e562e5c0b50a353dfe9d297519cfe Mon Sep 17 00:00:00 2001 From: Green Sky Date: Wed, 2 Aug 2023 19:24:51 +0200 Subject: [PATCH] image inlining working --- src/CMakeLists.txt | 9 +++- src/chat_gui4.cpp | 17 +++---- src/image_loader_sdl_bmp.cpp | 4 ++ src/main_screen.cpp | 1 + src/main_screen.hpp | 4 ++ src/media_meta_info_loader.cpp | 84 ++++++++++++++++++++++++++++++++++ src/media_meta_info_loader.hpp | 33 +++++++++++++ src/message_image_loader.cpp | 2 + src/texture_cache.cpp | 4 +- 9 files changed, 144 insertions(+), 14 deletions(-) create mode 100644 src/media_meta_info_loader.cpp create mode 100644 src/media_meta_info_loader.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ef5d16c9..b1627fc4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,6 +15,8 @@ add_executable(tomato ./auto_dirty.hpp ./auto_dirty.cpp + ./theme.hpp + ./image_loader.hpp ./image_loader_sdl_bmp.hpp ./image_loader_sdl_bmp.cpp @@ -23,18 +25,23 @@ add_executable(tomato ./image_loader_webp.hpp ./image_loader_webp.cpp - ./theme.hpp ./texture_uploader.hpp ./sdlrenderer_texture_uploader.hpp ./sdlrenderer_texture_uploader.cpp + ./texture_cache.hpp ./texture_cache.cpp ./tox_avatar_loader.hpp ./tox_avatar_loader.cpp ./message_image_loader.hpp ./message_image_loader.cpp + + ./media_meta_info_loader.hpp + ./media_meta_info_loader.cpp + ./sdl_clipboard_utils.hpp ./sdl_clipboard_utils.cpp + ./file_selector.hpp ./file_selector.cpp diff --git a/src/chat_gui4.cpp b/src/chat_gui4.cpp index 5507e68c..d07c803c 100644 --- a/src/chat_gui4.cpp +++ b/src/chat_gui4.cpp @@ -6,13 +6,13 @@ #include #include -//#include "./media_meta_info_loader.hpp" #include #include #include +#include "./media_meta_info_loader.hpp" #include "./sdl_clipboard_utils.hpp" #include @@ -42,6 +42,7 @@ void ChatGui4::render(void) { // ACTUALLY NOT IF RENDERED, MOVED LOGIC TO ABOVE // it might unload textures, so it needs to be done before rendering _contact_tc.update(); + _msg_tc.update(); const ImGuiViewport* viewport = ImGui::GetMainViewport(); ImGui::SetNextWindowPos(viewport->WorkPos); @@ -294,6 +295,7 @@ void ChatGui4::render(void) { _fss.render(); _contact_tc.workLoadQueue(); + _msg_tc.workLoadQueue(); } // has MessageText @@ -400,14 +402,11 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) { ImGui::Bullet(); ImGui::Text("%s (%lu)", file_list[i].file_name.c_str(), file_list[i].file_size); } -#if 0 - - // TODO: use frame dims if (file_list.size() == 1 && reg.all_of(e)) { - auto [id, width, height] = _tc.get(reg.get(e).file_list.front()); + auto [id, width, height] = _msg_tc.get(Message3Handle{reg, e}); // if cache gives 0s, fall back to frame dims (eg if pic not loaded yet) - if (width > 0 || height > 0) { + if (width == 0 || height == 0) { const auto& frame_dims = reg.get(e); width = frame_dims.width; height = frame_dims.height; @@ -420,9 +419,9 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) { height = max_inline_height; width *= scale; } + ImGui::Image(id, ImVec2{static_cast(width), static_cast(height)}); } -#endif } void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) { @@ -529,7 +528,6 @@ bool ChatGui4::renderContactListContactBig(const Contact3 c) { } // avatar -#if 1 const auto [id, width, height] = _contact_tc.get(c); ImGui::Image( id, @@ -539,9 +537,6 @@ bool ChatGui4::renderContactListContactBig(const Contact3 c) { {1, 1, 1, 1}, color_current ); -#else - ImGui::Dummy({img_y, img_y}); -#endif ImGui::SameLine(); ImGui::BeginGroup(); diff --git a/src/image_loader_sdl_bmp.cpp b/src/image_loader_sdl_bmp.cpp index 34661cda..0a16b150 100644 --- a/src/image_loader_sdl_bmp.cpp +++ b/src/image_loader_sdl_bmp.cpp @@ -2,6 +2,8 @@ #include +#include + ImageLoaderSDLBMP::ImageInfo ImageLoaderSDLBMP::loadInfoFromMemory(const uint8_t* data, uint64_t data_size) { ImageInfo res; @@ -48,6 +50,8 @@ ImageLoaderSDLBMP::ImageResult ImageLoaderSDLBMP::loadFromMemoryRGBA(const uint8 SDL_UnlockSurface(conv_surf); SDL_DestroySurface(conv_surf); + std::cout << "IL_SDLBMP: loaded img " << res.width << "x" << res.height << "\n"; + return res; } diff --git a/src/main_screen.cpp b/src/main_screen.cpp index 6a2f5a36..a4d7d3f7 100644 --- a/src/main_screen.cpp +++ b/src/main_screen.cpp @@ -15,6 +15,7 @@ MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path) : tcm(cr, tc, tc), tmm(rmm, cr, tcm, tc, tc), ttm(rmm, cr, tcm, tc, tc), + mmil(rmm), sdlrtu(renderer_), cg(conf, rmm, cr, sdlrtu) { diff --git a/src/main_screen.hpp b/src/main_screen.hpp index 6f9de6a2..ad081a4a 100644 --- a/src/main_screen.hpp +++ b/src/main_screen.hpp @@ -16,6 +16,8 @@ #include "./tox_client.hpp" #include "./auto_dirty.hpp" +#include "./media_meta_info_loader.hpp" + #include "./sdlrenderer_texture_uploader.hpp" #include "./chat_gui4.hpp" @@ -47,6 +49,8 @@ struct MainScreen final : public Screen { ToxMessageManager tmm; ToxTransferManager ttm; + MediaMetaInfoLoader mmil; + SDLRendererTextureUploader sdlrtu; //OpenGLTextureUploader ogltu; diff --git a/src/media_meta_info_loader.cpp b/src/media_meta_info_loader.cpp new file mode 100644 index 00000000..31f78542 --- /dev/null +++ b/src/media_meta_info_loader.cpp @@ -0,0 +1,84 @@ +#include "./media_meta_info_loader.hpp" + +#include "./image_loader_webp.hpp" +#include "./image_loader_sdl_bmp.hpp" +#include "./image_loader_stb.hpp" + +#include + +#include +#include + +MediaMetaInfoLoader::MediaMetaInfoLoader(RegistryMessageModel& rmm) : _rmm(rmm) { + // HACK: make them be added externally? + _image_loaders.push_back(std::make_unique()); + _image_loaders.push_back(std::make_unique()); + _image_loaders.push_back(std::make_unique()); + + _rmm.subscribe(this, RegistryMessageModel_Event::message_construct); + _rmm.subscribe(this, RegistryMessageModel_Event::message_updated); +} + +MediaMetaInfoLoader::~MediaMetaInfoLoader(void) { +} + +bool MediaMetaInfoLoader::onEvent(const Message::Events::MessageConstruct& e) { + return false; +} + +bool MediaMetaInfoLoader::onEvent(const Message::Events::MessageUpdated& e) { + if (e.e.any_of()) { + return false; + } + + if (!e.e.all_of()) { + return false; + } + + const auto& fil = e.e.get(); + if (fil.file_list.size() != 1) { + return false; + } + + std::ifstream file(fil.file_list.front(), 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); + } + } + + bool could_load {false}; + // try all loaders after another + for (auto& il : _image_loaders) { + auto res = il->loadInfoFromMemory(tmp_buffer.data(), tmp_buffer.size()); + if (res.height == 0 || res.width == 0) { + continue; + } + + e.e.emplace(res.width, res.height); + + could_load = true; + + std::cout << "MMIL loaded image info " << fil.file_list.front() << "\n"; + + _rmm.throwEventUpdate(e.e); + break; + } + + if (!could_load) { + e.e.emplace(); + + std::cout << "MMIL loading failed image info " << fil.file_list.front() << "\n"; + + _rmm.throwEventUpdate(e.e); + } + } + + return false; +} + diff --git a/src/media_meta_info_loader.hpp b/src/media_meta_info_loader.hpp new file mode 100644 index 00000000..26b1e8f5 --- /dev/null +++ b/src/media_meta_info_loader.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "./image_loader.hpp" + +namespace Message::Components { + + struct FrameDims { + uint32_t width {0}; + uint32_t height {0}; + }; + + struct TagNotImage {}; + +} // Message::Components + +// adds metadata to file messages +class MediaMetaInfoLoader : public RegistryMessageModelEventI { + protected: + RegistryMessageModel& _rmm; + + std::vector> _image_loaders; + + public: + MediaMetaInfoLoader(RegistryMessageModel& rmm); + virtual ~MediaMetaInfoLoader(void); + + protected: // rmm + bool onEvent(const Message::Events::MessageConstruct& e) override; + bool onEvent(const Message::Events::MessageUpdated& e) override; +}; + diff --git a/src/message_image_loader.cpp b/src/message_image_loader.cpp index 16626559..1c02004a 100644 --- a/src/message_image_loader.cpp +++ b/src/message_image_loader.cpp @@ -65,6 +65,8 @@ std::optional MessageImageLoader::load(TextureUploaderI& tu, Messa } } + std::cerr << "MIL: failed to load message\n"; + return std::nullopt; } diff --git a/src/texture_cache.cpp b/src/texture_cache.cpp index fba6de48..9abdf5d9 100644 --- a/src/texture_cache.cpp +++ b/src/texture_cache.cpp @@ -49,8 +49,8 @@ TextureEntry generateTestAnim(TextureUploaderI& tu) { new_entry.textures.emplace_back(n_t); new_entry.frame_duration.emplace_back(250); } - new_entry.width = 2; - new_entry.height = 2; + new_entry.width = 0; + new_entry.height = 0; return new_entry; }