Add arg parsing
This commit is contained in:
parent
af7b28f794
commit
07d931126f
7 changed files with 163 additions and 13 deletions
|
@ -3,6 +3,7 @@ project(EN605.617.81.FA21_StephenSeo_DitheringProject)
|
||||||
|
|
||||||
set(Project_SOURCES
|
set(Project_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
|
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/arg_parse.cc
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/image.cc
|
${CMAKE_CURRENT_SOURCE_DIR}/src/image.cc
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/video.cc
|
${CMAKE_CURRENT_SOURCE_DIR}/src/video.cc
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/opencl_handle.cc
|
${CMAKE_CURRENT_SOURCE_DIR}/src/opencl_handle.cc
|
||||||
|
|
69
src/arg_parse.cc
Normal file
69
src/arg_parse.cc
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#include "arg_parse.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
Args::Args()
|
||||||
|
: do_dither_image_(true),
|
||||||
|
do_dither_grayscaled_(false),
|
||||||
|
do_overwrite_(false),
|
||||||
|
input_filename(),
|
||||||
|
output_filename() {}
|
||||||
|
|
||||||
|
void Args::PrintUsage() {
|
||||||
|
std::cout
|
||||||
|
<< "Usage: [-h | --help] [-i <filename> | --input <filename>] [-o "
|
||||||
|
"<filename> | --output <filename>] [-b <filename> | --blue "
|
||||||
|
"<filename>] [-g | --gray] [--image] [--video] [--overwrite]\n"
|
||||||
|
" -h | --help\t\t\t\tPrint this usage text\n"
|
||||||
|
" -i <filename> | --input <filename>\tSet input filename\n"
|
||||||
|
" -o <filename> | --output <filename>\tSet output filename\n"
|
||||||
|
" -b <filename> | --blue <filename>\tSet input blue_noise filename\n"
|
||||||
|
" -g | --gray\t\t\t\tDither output in grayscale\n"
|
||||||
|
" --image\t\t\t\tDither a single image\n"
|
||||||
|
" --video\t\t\t\tDither frames in a video\n"
|
||||||
|
" --overwrite\t\t\t\tAllow overwriting existing files\n"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Args::ParseArgs(int argc, char **argv) {
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
|
while (argc > 0) {
|
||||||
|
if (std::strcmp(argv[0], "-h") == 0 ||
|
||||||
|
std::strcmp(argv[0], "--help") == 0) {
|
||||||
|
PrintUsage();
|
||||||
|
return true;
|
||||||
|
} else if (argc > 1 && (std::strcmp(argv[0], "-i") == 0 ||
|
||||||
|
std::strcmp(argv[0], "--input") == 0)) {
|
||||||
|
input_filename = std::string(argv[1]);
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
|
} else if (argc > 1 && (std::strcmp(argv[0], "-o") == 0 ||
|
||||||
|
std::strcmp(argv[0], "--output") == 0)) {
|
||||||
|
output_filename = std::string(argv[1]);
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
|
} else if (argc > 1 && (std::strcmp(argv[0], "-b") == 0 ||
|
||||||
|
std::strcmp(argv[0], "--blue") == 0)) {
|
||||||
|
blue_noise_filename = std::string(argv[1]);
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
|
} else if (std::strcmp(argv[0], "-g") == 0 ||
|
||||||
|
std::strcmp(argv[0], "--gray") == 0) {
|
||||||
|
do_dither_grayscaled_ = true;
|
||||||
|
} else if (std::strcmp(argv[0], "--image") == 0) {
|
||||||
|
do_dither_image_ = true;
|
||||||
|
} else if (std::strcmp(argv[0], "--video") == 0) {
|
||||||
|
do_dither_image_ = false;
|
||||||
|
} else if (std::strcmp(argv[0], "--overwrite") == 0) {
|
||||||
|
do_overwrite_ = true;
|
||||||
|
} else {
|
||||||
|
std::cout << "WARNING: Ignoring invalid input \"" << argv[0] << '"'
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
22
src/arg_parse.h
Normal file
22
src/arg_parse.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef IGPUP_DITHERING_PROJECT_ARG_PARSE_
|
||||||
|
#define IGPUP_DITHERING_PROJECT_ARG_PARSE_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct Args {
|
||||||
|
Args();
|
||||||
|
|
||||||
|
static void PrintUsage();
|
||||||
|
|
||||||
|
/// Returns true if help was printed
|
||||||
|
bool ParseArgs(int argc, char **argv);
|
||||||
|
|
||||||
|
bool do_dither_image_;
|
||||||
|
bool do_dither_grayscaled_;
|
||||||
|
bool do_overwrite_;
|
||||||
|
std::string input_filename;
|
||||||
|
std::string output_filename;
|
||||||
|
std::string blue_noise_filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -64,7 +64,11 @@ Image::Image(const std::string &filename)
|
||||||
is_dithered_grayscale_(false),
|
is_dithered_grayscale_(false),
|
||||||
is_dithered_color_(false),
|
is_dithered_color_(false),
|
||||||
is_preserving_blue_noise_offsets_(true) {
|
is_preserving_blue_noise_offsets_(true) {
|
||||||
if (filename.compare(filename.size() - 4, filename.size(), ".png") == 0) {
|
if (filename.empty()) {
|
||||||
|
std::cout << "ERROR: Image got empty filename string" << std::endl;
|
||||||
|
return;
|
||||||
|
} else if (filename.compare(filename.size() - 4, filename.size(), ".png") ==
|
||||||
|
0) {
|
||||||
// filename expected to be .png
|
// filename expected to be .png
|
||||||
std::cout << "INFO: PNG filename extension detected, decoding..."
|
std::cout << "INFO: PNG filename extension detected, decoding..."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
67
src/main.cc
67
src/main.cc
|
@ -1,18 +1,71 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "arg_parse.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
Image blue_noise("bluenoise.png");
|
Args args{};
|
||||||
if (!blue_noise.IsValid()) {
|
if (args.ParseArgs(argc, argv)) {
|
||||||
std::cout << "ERROR: Invalid bluenoise.png" << std::endl;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image blue_noise(args.blue_noise_filename);
|
||||||
|
if (!blue_noise.IsValid() || !blue_noise.IsGrayscale()) {
|
||||||
|
std::cout << "ERROR: Invalid blue noise file \"" << args.blue_noise_filename
|
||||||
|
<< '"' << std::endl;
|
||||||
|
Args::PrintUsage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
Video video("input.mp4");
|
|
||||||
if (!video.DitherVideo("output.mp4", &blue_noise, false)) {
|
if (args.do_dither_image_) {
|
||||||
std::cout << "ERROR: Failed to dither video" << std::endl;
|
Image input_image(args.input_filename);
|
||||||
return 1;
|
if (!input_image.IsValid()) {
|
||||||
|
std::cout << "ERROR: Invalid input image file \"" << args.input_filename
|
||||||
|
<< '"' << std::endl;
|
||||||
|
Args::PrintUsage();
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.do_dither_grayscaled_) {
|
||||||
|
auto output_image =
|
||||||
|
input_image.ToGrayscaleDitheredWithBlueNoise(&blue_noise);
|
||||||
|
if (!output_image) {
|
||||||
|
std::cout << "ERROR: Failed to dither input image \""
|
||||||
|
<< args.input_filename << '"' << std::endl;
|
||||||
|
Args::PrintUsage();
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if (!output_image->SaveAsPNG(args.output_filename, args.do_overwrite_)) {
|
||||||
|
std::cout << "ERROR: Failed to saved dithered image from input \""
|
||||||
|
<< args.input_filename << '"' << std::endl;
|
||||||
|
Args::PrintUsage();
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto output_image = input_image.ToColorDitheredWithBlueNoise(&blue_noise);
|
||||||
|
if (!output_image) {
|
||||||
|
std::cout << "ERROR: Failed to dither input image \""
|
||||||
|
<< args.input_filename << '"' << std::endl;
|
||||||
|
Args::PrintUsage();
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
if (!output_image->SaveAsPNG(args.output_filename, args.do_overwrite_)) {
|
||||||
|
std::cout << "ERROR: Failed to saved dithered image from input \""
|
||||||
|
<< args.input_filename << '"' << std::endl;
|
||||||
|
Args::PrintUsage();
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Video video(args.input_filename);
|
||||||
|
if (!video.DitherVideo(args.output_filename, &blue_noise,
|
||||||
|
args.do_dither_grayscaled_, args.do_overwrite_)) {
|
||||||
|
std::cout << "ERROR: Failed to dither frames from input video \""
|
||||||
|
<< args.input_filename << '"' << std::endl;
|
||||||
|
Args::PrintUsage();
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -25,12 +25,13 @@ Video::~Video() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Video::DitherVideo(const char *output_filename, Image *blue_noise,
|
bool Video::DitherVideo(const char *output_filename, Image *blue_noise,
|
||||||
bool grayscale) {
|
bool grayscale, bool overwrite) {
|
||||||
return DitherVideo(std::string(output_filename), blue_noise, grayscale);
|
return DitherVideo(std::string(output_filename), blue_noise, grayscale,
|
||||||
|
overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Video::DitherVideo(const std::string &output_filename, Image *blue_noise,
|
bool Video::DitherVideo(const std::string &output_filename, Image *blue_noise,
|
||||||
bool grayscale) {
|
bool grayscale, bool overwrite) {
|
||||||
// Get AVFormatContext for input file
|
// Get AVFormatContext for input file
|
||||||
AVFormatContext *avf_context = nullptr;
|
AVFormatContext *avf_context = nullptr;
|
||||||
std::string url = std::string("file:") + input_filename_;
|
std::string url = std::string("file:") + input_filename_;
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Video {
|
||||||
|
|
||||||
/// Same as DitherVideo(const std::string&, Image*, bool)
|
/// Same as DitherVideo(const std::string&, Image*, bool)
|
||||||
bool DitherVideo(const char *output_filename, Image *blue_noise,
|
bool DitherVideo(const char *output_filename, Image *blue_noise,
|
||||||
bool grayscale = false);
|
bool grayscale = false, bool overwrite = false);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Dithers the frames in the input video.
|
* \brief Dithers the frames in the input video.
|
||||||
|
@ -39,7 +39,7 @@ class Video {
|
||||||
* \return True on success.
|
* \return True on success.
|
||||||
*/
|
*/
|
||||||
bool DitherVideo(const std::string &output_filename, Image *blue_noise,
|
bool DitherVideo(const std::string &output_filename, Image *blue_noise,
|
||||||
bool grayscale = false);
|
bool grayscale = false, bool overwrite = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Image image_;
|
Image image_;
|
||||||
|
|
Loading…
Reference in a new issue