satdump/plugins/goes_support/goes/sd/sd_imager_reader.cpp

199 lines
8.3 KiB
C++
Raw Permalink Normal View History

2023-03-09 02:48:06 +01:00
#include "sd_imager_reader.h"
2023-03-09 16:51:20 +01:00
#include "logger.h"
#include "common/utils.h"
#include <filesystem>
2023-05-08 23:08:34 +02:00
#include <cstring>
#include "image/io.h"
#include "image/processing.h"
2025-05-21 18:04:31 +02:00
#include <iostream>
2025-05-26 19:21:10 +01:00
#include "utils/stats.h"
2023-03-09 02:48:06 +01:00
#define IMG_WIDTH 40000
namespace goes
{
namespace sd
{
2023-03-09 16:51:20 +01:00
SDImagerReader::SDImagerReader()
{
2025-05-21 18:04:31 +02:00
memset(last_status, 0, FULL_BUF_SZ * sizeof(uint16_t));
2023-03-09 16:51:20 +01:00
}
2023-03-09 02:48:06 +01:00
void SDImagerReader::work(uint16_t *words)
{
2025-05-21 18:04:31 +02:00
uint16_t type = words[1] & 31;
2023-03-09 02:48:06 +01:00
2025-05-21 18:04:31 +02:00
memmove(last_status, &last_status[1], (FULL_BUF_SZ - 1) * sizeof(uint16_t));
2023-03-09 17:06:56 +01:00
last_status[FULL_BUF_SZ - 1] = type;
2023-03-09 16:51:20 +01:00
2025-05-26 19:21:10 +01:00
uint16_t last_types = satdump::most_common(&last_status[0], &last_status[FULL_BUF_SZ], 0);
2025-05-21 18:04:31 +02:00
//std::cout<<type<<std::endl;
2023-03-09 16:51:20 +01:00
if (last_types == 16 && images_lines > 10)
{
logger->critical("END OF FRAME");
images_lines = 0;
should_save = true;
}
else if (last_types == 16)
{
images_lines = 0;
}
2025-05-21 18:04:31 +02:00
if (type == 21 && last_types == 0)
2023-03-09 02:48:06 +01:00
{
image_vis.resize(size_t(lines + 1) * 8 * IMG_WIDTH);
image_ir1.resize(size_t(lines + 1) * 2 * IMG_WIDTH);
image_ir2.resize(size_t(lines + 1) * 2 * IMG_WIDTH);
image_ir3.resize(size_t(lines + 1) * 2 * IMG_WIDTH);
image_ir4.resize(size_t(lines + 1) * 2 * IMG_WIDTH);
bool is_shifted = ((words[3] >> 6) & 1);
2025-05-21 18:04:31 +02:00
int x = is_shifted ? ((20917 - 70 + 12 - 3 - 8 -7*4) / 4) : 0;
2023-03-09 02:48:06 +01:00
2023-08-06 17:22:09 +02:00
for (int y = 0; y < (int)wip_scanline.size() / 48; y++)
2023-03-09 02:48:06 +01:00
{
uint16_t *block = &wip_scanline[y * 48];
if (!is_shifted)
{
2025-05-21 18:05:39 +02:00
2023-03-09 02:48:06 +01:00
for (int b = 0; b < 4; b++)
{
image_vis[size_t(lines * 8 + 0) * IMG_WIDTH + (x * 4 + b)] = block[b * 12 + 9] << 6;
image_vis[size_t(lines * 8 + 1) * IMG_WIDTH + (x * 4 + b)] = block[b * 12 + 8] << 6;
image_vis[size_t(lines * 8 + 2) * IMG_WIDTH + (x * 4 + b)] = block[b * 12 + 7] << 6;
image_vis[size_t(lines * 8 + 3) * IMG_WIDTH + (x * 4 + b)] = block[b * 12 + 6] << 6;
image_vis[size_t(lines * 8 + 4) * IMG_WIDTH + (x * 4 + b)] = block[b * 12 + 5] << 6;
image_vis[size_t(lines * 8 + 5) * IMG_WIDTH + (x * 4 + b)] = block[b * 12 + 4] << 6;
image_vis[size_t(lines * 8 + 6) * IMG_WIDTH + (x * 4 + b)] = block[b * 12 + 3] << 6;
image_vis[size_t(lines * 8 + 7) * IMG_WIDTH + (x * 4 + b)] = block[b * 12 + 2] << 6;
}
2025-05-21 18:05:39 +02:00
2023-03-09 02:48:06 +01:00
2025-05-21 18:04:31 +02:00
image_ir1[size_t(lines * 2 + 1) * IMG_WIDTH + x] = 65535 - (block[0 * 12 + 10] << 6);
image_ir1[size_t(lines * 2 + 0) * IMG_WIDTH + x] = 65535 - (block[0 * 12 + 11] << 6);
2023-03-09 02:48:06 +01:00
2025-05-21 18:04:31 +02:00
image_ir2[size_t(lines * 2 + 1) * IMG_WIDTH + x] = 65535 - (block[1 * 12 + 10] << 6);
image_ir2[size_t(lines * 2 + 0) * IMG_WIDTH + x] = 65535 - (block[1 * 12 + 11] << 6);
2023-03-09 02:48:06 +01:00
2025-05-21 18:04:31 +02:00
image_ir3[size_t(lines * 2 + 1) * IMG_WIDTH + x] = 65535 - (block[2 * 12 + 10] << 6);
image_ir3[size_t(lines * 2 + 0) * IMG_WIDTH + x] = 65535 - (block[2 * 12 + 11] << 6);
2023-03-09 02:48:06 +01:00
image_ir4[size_t(lines * 2 + 1) * IMG_WIDTH + x] = 65535 - (block[3 * 12 + 10] << 6);
2025-05-21 18:04:31 +02:00
image_ir4[size_t(lines * 2 + 0) * IMG_WIDTH + x] = 65535 - (block[3 * 12 + 10] << 6);
2023-03-09 02:48:06 +01:00
}
else
{
2025-05-21 18:05:39 +02:00
2023-03-09 02:48:06 +01:00
for (int b = 0; b < 4; b++)
{
image_vis[size_t(lines * 8 + 0) * IMG_WIDTH + (x * 4 + 3 - b)] = block[b * 12 + 9] << 6;
image_vis[size_t(lines * 8 + 1) * IMG_WIDTH + (x * 4 + 3 - b)] = block[b * 12 + 8] << 6;
image_vis[size_t(lines * 8 + 2) * IMG_WIDTH + (x * 4 + 3 - b)] = block[b * 12 + 7] << 6;
image_vis[size_t(lines * 8 + 3) * IMG_WIDTH + (x * 4 + 3 - b)] = block[b * 12 + 6] << 6;
image_vis[size_t(lines * 8 + 4) * IMG_WIDTH + (x * 4 + 3 - b)] = block[b * 12 + 5] << 6;
image_vis[size_t(lines * 8 + 5) * IMG_WIDTH + (x * 4 + 3 - b)] = block[b * 12 + 4] << 6;
image_vis[size_t(lines * 8 + 6) * IMG_WIDTH + (x * 4 + 3 - b)] = block[b * 12 + 3] << 6;
image_vis[size_t(lines * 8 + 7) * IMG_WIDTH + (x * 4 + 3 - b)] = block[b * 12 + 2] << 6;
}
2025-05-21 18:05:39 +02:00
2023-03-09 02:48:06 +01:00
2025-05-21 18:04:31 +02:00
image_ir1[size_t(lines * 2 + 1) * IMG_WIDTH + x] = 65535 - (block[0 * 12 + 10] << 6);
image_ir1[size_t(lines * 2 + 0) * IMG_WIDTH + x] = 65535 - (block[0 * 12 + 11] << 6);
2023-03-09 02:48:06 +01:00
2025-05-21 18:04:31 +02:00
image_ir2[size_t(lines * 2 + 1) * IMG_WIDTH + x] = 65535 - (block[1 * 12 + 10] << 6);
image_ir2[size_t(lines * 2 + 0) * IMG_WIDTH + x] = 65535 - (block[1 * 12 + 11] << 6);
2023-03-09 02:48:06 +01:00
2025-05-21 18:04:31 +02:00
image_ir3[size_t(lines * 2 + 1) * IMG_WIDTH + x] = 65535 - (block[2 * 12 + 10] << 6);
image_ir3[size_t(lines * 2 + 0) * IMG_WIDTH + x] = 65535 - (block[2 * 12 + 11] << 6);
2023-03-09 02:48:06 +01:00
image_ir4[size_t(lines * 2 + 1) * IMG_WIDTH + x] = 65535 - (block[3 * 12 + 10] << 6);
2025-05-21 18:04:31 +02:00
image_ir4[size_t(lines * 2 + 0) * IMG_WIDTH + x] = 65535 - (block[3 * 12 + 10] << 6);
2023-03-09 02:48:06 +01:00
}
if (is_shifted)
x--;
else
x++;
if (x < 0)
x = 0;
}
lines++;
2023-03-09 16:51:20 +01:00
images_lines++;
2023-03-09 02:48:06 +01:00
wip_scanline.clear();
2023-03-09 17:12:32 +01:00
2025-05-21 18:04:31 +02:00
//logger->info("Lines %d", lines);
2023-03-09 02:48:06 +01:00
}
2025-05-21 18:04:31 +02:00
if (last_types == 26)
wip_scanline.insert(wip_scanline.end(), &words[0], &words[48]);
2023-03-09 02:48:06 +01:00
}
2024-05-09 01:16:08 +02:00
image::Image SDImagerReader::getChannel(int c)
2023-03-09 02:48:06 +01:00
{
2024-05-09 01:16:08 +02:00
image::Image img;
2023-03-09 02:48:06 +01:00
if (c == 0)
2024-05-09 01:16:08 +02:00
img = image::Image(image_vis.data(), 16, IMG_WIDTH, lines * 8, 1);
2023-03-09 02:48:06 +01:00
else if (c == 1)
2024-05-09 01:16:08 +02:00
img = image::Image(image_ir1.data(), 16, IMG_WIDTH, lines * 2, 1);
2023-03-09 02:48:06 +01:00
else if (c == 2)
2024-05-09 01:16:08 +02:00
img = image::Image(image_ir2.data(), 16, IMG_WIDTH, lines * 2, 1);
2023-03-09 02:48:06 +01:00
else if (c == 3)
2024-05-09 01:16:08 +02:00
img = image::Image(image_ir3.data(), 16, IMG_WIDTH, lines * 2, 1);
2023-03-09 02:48:06 +01:00
else if (c == 4)
2024-05-09 01:16:08 +02:00
img = image::Image(image_ir4.data(), 16, IMG_WIDTH, lines * 2, 1);
2023-03-09 02:48:06 +01:00
if (c == 0)
img.crop(0, 21072);
else
img.crop(0, 21072 / 4);
2025-05-21 18:04:31 +02:00
//image::median_blur(img);
2023-03-09 02:48:06 +01:00
2025-05-21 18:04:31 +02:00
//img.resize_bilinear(img.width(), img.height() * 1.75);
2023-03-09 02:48:06 +01:00
2023-03-09 17:06:56 +01:00
// img.mirror(true, false);
2023-03-09 02:48:06 +01:00
return img;
}
2023-03-09 16:51:20 +01:00
void SDImagerReader::try_save(std::string directory, bool force)
{
if (should_save || force)
{
nsaved++;
std::string dir = directory + "/" + std::to_string(nsaved) + "/";
if (!std::filesystem::exists(dir))
std::filesystem::create_directories(dir);
2024-05-09 01:16:08 +02:00
auto img = getChannel(0);
image::save_img(img, dir + "/VIS", false);
img = getChannel(1);
image::save_img(img, dir + "/IR1", false);
img = getChannel(2);
image::save_img(img, dir + "/IR2", false);
img = getChannel(3);
image::save_img(img, dir + "/IR3", false);
img = getChannel(4);
image::save_img(img, dir + "/IR4", false);
img.clear();
2023-03-09 16:51:20 +01:00
lines = 0;
image_vis.clear();
image_ir1.clear();
image_ir2.clear();
image_ir3.clear();
image_ir4.clear();
should_save = false;
}
}
2023-03-09 02:48:06 +01:00
}
}