#include "application.h" #include "output_util.h" #include "filepath_util.h" #include #include #include #include ///////////////////////////////////////////////////////////////////////// static constexpr int NO_ARGC = 1; static constexpr int MIN_ARGC = 2; static constexpr int MAX_ARGC = 4; static constexpr int DEFAULT_SPLITTING = 5; static const std::string DEFAULT_PATH = "."; // current folder, I guess ///////////////////////////////////////////////////////////////////////// static std::tuple error(const char* msg) { std::cout << msg; return {EXIT_FAILURE, -1, {}}; } static std::tuple parsePath(const std::string &argv) { std::filesystem::path path(argv); if (!std::filesystem::exists(path)) { std::cout << "Path " << path << " does not exist.\n"; return {EXIT_FAILURE, {}}; } // Maybe user chose a specific image, not a folder if (std::filesystem::is_regular_file(path)) return {EXIT_SUCCESS, path.string()}; // So... it is a folder // Creating a vector of everything in the given directory std::vector> dir_items; std::transform(std::filesystem::directory_iterator(path), {}, std::back_inserter(dir_items), filepath::getFileInfo); std::set allowed_ext = {".bmp", ".dds", ".jpg", ".png", ".tga", ".psd"}; // Now getting images std::vector dir_image_items; for (const auto &[local_path, status] : dir_items) { const std::string str_path = local_path.string(); if (std::filesystem::is_regular_file(local_path) && std::any_of(allowed_ext.begin(), allowed_ext.end(), [&](const std::string& e) { return filepath::endsWith(str_path, e); })) { dir_image_items.emplace_back(str_path); } } if (dir_image_items.empty()) { std::cout << "No images found at " << path << "\n --help for more information.\n"; return {EXIT_FAILURE, {}}; } std::cout << "Loading random image file from " << path << "\n"; srand(static_cast(time(nullptr))); return {EXIT_SUCCESS, dir_image_items[rand() & (dir_image_items.size() - 1)]}; } static std::tuple parseInput(int argc, char **argv) { int splitting = DEFAULT_SPLITTING; std::string path = DEFAULT_PATH; switch (argc) { default: return error(output::NO_ARG_MSG); case NO_ARGC: { // Just launch the application with default parameters std::cout << "No arguments given. Launching at \"" + DEFAULT_PATH + "\" with splitting " + std::to_string(DEFAULT_SPLITTING) + "\n"; const auto &[ret_code, ret_path] = parsePath(DEFAULT_PATH); if (ret_code) return error(output::IMG_FAIL_MSG); path = ret_path; break; } case MIN_ARGC: { // maybe --help if (strcmp(argv[1], output::HELP_FLAG) == 0) return error(output::HELP_MSG); const auto &[ret_code, ret_path] = parsePath(argv[1]); if (ret_code) return error(output::IMG_FAIL_MSG); path = ret_path; break; } case (MAX_ARGC - 1): case MAX_ARGC: { // full stack if (strcmp(argv[1], output::SPLITTING_FLAG) == 0) { if (std::isdigit(*argv[2])) splitting = std::stoi(argv[2]); if (splitting < 1) return error(output::SPLITTING_MSG); const auto &[ret_code, ret_path] = parsePath(argv[3]); if (ret_code) return error(output::IMG_FAIL_MSG); path = ret_path; } break; } } return {EXIT_SUCCESS, splitting, path}; } ///////////////////////////////////////////////////////////////////////// int main(int argc, char **argv) { const auto&[ret_code, splitting, path] = parseInput(argc, argv); if (ret_code) // Error code is EXIT_FAILURE return ret_code; Application app; if (app.init(path, splitting)) { app.run(); return EXIT_SUCCESS; } return EXIT_FAILURE; }