summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build11
-rw-r--r--src/dump_image.cc90
2 files changed, 100 insertions, 1 deletions
diff --git a/meson.build b/meson.build
index 7470152..1e6b268 100644
--- a/meson.build
+++ b/meson.build
@@ -288,7 +288,16 @@ executable(
'src/static_files.hh',
],
dependencies: [args_dep, config_dep, inet_dep, logger_dep, server_dep,
- travel_dep])
+ travel_dep],
+ install: true)
+
+executable(
+ 'dump-image',
+ sources: [
+ 'src/dump_image.cc',
+ ],
+ dependencies: [args_dep, image_dep],
+ install: false)
gtest_dep = dependency(
'gtest',
diff --git a/src/dump_image.cc b/src/dump_image.cc
new file mode 100644
index 0000000..2c425e0
--- /dev/null
+++ b/src/dump_image.cc
@@ -0,0 +1,90 @@
+#include "common.hh"
+
+#include "args.hh"
+#include "image.hh"
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace {
+
+std::ostream& operator<<(std::ostream& out, Location const& loc) {
+ if (loc.empty()) {
+ return out << "none";
+ }
+ return out << loc.lat << ' ' << loc.lng;
+}
+
+std::ostream& operator<<(std::ostream& out, Rotation const& rot) {
+ switch (rot) {
+ case Rotation::UNKNOWN:
+ break;
+ case Rotation::NONE:
+ return out << "None";
+ case Rotation::MIRRORED:
+ return out << "Mirrored";
+ case Rotation::ROTATED_180:
+ return out << "Rotated 180";
+ case Rotation::ROTATED_180_MIRRORED:
+ return out << "Rotated 180 Mirrored";
+ case Rotation::ROTATED_90:
+ return out << "Rotated 90";
+ case Rotation::ROTATED_90_MIRRORED:
+ return out << "Rotated 90 Mirrored";
+ case Rotation::ROTATED_270:
+ return out << "Rotated 270";
+ case Rotation::ROTATED_270_MIRRORED:
+ return out << "Rotated 270 Mirrored";
+ }
+ return out << "Unknown";
+}
+
+std::ostream& operator<<(std::ostream& out, Date const& date) {
+ if (date.empty())
+ return out << "none";
+ return out << date.to_format("%Y-%m-%d %H:%M");
+}
+
+constexpr const char kTryMessage[] = "Try `dump-image --help` for usage.";
+
+} // namespace
+
+int main(int argc, char** argv) {
+ auto args = Args::create();
+ auto* help_arg = args->add_option('h', "help", "display this text and exit.");
+
+ std::vector<std::string> arguments;
+ if (!args->run(argc, argv, "dump-image", std::cerr, &arguments)) {
+ std::cerr << kTryMessage << std::endl;
+ return EXIT_FAILURE;
+ }
+ if (help_arg->is_set()) {
+ std::cout << "Usage: `dump-image FILE...'\n"
+ << "Dump image information about FILE.\n"
+ << "\n"
+ << "Options:\n";
+ args->print_descriptions(std::cout, 80);
+ return EXIT_SUCCESS;
+ }
+
+ bool good = true;
+
+ for (auto const& arg : arguments) {
+ if (arguments.size() > 1)
+ std::cout << arg << std::endl;
+ auto image = Image::load(arg);
+ if (image) {
+ std::cout << "Width: " << image->width() << std::endl;
+ std::cout << "Height: " << image->height() << std::endl;
+ std::cout << "Location: " << image->location() << std::endl;
+ std::cout << "Rotation: " << image->rotation() << std::endl;
+ std::cout << "Date: " << image->date() << std::endl;
+ } else {
+ std::cerr << "Failed to load " << arg << std::endl;
+ good = false;
+ }
+ }
+
+ return good ? EXIT_SUCCESS : EXIT_FAILURE;
+}