diff --git a/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h b/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h index d7d9c52f5..7a7b05090 100644 --- a/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h +++ b/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h @@ -34,7 +34,7 @@ namespace ImGui { class Texture { public: Texture() = default; - Texture(const ImU8 *buffer, int size); + Texture(const ImU8 *buffer, int size, int width = 0, int height = 0); explicit Texture(const char *path); Texture(const Texture&) = delete; Texture(Texture&& other) noexcept; diff --git a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp index 908e331c5..a28566c83 100644 --- a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp +++ b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp @@ -16,8 +16,17 @@ namespace ImGui { - Texture::Texture(const ImU8 *buffer, int size) { + Texture::Texture(const ImU8 *buffer, int size, int width, int height) { unsigned char *imageData = stbi_load_from_memory(buffer, size, &this->m_width, &this->m_height, nullptr, 4); + if (imageData == nullptr) { + if (width * height * 4 > size) + return; + + imageData = (unsigned char*) STBI_MALLOC(size); + std::memcpy(imageData, buffer, size); + this->m_width = width; + this->m_height = height; + } if (imageData == nullptr) return; diff --git a/plugins/builtin/source/content/data_processor_nodes.cpp b/plugins/builtin/source/content/data_processor_nodes.cpp index aa1243e4e..230058a48 100644 --- a/plugins/builtin/source/content/data_processor_nodes.cpp +++ b/plugins/builtin/source/content/data_processor_nodes.cpp @@ -1007,6 +1007,37 @@ namespace hex::plugin::builtin { ImGui::Texture m_texture; }; + class NodeVisualizerImageRGBA : public dp::Node { + public: + NodeVisualizerImageRGBA() : Node("hex.builtin.nodes.visualizer.image_rgba.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.common.width"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.common.height") }) { } + + void drawNode() override { + ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 200, 200))); + if (ImGui::IsItemHovered() && ImGui::IsKeyDown(ImGuiKey_LeftShift)) { + ImGui::BeginTooltip(); + ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 600, 600))); + ImGui::EndTooltip(); + } + } + + void process() override { + this->m_texture = { }; + + const auto rawData = this->getBufferOnInput(0); + const auto width = this->getIntegerOnInput(1); + const auto height = this->getIntegerOnInput(2); + + const size_t requiredBytes = width * height * 4; + if (requiredBytes > rawData.size()) + throwNodeError(hex::format("Image requires at least {} bytes of data, but only {} bytes are available", requiredBytes, rawData.size())); + + this->m_texture = ImGui::Texture(rawData.data(), rawData.size(), width, height); + } + + private: + ImGui::Texture m_texture; + }; + class NodeVisualizerByteDistribution : public dp::Node { public: NodeVisualizerByteDistribution() : Node("hex.builtin.nodes.visualizer.byte_distribution.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { } @@ -1142,6 +1173,7 @@ namespace hex::plugin::builtin { ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.visualizer", "hex.builtin.nodes.visualizer.digram"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.visualizer", "hex.builtin.nodes.visualizer.layered_dist"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.visualizer", "hex.builtin.nodes.visualizer.image"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.visualizer", "hex.builtin.nodes.visualizer.image_rgba"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.visualizer", "hex.builtin.nodes.visualizer.byte_distribution"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.pattern_language", "hex.builtin.nodes.pattern_language.out_var"); diff --git a/plugins/builtin/source/lang/de_DE.cpp b/plugins/builtin/source/lang/de_DE.cpp index e7db11d0b..26fffa870 100644 --- a/plugins/builtin/source/lang/de_DE.cpp +++ b/plugins/builtin/source/lang/de_DE.cpp @@ -512,6 +512,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.common.input.a", "Input A" }, { "hex.builtin.nodes.common.input.b", "Input B" }, { "hex.builtin.nodes.common.output", "Output" }, + { "hex.builtin.nodes.common.width", "Breite" }, + { "hex.builtin.nodes.common.height", "Höhe" }, { "hex.builtin.nodes.constants", "Konstanten" }, { "hex.builtin.nodes.constants.int", "Integral" }, @@ -646,6 +648,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.visualizer.layered_dist.header", "Geschichtete Verteilung" }, { "hex.builtin.nodes.visualizer.image", "Bild" }, { "hex.builtin.nodes.visualizer.image.header", "Bild" }, + { "hex.builtin.nodes.visualizer.image_rgba", "RGBA8 Bild" }, + { "hex.builtin.nodes.visualizer.image_rgba.header", "RGBA8 Bild" }, { "hex.builtin.nodes.visualizer.byte_distribution", "Byteverteilung" }, { "hex.builtin.nodes.visualizer.byte_distribution.header", "Byteverteilung" }, diff --git a/plugins/builtin/source/lang/en_US.cpp b/plugins/builtin/source/lang/en_US.cpp index 386616a82..66caf6510 100644 --- a/plugins/builtin/source/lang/en_US.cpp +++ b/plugins/builtin/source/lang/en_US.cpp @@ -517,6 +517,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.common.input.a", "Input A" }, { "hex.builtin.nodes.common.input.b", "Input B" }, { "hex.builtin.nodes.common.output", "Output" }, + { "hex.builtin.nodes.common.width", "Width" }, + { "hex.builtin.nodes.common.height", "Height" }, { "hex.builtin.nodes.constants", "Constants" }, { "hex.builtin.nodes.constants.int", "Integer" }, @@ -650,6 +652,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.visualizer.layered_dist.header", "Layered Distribution" }, { "hex.builtin.nodes.visualizer.image", "Image" }, { "hex.builtin.nodes.visualizer.image.header", "Image Visualizer" }, + { "hex.builtin.nodes.visualizer.image_rgba", "RGBA8 Image" }, + { "hex.builtin.nodes.visualizer.image_rgba.header", "RGBA8 Image Visualizer" }, { "hex.builtin.nodes.visualizer.byte_distribution", "Byte Distribution" }, { "hex.builtin.nodes.visualizer.byte_distribution.header", "Byte Distribution" }, diff --git a/plugins/builtin/source/lang/it_IT.cpp b/plugins/builtin/source/lang/it_IT.cpp index 6b9aa0fa4..44c564eab 100644 --- a/plugins/builtin/source/lang/it_IT.cpp +++ b/plugins/builtin/source/lang/it_IT.cpp @@ -543,6 +543,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.common.input.a", "Input A" }, { "hex.builtin.nodes.common.input.b", "Input B" }, { "hex.builtin.nodes.common.output", "Output" }, + //{ "hex.builtin.nodes.common.width", "Width" }, + //{ "hex.builtin.nodes.common.height", "Height" }, { "hex.builtin.nodes.display", "Mostra" }, { "hex.builtin.nodes.display.int", "Intero" }, @@ -656,6 +658,8 @@ namespace hex::plugin::builtin { //{ "hex.builtin.nodes.visualizer.layered_dist.header", "Layered Distribution" }, //{ "hex.builtin.nodes.visualizer.image", "Image" }, //{ "hex.builtin.nodes.visualizer.image.header", "Image Visualizer" }, + //{ "hex.builtin.nodes.visualizer.image_rgba", "RGBA8 Image" }, + //{ "hex.builtin.nodes.visualizer.image_rgba.header", "RGBA8 Image Visualizer" }, //{ "hex.builtin.nodes.visualizer.byte_distribution", "Byte Distribution" }, //{ "hex.builtin.nodes.visualizer.byte_distribution.header", "Byte Distribution" }, diff --git a/plugins/builtin/source/lang/ja_JP.cpp b/plugins/builtin/source/lang/ja_JP.cpp index e23ff6be2..51b1a78e6 100644 --- a/plugins/builtin/source/lang/ja_JP.cpp +++ b/plugins/builtin/source/lang/ja_JP.cpp @@ -520,6 +520,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.common.input.a", "入力 A" }, { "hex.builtin.nodes.common.input.b", "入力 B" }, { "hex.builtin.nodes.common.output", "出力" }, + //{ "hex.builtin.nodes.common.width", "Width" }, + //{ "hex.builtin.nodes.common.height", "Height" }, { "hex.builtin.nodes.constants", "定数" }, { "hex.builtin.nodes.constants.int", "整数" }, @@ -652,6 +654,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.visualizer.layered_dist.header", "層状分布" }, { "hex.builtin.nodes.visualizer.image", "画像" }, { "hex.builtin.nodes.visualizer.image.header", "画像ビジュアライザー" }, + //{ "hex.builtin.nodes.visualizer.image_rgba", "RGBA8 Image" }, + //{ "hex.builtin.nodes.visualizer.image_rgba.header", "RGBA8 Image Visualizer" }, { "hex.builtin.nodes.visualizer.byte_distribution", "バイト分布" }, { "hex.builtin.nodes.visualizer.byte_distribution.header", "バイト分布" }, diff --git a/plugins/builtin/source/lang/ko_KR.cpp b/plugins/builtin/source/lang/ko_KR.cpp index efe5fe67f..d5377eb45 100644 --- a/plugins/builtin/source/lang/ko_KR.cpp +++ b/plugins/builtin/source/lang/ko_KR.cpp @@ -516,6 +516,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.common.input.a", "Input A" }, { "hex.builtin.nodes.common.input.b", "Input B" }, { "hex.builtin.nodes.common.output", "Output" }, + //{ "hex.builtin.nodes.common.width", "Width" }, + //{ "hex.builtin.nodes.common.height", "Height" }, { "hex.builtin.nodes.constants", "상수" }, { "hex.builtin.nodes.constants.int", "정수" }, @@ -649,6 +651,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.visualizer.layered_dist.header", "계층적 분포" }, { "hex.builtin.nodes.visualizer.image", "이미지" }, { "hex.builtin.nodes.visualizer.image.header", "이미지 시각화" }, + //{ "hex.builtin.nodes.visualizer.image_rgba", "RGBA8 Image" }, + //{ "hex.builtin.nodes.visualizer.image_rgba.header", "RGBA8 Image Visualizer" }, { "hex.builtin.nodes.visualizer.byte_distribution", "바이트 분포" }, { "hex.builtin.nodes.visualizer.byte_distribution.header", "바이트 분포" }, diff --git a/plugins/builtin/source/lang/pt_BR.cpp b/plugins/builtin/source/lang/pt_BR.cpp index c267a885a..5c1561df7 100644 --- a/plugins/builtin/source/lang/pt_BR.cpp +++ b/plugins/builtin/source/lang/pt_BR.cpp @@ -515,6 +515,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.common.input.a", "Input A" }, { "hex.builtin.nodes.common.input.b", "Input B" }, { "hex.builtin.nodes.common.output", "Output" }, + //{ "hex.builtin.nodes.common.width", "Width" }, + //{ "hex.builtin.nodes.common.height", "Height" }, { "hex.builtin.nodes.constants", "Constants" }, { "hex.builtin.nodes.constants.int", "Integer" }, @@ -648,6 +650,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.visualizer.layered_dist.header", "Layered Distribution" }, { "hex.builtin.nodes.visualizer.image", "Image" }, { "hex.builtin.nodes.visualizer.image.header", "Image Visualizer" }, + //{ "hex.builtin.nodes.visualizer.image_rgba", "RGBA8 Image" }, + //{ "hex.builtin.nodes.visualizer.image_rgba.header", "RGBA8 Image Visualizer" }, { "hex.builtin.nodes.visualizer.byte_distribution", "Byte Distribution" }, { "hex.builtin.nodes.visualizer.byte_distribution.header", "Byte Distribution" }, diff --git a/plugins/builtin/source/lang/zh_CN.cpp b/plugins/builtin/source/lang/zh_CN.cpp index 771664ace..b809034ed 100644 --- a/plugins/builtin/source/lang/zh_CN.cpp +++ b/plugins/builtin/source/lang/zh_CN.cpp @@ -517,6 +517,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.common.input.a", "输入 A" }, { "hex.builtin.nodes.common.input.b", "输入 B" }, { "hex.builtin.nodes.common.output", "输出" }, + //{ "hex.builtin.nodes.common.width", "Width" }, + //{ "hex.builtin.nodes.common.height", "Height" }, { "hex.builtin.nodes.constants", "常量" }, { "hex.builtin.nodes.constants.int", "整数" }, @@ -651,6 +653,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.visualizer.layered_dist.header", "分层布局" }, { "hex.builtin.nodes.visualizer.image", "图像" }, { "hex.builtin.nodes.visualizer.image.header", "图像可视化" }, + //{ "hex.builtin.nodes.visualizer.image_rgba", "RGBA8 Image" }, + //{ "hex.builtin.nodes.visualizer.image_rgba.header", "RGBA8 Image Visualizer" }, { "hex.builtin.nodes.visualizer.byte_distribution", "字节分布" }, { "hex.builtin.nodes.visualizer.byte_distribution.header", "字节分布" }, diff --git a/plugins/builtin/source/lang/zh_TW.cpp b/plugins/builtin/source/lang/zh_TW.cpp index ea2d7e791..1b3712f72 100644 --- a/plugins/builtin/source/lang/zh_TW.cpp +++ b/plugins/builtin/source/lang/zh_TW.cpp @@ -515,6 +515,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.common.input.a", "輸入 A" }, { "hex.builtin.nodes.common.input.b", "輸入 B" }, { "hex.builtin.nodes.common.output", "輸出" }, + //{ "hex.builtin.nodes.common.width", "Width" }, + //{ "hex.builtin.nodes.common.height", "Height" }, { "hex.builtin.nodes.constants", "常數" }, { "hex.builtin.nodes.constants.int", "整數" }, @@ -648,6 +650,8 @@ namespace hex::plugin::builtin { { "hex.builtin.nodes.visualizer.layered_dist.header", "Layered Distribution" }, { "hex.builtin.nodes.visualizer.image", "圖片" }, { "hex.builtin.nodes.visualizer.image.header", "Image Visualizer" }, + //{ "hex.builtin.nodes.visualizer.image_rgba", "RGBA8 Image" }, + //{ "hex.builtin.nodes.visualizer.image_rgba.header", "RGBA8 Image Visualizer" }, { "hex.builtin.nodes.visualizer.byte_distribution", "Byte Distribution" }, { "hex.builtin.nodes.visualizer.byte_distribution.header", "Byte Distribution" },