diff --git a/CMakeLists.txt b/CMakeLists.txt index 985b82227..65d7027ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,9 @@ if(CORRADE_TARGET_UNIX OR CORRADE_TARGET_WINDOWS) cmake_dependent_option(WITH_DISTANCEFIELDCONVERTER "Build magnum-distancefieldconverter utility" OFF "NOT TARGET_GLES" OFF) endif() +# API-independent utilities +option(WITH_IMAGECONVERTER "Build magnum-imageconverter utility" OFF) + # Plugins option(WITH_WAVAUDIOIMPORTER "Build WavAudioImporter plugin" OFF) option(WITH_MAGNUMFONT "Build MagnumFont plugin" OFF) diff --git a/doc/building.dox b/doc/building.dox index a4b6db335..04bbc28f1 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -250,6 +250,8 @@ There are also a few command-line utilities, also disabled by default: executable for converting fonts to raster ones. Enables also building of @ref Text library. Available only on desktop GL, depends on some windowless application library. +- `WITH_IMAGECONVERTER` - @ref magnum-imageconverter "magnum-imageconverter" + executable for converting images of different formats. Magnum also contains a set of dependency-less plugins for importing essential file formats. Additional plugins are provided in separate plugin repository, diff --git a/doc/cmake.dox b/doc/cmake.dox index d491fc795..9bd1fbce7 100644 --- a/doc/cmake.dox +++ b/doc/cmake.dox @@ -142,6 +142,7 @@ Lastly, a few utility executables are available: - `distancefieldconverter` -- @ref magnum-distancefieldconverter executable - `fontconverter` -- @ref magnum-fontconverter executable +- `imageconverter` -- @ref magnum-imageconverter executable - `info` -- @ref magnum-info executable - `al-info` -- @ref magnum-al-info executable diff --git a/doc/utilities.dox b/doc/utilities.dox index 8533fa386..f5d1ecaff 100644 --- a/doc/utilities.dox +++ b/doc/utilities.dox @@ -28,8 +28,10 @@ namespace Magnum { @brief Command-line utilities for system information and data conversion - @subpage magnum-info -- @copybrief magnum-info +- @subpage magnum-al-info -- @copybrief magnum-al-info - @subpage magnum-distancefieldconverter -- @copybrief magnum-distancefieldconverter - @subpage magnum-fontconverter -- @copybrief magnum-fontconverter +- @subpage magnum-imageconverter -- @copybrief magnum-imageconverter */ } diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 846ed9da0..7ee1a6916 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -72,6 +72,7 @@ # WavAudioImporter - WAV audio importer plugin # distancefieldconverter - magnum-distancefieldconverter executable # fontconverter - magnum-fontconverter executable +# imageconverter - magnum-imageconverter executable # info - magnum-info executable # al-info - magnum-al-info executable # @@ -345,7 +346,7 @@ endif() # components from other repositories) set(_MAGNUM_LIBRARY_COMPONENTS "^(Audio|DebugTools|MeshTools|Primitives|SceneGraph|Shaders|Shapes|Text|TextureTools|AndroidApplication|GlfwApplication|GlutApplication|GlxApplication|NaClApplication|Sdl2Application|XEglApplication|WindowlessCglApplication|WindowlessEglApplication|WindowlessGlxApplication|WindowlessIosApplication|WindowlessNaClApplication|WindowlessWglApplication|WindowlessWindowsEglApplication|CglContext|EglContext|GlxContext|WglContext)$") set(_MAGNUM_PLUGIN_COMPONENTS "^(MagnumFont|MagnumFontConverter|ObjImporter|TgaImageConverter|TgaImporter|WavAudioImporter)$") -set(_MAGNUM_EXECUTABLE_COMPONENTS "^(distancefieldconverter|fontconverter|info|al-info)$") +set(_MAGNUM_EXECUTABLE_COMPONENTS "^(distancefieldconverter|fontconverter|imageconverter|info|al-info)$") # Find all components foreach(_component ${Magnum_FIND_COMPONENTS}) diff --git a/src/Magnum/Trade/CMakeLists.txt b/src/Magnum/Trade/CMakeLists.txt index 59f0b8d44..e3d997aa6 100644 --- a/src/Magnum/Trade/CMakeLists.txt +++ b/src/Magnum/Trade/CMakeLists.txt @@ -46,6 +46,20 @@ add_custom_target(MagnumTrade SOURCES ${MagnumTrade_HEADERS}) install(FILES ${MagnumTrade_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Trade) +if(WITH_IMAGECONVERTER) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/imageconverterConfigure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/imageconverterConfigure.h) + + add_executable(magnum-imageconverter imageconverter.cpp) + target_include_directories(magnum-imageconverter PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + target_link_libraries(magnum-imageconverter Magnum) + + install(TARGETS magnum-imageconverter DESTINATION ${MAGNUM_BINARY_INSTALL_DIR}) + + # Magnum imageconverter target alias for superprojects + add_executable(Magnum::imageconverter ALIAS magnum-imageconverter) +endif() + if(BUILD_TESTS) add_subdirectory(Test) endif() diff --git a/src/Magnum/Trade/imageconverter.cpp b/src/Magnum/Trade/imageconverter.cpp new file mode 100644 index 000000000..f1fbd138a --- /dev/null +++ b/src/Magnum/Trade/imageconverter.cpp @@ -0,0 +1,107 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include + +#include "Magnum/PixelFormat.h" +#include "Magnum/Trade/AbstractImporter.h" +#include "Magnum/Trade/AbstractImageConverter.h" +#include "Magnum/Trade/ImageData.h" + +#include "imageconverterConfigure.h" + +namespace Magnum { + +/** +@page magnum-imageconverter Image conversion utility +@brief Converts images of different formats + +@section magnum-imageconverter-usage Usage + + magnum-imageconverter [-h|--help] [--importer IMPORTER] [--converter CONVERTER] [--plugin-dir DIR] [--] input output + +Arguments: + +- `input` -- input image +- `output` -- output image +- `-h`, `--help` -- display this help message and exit +- `--importer IMPORTER` -- image importer plugin (default: + @ref Trade::AnyImageImporter "AnyImageImporter") +- `--converter CONVERTER` -- image converter plugin (default: + @ref Trade::AnyImageConverter "AnyImageConverter") +- `--plugin-dir DIR` -- base plugin dir (defaults to plugin directory in + Magnum install location) + +@section magnum-imageconverter-example Example usage + +Converting a JPEG file to a PNG: + + magnum-imageconverter image.jpg image.png + +*/ + +} + +using namespace Magnum; + +int main(int argc, char** argv) { + Utility::Arguments args; + args.addArgument("input").setHelp("input", "input image") + .addArgument("output").setHelp("output", "output image") + .addOption("importer", "AnyImageImporter").setHelp("importer", "image importer plugin") + .addOption("converter", "AnyImageConverter").setHelp("converter", "image converter plugin") + .addOption("plugin-dir", MAGNUM_PLUGINS_DIR).setHelp("plugin-dir", "base plugin dir", "DIR") + .setHelp("Converts images of different formats.") + .parse(argc, argv); + + /* Load importer plugin */ + PluginManager::Manager importerManager(Utility::Directory::join(args.value("plugin-dir"), "importers/")); + if(!(importerManager.load(args.value("importer")) & PluginManager::LoadState::Loaded)) + return 1; + std::unique_ptr importer = importerManager.instance(args.value("importer")); + + /* Load converter plugin */ + PluginManager::Manager converterManager(Utility::Directory::join(args.value("plugin-dir"), "imageconverters/")); + if(!(converterManager.load(args.value("converter")) & PluginManager::LoadState::Loaded)) + return 1; + std::unique_ptr converter = converterManager.instance(args.value("converter")); + + /* Open input file */ + std::optional image; + if(!importer->openFile(args.value("input")) || !(image = importer->image2D(0))) { + Error() << "Cannot open file" << args.value("input"); + return 1; + } + + Debug() << "Converting image of size" << image->size() << Debug::nospace << ", format" << image->format() << "and type" << image->type() << "to" << args.value("output"); + + /* Save output file */ + if(!converter->exportToFile(*image, args.value("output"))) { + Error() << "Cannot save file" << args.value("output"); + return 1; + } +} diff --git a/src/Magnum/Trade/imageconverterConfigure.h.cmake b/src/Magnum/Trade/imageconverterConfigure.h.cmake new file mode 100644 index 000000000..895e33c28 --- /dev/null +++ b/src/Magnum/Trade/imageconverterConfigure.h.cmake @@ -0,0 +1,30 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifdef CORRADE_IS_DEBUG_BUILD +#define MAGNUM_PLUGINS_DIR "${MAGNUM_PLUGINS_DEBUG_INSTALL_DIR}" +#else +#define MAGNUM_PLUGINS_DIR "${MAGNUM_PLUGINS_INSTALL_DIR}" +#endif