#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 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(); msg::SegmentIdentificationHeader segment_id_header = file.getHeader(); 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(); 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