#include "logger.h" #include "init.h" #include "project.h" #include "common/cli_utils.h" #include "image/image.h" #include "common/projection/reprojector.h" #include "core/resources.h" #include "image/image_utils.h" #include "common/overlay_handler.h" #include "common/projection/reprojector_backend_utils.h" bool isFlag(std::string flag) { if (flag[0] == '-' && flag[1] != '-') { flag = flag.substr(1, flag.length()); if (flag == "layer" || flag == "target") return true; } return false; } int main_project(int argc, char *argv[]) { // We don't wanna spam with init this time around logger->set_level(slog::LOG_ERROR); satdump::initSatDump(); completeLoggerInit(); logger->set_level(slog::LOG_TRACE); logger->info("Starting projection tool..."); std::deque projection_layers; nlohmann::json target_cfg; int projections_image_width = 0, projections_image_height = 0; for (int i = 0; i < argc; i++) { // logger->debug(argv[i]); if (i != argc) { std::string flag = argv[i]; if (isFlag(flag)) // Detect a flag { flag = flag.substr(1, flag.length()); // Remove the "--" // logger->trace(flag); int end = 0; for (int ii = i + 1; ii < argc; ii++) { end = ii; std::string flag2 = argv[ii]; if (isFlag(flag2)) // Detect a flag break; } // for (int xi = 0; xi < end; xi++) // logger->trace((argv + i + 1)[xi]); // logger->error(end - i); auto params = parse_common_flags(end - i, argv + i + 1); // logger->trace("\n" + params.dump(4)); if (flag == "layer") { logger->info("Loading layer..."); satdump::ProjectionLayer newlayer = satdump::loadExternalLayer((satdump::LayerLoadingConfig)params); if (params.contains("opacity")) newlayer.opacity = params["opacity"]; if (params.contains("old_algo")) newlayer.opacity = params["old_algo"]; projection_layers.push_back(newlayer); } else if (flag == "target") { target_cfg = params; if (params.contains("width")) projections_image_width = params["width"]; if (params.contains("height")) projections_image_height = params["height"]; } else { throw satdump_exception("Invalid tag. Must be -layer or -target!"); } } } } //////////////////////////////////////////////////////////////////// bool projection_auto_mode = target_cfg.contains("auto_mode") ? target_cfg["auto_mode"].get() : false; bool projection_auto_scale_mode = target_cfg.contains("auto_scale_mode") ? target_cfg["auto_scale_mode"].get() : false; satdump::applyAutomaticProjectionSettings(projection_layers, projection_auto_mode, projection_auto_scale_mode, projections_image_width, projections_image_height, target_cfg); //////////////////////////////////////////////////////////////////// // Generate all layers std::vector layers_images = satdump::generateAllProjectionLayers(projection_layers, projections_image_width, projections_image_height, target_cfg); //////////////////////////////////////////////////////////////////// // Setup final image image::Image projected_image_result; projected_image_result.init(16, projections_image_width, projections_image_height, 3); // TODOIMG ALLOW MORE THAN 16 logger->info("Combining images..."); if (target_cfg.contains("blend_mode") ? target_cfg["blend_mode"].get() : false) // Blend { projected_image_result = image::blend_images(layers_images); } else { projected_image_result = layers_images[0]; for (int i = 1; i < (int)layers_images.size(); i++) { projected_image_result = image::merge_images_opacity(projected_image_result, layers_images[i], projection_layers[(projection_layers.size() - 1) - i].opacity / 100.0f); } } //////////////////////////////////////////////////////////////////// OverlayHandler projection_overlay_handler; projection_overlay_handler.set_config(target_cfg); if (projection_overlay_handler.enabled()) { auto proj_func = satdump::reprojection::setupProjectionFunction(projections_image_width, projections_image_height, target_cfg, {}); projection_overlay_handler.clear_cache(); projection_overlay_handler.apply(projected_image_result, proj_func, nullptr); } //////////////////////////////////////////////////////////////////// image::save_img(projected_image_result, target_cfg["file"]); satdump::exitSatDump(); return 0; }