mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
141 lines
4.5 KiB
C++
141 lines
4.5 KiB
C++
#pragma once
|
|
|
|
#include <map>
|
|
#include <mutex>
|
|
#include "image/image.h"
|
|
#include "image/io.h"
|
|
#include "image/j2k_utils.h"
|
|
#include "common/ccsds/ccsds.h"
|
|
#include "common/ccsds/ccsds_time.h"
|
|
#include "common/utils.h"
|
|
#include "imgui/imgui_image.h"
|
|
#include <filesystem>
|
|
#include "utils/time.h"
|
|
|
|
namespace orb
|
|
{
|
|
class ImageParser
|
|
{
|
|
public:
|
|
struct ImgStc
|
|
{
|
|
image::Image img;
|
|
uint32_t textureID = 0;
|
|
uint32_t *textureBuffer;
|
|
int imgsize = 0;
|
|
bool hasToUpdate = false;
|
|
bool is_dling = false;
|
|
}; // TODO, handle changing image sizes!
|
|
|
|
std::map<int, ImgStc> decoded_imgs;
|
|
time_t last_timestamp = 0;
|
|
std::mutex savingMutex;
|
|
|
|
public:
|
|
std::string directory;
|
|
|
|
public:
|
|
ImageParser()
|
|
{
|
|
}
|
|
|
|
~ImageParser()
|
|
{
|
|
}
|
|
|
|
void work(ccsds::CCSDSPacket &pkt)
|
|
{
|
|
if (pkt.payload.size() < 18)
|
|
{
|
|
if (pkt.payload.size() == 10) // END?
|
|
{
|
|
if (pkt.payload[9] == 0xFF)
|
|
{
|
|
int channel = pkt.payload[8];
|
|
saveAll(channel);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
image::Image imgt = image::decompress_j2k_openjp2(&pkt.payload[17], pkt.payload.size() - 17);
|
|
|
|
uint64_t timestamp = (uint64_t)pkt.payload[0] << 56 |
|
|
(uint64_t)pkt.payload[1] << 48 |
|
|
(uint64_t)pkt.payload[2] << 40 |
|
|
(uint64_t)pkt.payload[3] << 32 |
|
|
(uint64_t)pkt.payload[4] << 24 |
|
|
(uint64_t)pkt.payload[5] << 16 |
|
|
(uint64_t)pkt.payload[6] << 8 |
|
|
(uint64_t)pkt.payload[7]; // TODO use CCSDS
|
|
int channel = pkt.payload[8];
|
|
int width = pkt.payload[9] << 8 | pkt.payload[10];
|
|
int height = pkt.payload[11] << 8 | pkt.payload[12];
|
|
int x_s = pkt.payload[13] << 8 | pkt.payload[14];
|
|
int y_s = pkt.payload[15] << 8 | pkt.payload[16];
|
|
|
|
image::Image img = imgt.to8bits();
|
|
|
|
for (size_t i = 0; i < img.size(); i++)
|
|
img.set(i, imgt.get(i));
|
|
|
|
if (decoded_imgs.count(channel) == 0)
|
|
decoded_imgs.emplace(channel, ImgStc());
|
|
|
|
if ((uint64_t)last_timestamp != timestamp || decoded_imgs[channel].img.size() == 0)
|
|
{
|
|
if (decoded_imgs[channel].img.size() != 0)
|
|
saveAll();
|
|
|
|
// logger->critical("%d %d %d", width, height, channel);
|
|
decoded_imgs[channel].img.init(8, width, height, 1);
|
|
last_timestamp = timestamp;
|
|
}
|
|
|
|
decoded_imgs[channel].img.draw_image(0, img, x_s, y_s);
|
|
decoded_imgs[channel].is_dling = true;
|
|
|
|
if (decoded_imgs[channel].textureID != 0)
|
|
{
|
|
auto imageScaled = decoded_imgs[channel].img;
|
|
imageScaled.resize(1000, 1000);
|
|
image::image_to_rgba(imageScaled, decoded_imgs[channel].textureBuffer);
|
|
decoded_imgs[channel].hasToUpdate = true;
|
|
}
|
|
}
|
|
|
|
void saveAll(int channel = -1)
|
|
{
|
|
std::string dirpath = directory + "/" +
|
|
satdump::timestamp_to_string(last_timestamp); //+std::to_string(last_timestamp);
|
|
|
|
if (!std::filesystem::exists(dirpath))
|
|
std::filesystem::create_directories(dirpath);
|
|
|
|
if (channel == -1)
|
|
{
|
|
for (auto &ch : decoded_imgs)
|
|
{
|
|
std::string path = dirpath +
|
|
"/" +
|
|
std::to_string(ch.first);
|
|
|
|
if (decoded_imgs[ch.first].is_dling)
|
|
image::save_img(decoded_imgs[ch.first].img, path);
|
|
decoded_imgs[ch.first].is_dling = false;
|
|
}
|
|
}
|
|
else if (decoded_imgs.count(channel) > 0)
|
|
{
|
|
std::string path = dirpath +
|
|
"/" +
|
|
std::to_string(channel);
|
|
|
|
image::save_img(decoded_imgs[channel].img, path);
|
|
decoded_imgs[channel].is_dling = false;
|
|
decoded_imgs[channel].img.fill(0);
|
|
}
|
|
}
|
|
};
|
|
}
|