satdump/plugins/xrit_support/xrit/msg/segment_decoder.h
2025-07-29 17:03:11 +01:00

97 lines
No EOL
3.3 KiB
C++

#pragma once
/**
* @file segment_decoder.h
* @brief MSG/ELEKTRO Segmented decoder
*/
#include "../segment_decoder.h"
#include "image/image.h"
#include "msg_headers.h"
#include "xrit/identify.h"
#include "xrit/processor/get_img.h"
#include "xrit/xrit_file.h"
namespace satdump
{
namespace xrit
{
/**
* @brief MSG/ELEKTRO-specific Segmented Decoder
*/
class MSGSegmentedImageDecoder : public SegmentedImageDecoder
{
private:
int seg_count = 0;
std::vector<bool> segments_done;
int seg_height = 0, seg_width = 0;
public:
void init(int bit_depth, int max_seg, int segment_width, int segment_height)
{
seg_count = max_seg;
segments_done.resize(seg_count, false);
image = image::Image(bit_depth, segment_width, segment_height * max_seg, 1);
seg_height = segment_height;
seg_width = segment_width;
image.fill(0);
}
MSGSegmentedImageDecoder(XRITFile &file)
{
ImageStructureRecord image_structure_record = file.getHeader<ImageStructureRecord>();
msg::SegmentIdentificationHeader segment_id_header = file.getHeader<msg::SegmentIdentificationHeader>();
init(image_structure_record.bit_per_pixel > 8 ? 16 : 8, //
segment_id_header.planned_end_segment - segment_id_header.planned_start_segment + 1, //
image_structure_record.columns_count, //
image_structure_record.lines_count);
}
void pushSegment(image::Image &data, int segc)
{
if (segc >= seg_count || segc < 0)
return;
if (data.size() != seg_height * seg_width)
{
logger->error("Image of the wrong size!");
return;
}
image::imemcpy(image, (seg_height * seg_width) * segc, data, 0, seg_height * seg_width);
segments_done[segc] = true;
}
void pushSegment(XRITFile &file)
{
msg::SegmentIdentificationHeader segment_id_header = file.getHeader<msg::SegmentIdentificationHeader>();
auto img = getImageFromXRITFile(XRIT_MSG_SEVIRI, file);
pushSegment(img, segment_id_header.segment_sequence_number - segment_id_header.planned_start_segment);
}
bool isComplete()
{
bool complete = true;
for (int i = 0; i < seg_count; i++)
complete = complete && segments_done[i];
return complete;
}
void reset()
{
for (int i = 0; i < seg_count; i++)
segments_done[i] = false;
image.clear();
}
bool hasData()
{
for (int i = 0; i < seg_count; i++)
if (segments_done[i])
return true;
return false;
}
};
} // namespace xrit
} // namespace satdump