summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2020-05-04 20:04:57 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2020-05-04 20:04:57 +0200
commit263b055953f2b49e1fdc4b0cb4bec5253c04a265 (patch)
tree0464194850c30cdf7f71d2a6873a44a6c4eb62ac
parent6fecf27d61fd391785a72e315f14eef23f7028d8 (diff)
DGValidator: Add clickmap validation.
-rw-r--r--drumgizmo/Makefile.am14
-rw-r--r--drumgizmo/dgvalidator.cc189
2 files changed, 196 insertions, 7 deletions
diff --git a/drumgizmo/Makefile.am b/drumgizmo/Makefile.am
index c9e85b9..2cb46bf 100644
--- a/drumgizmo/Makefile.am
+++ b/drumgizmo/Makefile.am
@@ -108,13 +108,23 @@ dgvalidator_LDFLAGS =
dgvalidator_CXXFLAGS = \
-I$(top_srcdir)/src -I$(top_srcdir)/getoptpp \
-I$(top_srcdir)/hugin -DWITH_HUG_MUTEX -DWITH_HUG_FILTER \
- $(SSEFLAGS)
+ $(SSEFLAGS) \
+ -I$(top_srcdir)/plugingui \
+ -DLODEPNG_NO_COMPILE_ENCODER \
+ -DLODEPNG_NO_COMPILE_DISK \
+ -DLODEPNG_NO_COMPILE_ANCILLARY_CHUNKS \
+ -DLODEPNG_NO_COMPILE_ERROR_TEXT \
+ -DLODEPNG_NO_COMPILE_CPP
dgvalidator_CFLAGS = -DWITH_HUG_MUTEX -DWITH_HUG_FILTER
dgvalidator_SOURCES = \
dgvalidator.cc \
$(top_srcdir)/hugin/hugin.c \
- $(top_srcdir)/hugin/hugin_filter.c
+ $(top_srcdir)/hugin/hugin_filter.c \
+ $(top_srcdir)/plugingui/lodepng/lodepng.cpp \
+ $(top_srcdir)/plugingui/image.cc \
+ $(top_srcdir)/plugingui/resource.cc \
+ $(top_srcdir)/plugingui/colour.cc
endif # ENABLE_CLI
diff --git a/drumgizmo/dgvalidator.cc b/drumgizmo/dgvalidator.cc
index 456e5bb..bc80a33 100644
--- a/drumgizmo/dgvalidator.cc
+++ b/drumgizmo/dgvalidator.cc
@@ -35,8 +35,24 @@
#include <hugin.hpp>
#include <getoptpp.hpp>
#include <sstream>
+#include <climits>
+
+#include <lodepng/lodepng.h>
#include <config.h>
+#include <platform.h>
+
+#if DG_PLATFORM != DG_PLATFORM_WINDOWS
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#endif
+
+#include <image.h>
+
+// Needed for Resource class
+#include <resource_data.h>
+const rc_data_t rc_data[] = {};
namespace
{
@@ -118,6 +134,21 @@ std::string usage(const std::string& name, bool brief = false)
return output.str();
}
+bool pathIsFile(const std::string& path)
+{
+#if DG_PLATFORM == DG_PLATFORM_WINDOWS
+ return (GetFileAttributesA(path.data()) & FILE_ATTRIBUTE_DIRECTORY) == 0;
+#else
+ struct stat s;
+ if(stat(path.data(), &s) != 0)
+ {
+ return false; // error
+ }
+
+ return (s.st_mode & S_IFREG) != 0; // s.st_mode & S_IFDIR => dir
+#endif
+}
+
}
int main(int argc, char* argv[])
@@ -282,14 +313,162 @@ int main(int argc, char* argv[])
}
}
- if(parseerror)
+ bool image_error{false};
+ // Check drumkit images
{
- logger(LogLevel::Warning, "Validator found errors.");
+ if(!drumkitdom.metadata.image_map.empty() &&
+ drumkitdom.metadata.image.empty())
+ {
+ logger(LogLevel::Warning, "Found drumkit image_map but no image,"
+ " so image_map will not be usable.");
+ image_error = true;
+ }
+
+ std::pair<std::size_t, std::size_t> image_size;
+ if(!drumkitdom.metadata.image.empty())
+ {
+ // Check if the image file exists
+ auto image = path + "/" + drumkitdom.metadata.image;
+ logger(LogLevel::Info, "Found drumkit image '" + image + "'");
+ if(!pathIsFile(image))
+ {
+ logger(LogLevel::Warning, "Image file does not exist.");
+ image_error = true;
+ }
+ else
+ {
+ // Check if the image_map can be loaded (is a valid png file)
+ GUI::Image img(image);
+ if(!img.isValid())
+ {
+ logger(LogLevel::Warning, "Drumkit image, '" + image +
+ "', could not be loaded. Not a valid PNG image?");
+ image_error = true;
+ }
+ else
+ {
+ image_size = { img.width(), img.height() };
+ logger(LogLevel::Info, "Loaded image in resolution " +
+ std::to_string(image_size.first) + " x " +
+ std::to_string(image_size.second));
+ }
+ }
+ }
+
+ std::pair<std::size_t, std::size_t> image_map_size;
+ if(!drumkitdom.metadata.image_map.empty())
+ {
+ // Check if the image_map file exists
+ auto image_map = path + "/" + drumkitdom.metadata.image_map;
+ logger(LogLevel::Info, "Found drumkit image_map '" + image_map + "'");
+ if(!pathIsFile(image_map))
+ {
+ logger(LogLevel::Warning, "Image map file does not exist.");
+ image_error = true;
+ }
+ else
+ {
+ // Check if the image_map can be loaded (is a valid png file)
+ GUI::Image image(image_map);
+ if(!image.isValid())
+ {
+ logger(LogLevel::Warning, "Drumkit image_map, '" + image_map +
+ "', could not be loaded. Not a valid PNG image?");
+ image_error = true;
+ }
+ else
+ {
+ image_map_size = { image.width(), image.height() };
+ logger(LogLevel::Info, "Loaded image_map in resolution " +
+ std::to_string(image_map_size.first) + " x " +
+ std::to_string(image_map_size.second));
+
+ // Check if the click map colours can be found in the image_map image.
+ for(const auto& clickmap : drumkitdom.metadata.clickmaps)
+ {
+ if(clickmap.colour.size() != 6)
+ {
+ logger(LogLevel::Warning,
+ "Clickmap colour field not the right length (should be 6).");
+ image_error = true;
+ continue;
+ }
+
+ try
+ {
+ auto hex_colour = std::stoul(clickmap.colour, nullptr, 16);
+ float red = (hex_colour >> 16 & 0xff) / 255.0f;
+ float green = (hex_colour >> 8 & 0xff) / 255.0f;
+ float blue = (hex_colour >> 0 & 0xff) / 255.0f;
+ GUI::Colour colour(red, green, blue);
+
+ bool found{false};
+ for(int y = 0; y < image.height() && !found; ++y)
+ {
+ for(int x = 0; x < image.width() && !found; ++x)
+ {
+ if(image.getPixel(x, y) == colour)
+ {
+ found = true;
+ }
+ }
+ }
+
+ if(!found)
+ {
+ logger(LogLevel::Warning,
+ "Clickmap colour '" + clickmap.colour +
+ "' not found in image_map.");
+ image_error = true;
+ }
+ }
+ catch(...)
+ {
+ // Not valid hex number
+ logger(LogLevel::Warning,
+ "Clickmap colour not a valid hex colour.");
+ image_error = true;
+ continue;
+ }
+
+ // Check if the click map instruments exist.
+ bool found{false};
+ for(const auto& instrument: kit.instruments)
+ {
+ if(instrument->getName() == clickmap.instrument)
+ {
+ found = true;
+ }
+ }
+ if(!found)
+ {
+ logger(LogLevel::Warning,
+ "Clickmap instrument '" + clickmap.instrument +
+ "' not found in drumkit.");
+ image_error = true;
+ }
+
+ }
+ }
+ }
+ }
+
+ // Check if the image and the image_map have same resolutions
+ if(image_size != image_map_size)
+ {
+ logger(LogLevel::Warning,
+ "Drumkit image and image_map does not have same resolution.");
+ image_error = true;
+ }
+
}
- else
+
+ if(parseerror || image_error)
{
- logger(LogLevel::Info, "Validator finished without errors.");
+ logger(LogLevel::Warning, "Validator found errors.");
+ return 1;
}
- return parseerror ? 1 : 0;
+ logger(LogLevel::Info, "Validator finished without errors.");
+ return 0;
}