blob: 08d2d085543480c6e732309d944353af0f82b0e1 [file] [log] [blame]
// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause
#include <iomanip>
#include <string>
#include <vector>
#include "argparse.hpp"
#include "avif/avif.h"
#include "avifutil.h"
#include "combine_command.h"
#include "convert_command.h"
#include "extractgainmap_command.h"
#include "printmetadata_command.h"
#include "program_command.h"
#include "swapbase_command.h"
#include "tonemap_command.h"
namespace avif {
namespace {
class HelpCommand : public ProgramCommand {
public:
HelpCommand() : ProgramCommand("help", "Prints a command's usage") {}
avifResult Run() override {
// Actual implementation is in the main function because it needs access
// to the list of commands.
return AVIF_RESULT_OK;
}
};
void PrintUsage(const std::vector<std::unique_ptr<ProgramCommand>>& commands) {
std::cout << "\nExperimental tool to manipulate avif images with HDR gain "
"maps.\n\n";
std::cout << "usage: avifgainmaputil <command> [options] [arguments...]\n\n";
std::cout << "Available commands:\n";
int longest_command_size = 0;
for (const std::unique_ptr<ProgramCommand>& command : commands) {
longest_command_size = std::max(longest_command_size,
static_cast<int>(command->name().size()));
}
for (const std::unique_ptr<ProgramCommand>& command : commands) {
std::cout << " " << std::left << std::setw(longest_command_size)
<< command->name() << " " << command->description() << "\n";
}
std::cout << "\n";
avifPrintVersions();
}
} // namespace
} // namespace avif
int main(int argc, char** argv) {
std::vector<std::unique_ptr<avif::ProgramCommand>> commands;
commands.emplace_back(std::make_unique<avif::HelpCommand>());
commands.emplace_back(std::make_unique<avif::CombineCommand>());
commands.emplace_back(std::make_unique<avif::ConvertCommand>());
commands.emplace_back(std::make_unique<avif::TonemapCommand>());
commands.emplace_back(std::make_unique<avif::SwapBaseCommand>());
commands.emplace_back(std::make_unique<avif::ExtractGainMapCommand>());
commands.emplace_back(std::make_unique<avif::PrintMetadataCommand>());
if (argc < 2) {
std::cerr << "Command name missing\n";
avif::PrintUsage(commands);
return 1;
}
const std::string command_name(argv[1]);
if (command_name == "help") {
if (argc >= 3) {
const std::string sub_command_name(argv[2]);
for (const auto& command : commands) {
if (command->name() == sub_command_name) {
command->PrintUsage();
return 0;
}
}
std::cerr << "Unknown command " << sub_command_name << "\n";
avif::PrintUsage(commands);
return 1;
} else {
avif::PrintUsage(commands);
return 0;
}
}
for (const auto& command : commands) {
if (command->name() == command_name) {
try {
avifResult result = command->ParseArgs(argc - 1, argv + 1);
if (result == AVIF_RESULT_OK) {
result = command->Run();
}
if (result == AVIF_RESULT_INVALID_ARGUMENT) {
command->PrintUsage();
}
return (result == AVIF_RESULT_OK) ? 0 : 1;
} catch (const std::invalid_argument& e) {
std::cerr << e.what() << "\n\n";
command->PrintUsage();
return 1;
}
}
}
std::cerr << "Unknown command " << command_name << "\n";
avif::PrintUsage(commands);
return 1;
}