1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause
#ifndef LIBAVIF_APPS_AVIFGAINMAPUTIL_PROGRAM_COMMAND_H_
#define LIBAVIF_APPS_AVIFGAINMAPUTIL_PROGRAM_COMMAND_H_
#include <string>
#include "argparse.hpp"
#include "avif/avif.h"
namespace avif {
// A command that can be invoked by name (similar to how 'git' has commands like
// 'commit', 'checkout', etc.)
// NOTE: "avifgainmaputil" is currently hardcoded in the implementation (for
// help messages).
class ProgramCommand {
public:
// 'name' is the command that should be used to invoke the command on the
// command line.
// 'description' should be a one line description of what the command does.
ProgramCommand(const std::string& name, const std::string& description);
virtual ~ProgramCommand() = default;
// Parses command line arguments. Should be called before Run().
avifResult ParseArgs(int argc, const char* const argv[]);
// Runs the command.
virtual avifResult Run() = 0;
std::string name() const { return name_; }
std::string description() const { return description_; }
// Prints this command's help on stdout.
void PrintUsage();
protected:
argparse::ArgumentParser argparse_;
private:
std::string name_;
std::string description_;
};
//------------------------------------------------------------------------------
// Utilities for flag parsing.
// avifPixelFormat converter for use with argparse.
// Actually converts to int, converting to avifPixelFormat didn't seem to
// compile.
struct PixelFormatConverter {
// Methods expected by argparse.
argparse::ConvertedValue<int> from_str(const std::string& str);
std::vector<std::string> default_choices();
};
struct CicpValues {
avifColorPrimaries color_primaries;
avifTransferCharacteristics transfer_characteristics;
avifMatrixCoefficients matrix_coefficients;
};
// CicpValues converter for use with argparse.
struct CicpConverter {
// Methods expected by argparse.
argparse::ConvertedValue<CicpValues> from_str(const std::string& str);
std::vector<std::string> default_choices();
};
// Basic flags for image writing.
struct BasicImageEncodeArgs {
argparse::ArgValue<int> speed;
argparse::ArgValue<int> quality;
argparse::ArgValue<int> quality_alpha;
// can_have_alpha should be true if the image can have alpha and the
// output format can be avif.
void Init(argparse::ArgumentParser& argparse, bool can_have_alpha) {
argparse.add_argument(speed, "--speed", "-s")
.help("Encoder speed (0-10, slowest-fastest)")
.default_value("6");
argparse.add_argument(quality, "--qcolor", "-q")
.help((can_have_alpha
? "Quality for color (0-100, where 100 is lossless)"
: "Quality (0-100, where 100 is lossless)"))
.default_value("60");
if (can_have_alpha) {
argparse.add_argument(quality_alpha, "--qalpha")
.help("Quality for alpha (0-100, where 100 is lossless)")
.default_value("100");
}
}
};
// Flags relevant when reading jpeg/png.
struct ImageReadArgs {
argparse::ArgValue<int> depth;
argparse::ArgValue<int> pixel_format;
argparse::ArgValue<bool> ignore_profile;
void Init(argparse::ArgumentParser& argparse) {
argparse
.add_argument<int, PixelFormatConverter>(pixel_format, "--yuv", "-y")
.help("Output YUV format for avif (default = automatic)");
argparse.add_argument(depth, "--depth", "-d")
.choices({"0", "8", "10", "12"})
.help("Output depth (0 = automatic)");
argparse.add_argument(ignore_profile, "--ignore-profile")
.help(
"If the input file contains an embedded color profile, ignore it "
"(no-op if absent)")
.action(argparse::Action::STORE_TRUE)
.default_value("false");
}
};
// Helper to parse flags that contain several delimited values.
template <typename T>
bool ParseList(std::string to_parse, char delim, int expected_num,
std::vector<T>* out) {
std::stringstream ss(to_parse);
std::string part;
T parsed;
while (std::getline(ss, part, delim)) {
std::istringstream is(part);
is >> parsed;
if (is.bad()) {
return false;
}
out->push_back(parsed);
}
if (expected_num > 0 && (int)out->size() != expected_num) {
return false;
}
return true;
}
} // namespace avif
#endif // LIBAVIF_APPS_AVIFGAINMAPUTIL_PROGRAM_COMMAND_H_
|