diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2020-05-04 20:04:57 +0200 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2020-05-04 20:04:57 +0200 | 
| commit | 263b055953f2b49e1fdc4b0cb4bec5253c04a265 (patch) | |
| tree | 0464194850c30cdf7f71d2a6873a44a6c4eb62ac /drumgizmo | |
| parent | 6fecf27d61fd391785a72e315f14eef23f7028d8 (diff) | |
DGValidator: Add clickmap validation.
Diffstat (limited to 'drumgizmo')
| -rw-r--r-- | drumgizmo/Makefile.am | 14 | ||||
| -rw-r--r-- | drumgizmo/dgvalidator.cc | 189 | 
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;  } | 
