satdump/plugins/bitview_app/bitview.cpp

238 lines
7.3 KiB
C++
Raw Normal View History

2024-05-18 18:05:04 +02:00
#include "bitview.h"
#include "bit_container.h"
2025-06-08 18:49:41 +02:00
#include "core/style.h"
#include "imgui/imgui.h"
#include "imgui/imgui_stdlib.h"
2024-05-18 18:05:04 +02:00
#include "imgui/implot/implot.h"
2025-12-11 18:07:32 +01:00
#include "imgui/implot/implot_internal.h"
2025-12-11 14:28:36 +01:00
#include <exception>
2025-06-08 18:49:41 +02:00
#include <fcntl.h>
#include <memory>
#include <string>
2024-05-18 18:05:04 +02:00
#include "libs/muparser/muParser.h"
#include "libs/muparser/muParserError.h"
2025-12-11 15:09:34 +01:00
#include "logger.h"
#include "tools/ccsds_apid_demux/ccsds_apid_demux.h"
#include "tools/ccsds_vcid_splitter/ccsds_vcid_splitter.h"
#include "tools/deframer/deframer.h"
#include "tools/deinterleave/deinterleave.h"
2025-12-11 15:09:34 +01:00
#include "tools/diff_decode/diff_decode.h"
#include "tools/soft2hard/soft2hard.h"
2025-12-12 11:48:41 +01:00
#include "tools/take_skip/take_skip.h"
2024-05-18 18:54:57 +02:00
2024-05-18 18:05:04 +02:00
namespace satdump
{
BitViewHandler::BitViewHandler(std::shared_ptr<BitContainer> c) : bc(c)
2024-05-18 18:05:04 +02:00
{
2025-02-10 20:09:03 +01:00
c->bitview = this;
2025-05-04 17:27:35 +02:00
handler_tree_icon = u8"\uf471";
2025-02-10 20:09:03 +01:00
2025-12-12 11:48:41 +01:00
all_tools.push_back(std::make_shared<TakeSkipTool>());
2024-05-19 15:16:25 +02:00
all_tools.push_back(std::make_shared<DeframerTool>());
all_tools.push_back(std::make_shared<DifferentialTool>());
all_tools.push_back(std::make_shared<Soft2HardTool>());
all_tools.push_back(std::make_shared<DeinterleaveTool>());
2024-05-19 17:34:10 +02:00
all_tools.push_back(std::make_shared<CCSDSVcidSplitterTool>());
2025-11-23 20:08:17 +01:00
all_tools.push_back(std::make_shared<CCSDSAPIDDemuxTool>());
frame_width_exp = std::to_string(bc->d_bitperiod);
2024-05-18 18:05:04 +02:00
}
2025-06-08 18:49:41 +02:00
BitViewHandler::~BitViewHandler() {}
2024-05-18 18:05:04 +02:00
2025-02-10 20:09:03 +01:00
void BitViewHandler::drawMenu()
2024-05-18 18:05:04 +02:00
{
2024-05-18 18:54:57 +02:00
if (is_busy)
style::beginDisabled();
if (ImGui::CollapsingHeader("Display", ImGuiTreeNodeFlags_DefaultOpen))
2024-05-18 18:05:04 +02:00
{
if (!bc->d_frame_mode)
{
if (ImGui::InputText("Period (Bits)", &frame_width_exp))
{
try
{
mu::Parser equParser;
equParser.SetExpr(frame_width_exp);
int nout = 0;
double *out = equParser.Eval(nout);
if (nout == 1)
{
bc->d_bitperiod = *out;
bc->init_display();
}
else
{
logger->error("Error parsing bit period! Expression must have 1 output");
}
}
catch (mu::ParserError &)
{
}
}
}
2024-05-18 18:05:04 +02:00
2025-12-12 23:17:19 +01:00
if (ImGui::RadioButton("Bits", bc->d_display_mode == 0 && !custom_bit_depth && bc->d_display_bits == 1))
2024-05-18 18:05:04 +02:00
{
2025-12-12 23:17:19 +01:00
bc->d_display_mode = 0;
2025-12-11 17:35:35 +01:00
custom_bit_depth = false;
bc->d_display_bits = 1;
bc->init_display();
}
2024-05-19 15:16:25 +02:00
ImGui::SameLine();
2025-12-12 23:17:19 +01:00
if (ImGui::RadioButton("Bytes", bc->d_display_mode == 0 && !custom_bit_depth && bc->d_display_bits == 8))
{
2025-12-12 23:17:19 +01:00
bc->d_display_mode = 0;
2025-12-11 17:35:35 +01:00
custom_bit_depth = false;
bc->d_display_bits = 8;
bc->init_display();
}
ImGui::SameLine();
2025-12-12 23:17:19 +01:00
if (ImGui::RadioButton("Custom", bc->d_display_mode == 0 && custom_bit_depth))
2025-12-11 17:35:35 +01:00
{
2025-12-12 23:17:19 +01:00
bc->d_display_mode = 0;
2025-12-11 17:35:35 +01:00
custom_bit_depth = true;
bc->d_display_bits = 10;
bc->init_display();
}
2025-12-12 23:17:19 +01:00
if (ImGui::RadioButton("ASCII", bc->d_display_mode == 1))
{
custom_bit_depth = false;
bc->d_display_mode = 1;
bc->init_display();
}
2025-12-11 17:35:35 +01:00
if (custom_bit_depth)
{
if (ImGui::InputInt("Bit Depth", &bc->d_display_bits))
{
if (bc->d_display_bits > 32)
bc->d_display_bits = 32;
if (bc->d_display_bits < 1)
bc->d_display_bits = 1;
bc->init_display();
}
2024-05-18 18:05:04 +02:00
}
if (!bc->d_is_temporary)
{
if (ImGui::Button("Reload"))
{
auto bbc = bc;
bc = std::make_shared<BitContainer>(bbc->getName(), bbc->getFilePath(), bbc->frames);
bc->d_bitperiod = bbc->d_bitperiod;
2025-12-11 17:35:35 +01:00
bc->init_display();
2025-12-09 20:50:40 +01:00
bc->bitview = this;
}
}
2024-05-18 18:05:04 +02:00
}
2024-05-18 18:54:57 +02:00
if (is_busy)
style::endDisabled();
2025-12-10 20:30:34 +01:00
for (auto &tool : all_tools)
2024-05-18 18:05:04 +02:00
{
2025-12-10 20:30:34 +01:00
if (ImGui::CollapsingHeader((tool->getName()).c_str()))
2024-05-18 18:05:04 +02:00
{
2025-12-11 17:35:35 +01:00
ImGui::PushID((tool->getName()).c_str());
tool->renderMenu(bc, is_busy);
2025-12-11 17:35:35 +01:00
ImGui::PopID();
2024-05-18 18:30:56 +02:00
if (tool->needToProcess())
{
tool->setProcessed();
2025-12-11 15:09:34 +01:00
auto func = [this, tool]()
2024-05-19 15:16:25 +02:00
{
2025-12-11 14:28:36 +01:00
try
{
tool->process(bc, process_progress);
}
catch (std::exception &e)
{
logger->error("Error running tool! %s", e.what());
}
is_busy = false;
};
is_busy = true;
2025-12-11 15:09:34 +01:00
process_task.push(func);
2024-05-18 18:05:04 +02:00
}
}
2025-12-10 20:30:34 +01:00
}
2024-05-18 18:05:04 +02:00
2025-12-10 20:30:34 +01:00
ImGui::Spacing();
2025-12-10 20:30:34 +01:00
ImGui::ProgressBar(process_progress);
2025-12-10 20:30:34 +01:00
ImGui::Separator();
2025-12-10 20:30:34 +01:00
if (ImGui::Button("Find Sync"))
{
2025-12-11 15:09:34 +01:00
auto func = [this]()
{
2025-12-10 20:30:34 +01:00
auto ptr = bc->get_ptr();
auto sz = bc->get_ptr_size();
2025-12-10 20:30:34 +01:00
bc->highlights.clear();
2025-12-10 20:30:34 +01:00
for (int i = 0; i < (sz / 8) - 4; i++)
{
if (ptr[i + 0] == 0x1a && ptr[i + 1] == 0xcf && ptr[i + 2] == 0xfc && ptr[i + 3] == 0x1d)
bc->highlights.push_back({(size_t)i * 8, 64, 0, 0, 255});
}
is_busy = false;
};
is_busy = true;
2025-12-11 15:09:34 +01:00
process_task.push(func);
2024-05-18 18:05:04 +02:00
}
}
2025-06-08 18:49:41 +02:00
void BitViewHandler::drawMenuBar() {}
2025-02-10 20:09:03 +01:00
2025-12-11 14:28:36 +01:00
void BitViewHandler::drawContextMenu()
{
// Delete all subhandlers quickly
if (subhandlers.size() && ImGui::MenuItem("Clear Subhandlers"))
{
for (auto &h : subhandlers)
delSubHandler(h);
}
}
2025-02-10 20:09:03 +01:00
void BitViewHandler::drawContents(ImVec2 win_size)
2024-05-18 18:05:04 +02:00
{
2025-02-10 20:09:03 +01:00
ImVec2 window_size = win_size;
2024-05-18 18:05:04 +02:00
bc->doUpdateTextures();
2024-05-18 18:05:04 +02:00
ImPlot::BeginPlot("MainPlot", window_size, ImPlotFlags_Equal | ImPlotFlags_NoLegend);
ImPlot::SetupAxes(nullptr, nullptr, 0, ImPlotAxisFlags_Invert);
ImPlotRect c = ImPlot::GetPlotLimits();
bc->doDrawPlotTextures(c);
2024-05-18 18:05:04 +02:00
// ImPlot::GetPlotDrawList()->AddRectFilled(ImPlot::PlotToPixels({0, 0}), ImPlot::PlotToPixels({1, 1}), ImColor(255, 0, 0, 255 * 0.5));
2025-12-11 18:07:32 +01:00
if (reset_view)
{
ImPlot::GetCurrentPlot()->XAxis(0).SetRange(ImPlotRange(0, 512));
ImPlot::GetCurrentPlot()->YAxis(0).SetRange(ImPlotRange(0, 512));
reset_view = false;
}
2024-05-18 18:05:04 +02:00
ImPlot::EndPlot();
2025-12-11 18:07:32 +01:00
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
reset_view = true;
2024-05-18 18:05:04 +02:00
}
2025-06-08 18:49:41 +02:00
} // namespace satdump