diff --git a/src/Plugins/TgaImageConverter/CMakeLists.txt b/src/Plugins/TgaImageConverter/CMakeLists.txt new file mode 100644 index 000000000..62dd12d87 --- /dev/null +++ b/src/Plugins/TgaImageConverter/CMakeLists.txt @@ -0,0 +1,46 @@ +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013 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. +# + +set(TgaImageConverter_SRCS + TgaImageConverter.cpp) + +set(TgaImageConverter_HEADERS + TgaImageConverter.h) + +add_library(TgaImageConverterObjects OBJECT ${TgaImageConverter_SRCS}) +set_target_properties(TgaImageConverterObjects PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) + +corrade_add_plugin(TgaImageConverter ${MAGNUM_PLUGINS_IMAGECONVERTER_INSTALL_DIR} + TgaImageConverter.conf + $ + pluginRegistrationTgaImageConverter.cpp) +target_link_libraries(TgaImageConverter ${MAGNUM_LIBRARIES}) + +install(FILES ${TgaImageConverter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImageConverter) + +if(BUILD_TESTS) + add_library(TgaImageConverterTestLib $) + target_link_libraries(TgaImageConverterTestLib ${MAGNUM_LIBRARIES}) + add_subdirectory(Test) +endif() diff --git a/src/Plugins/TgaImageConverter/Test/CMakeLists.txt b/src/Plugins/TgaImageConverter/Test/CMakeLists.txt new file mode 100644 index 000000000..f1c56f698 --- /dev/null +++ b/src/Plugins/TgaImageConverter/Test/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013 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. +# + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +corrade_add_test(TgaImageConverterTest TgaImageConverterTest.cpp LIBRARIES TgaImageConverterTestLib TgaImporterTestLib) diff --git a/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp b/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp new file mode 100644 index 000000000..5d448e0b6 --- /dev/null +++ b/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp @@ -0,0 +1,129 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 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 +#include +#include +#include +#include + +#include "configure.h" + +using Corrade::Utility::Directory; + +namespace Magnum { namespace Trade { namespace TgaImageConverter { namespace Test { + +class TgaImageConverterTest: public Corrade::TestSuite::Tester { + public: + explicit TgaImageConverterTest(); + + void wrongFormat(); + void wrongType(); + + void data(); + void file(); +}; + +namespace { + const Image2D original({2, 3}, Image2D::Format::BGR, Image2D::Type::UnsignedByte, new char[18] { + 1, 2, 3, 2, 3, 4, + 3, 4, 5, 4, 5, 6, + 5, 6, 7, 6, 7, 8 + }); +} + +TgaImageConverterTest::TgaImageConverterTest() { + addTests({&TgaImageConverterTest::wrongFormat, + &TgaImageConverterTest::wrongType, + + &TgaImageConverterTest::data, + &TgaImageConverterTest::file}); +} + +void TgaImageConverterTest::wrongFormat() { + Image2D image({}, Image2D::Format::RG, Image2D::Type::UnsignedByte, nullptr); + + std::ostringstream out; + Error::setOutput(&out); + + const unsigned char* data; + std::tie(data, std::ignore) = TgaImageConverter().convertToData(&image); + CORRADE_VERIFY(!data); + CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::TgaImageConverter::convertToData(): unsupported image format AbstractImage::Format::RG\n"); +} + +void TgaImageConverterTest::wrongType() { + Image2D image({}, Image2D::Format::Red, Image2D::Type::Float, nullptr); + + std::ostringstream out; + Error::setOutput(&out); + + const unsigned char* data; + std::tie(data, std::ignore) = TgaImageConverter().convertToData(&image); + CORRADE_VERIFY(!data); + CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::TgaImageConverter::convertToData(): unsupported image type AbstractImage::Type::Float\n"); +} + +void TgaImageConverterTest::data() { + const unsigned char* data; + std::size_t size; + std::tie(data, size) = TgaImageConverter().convertToData(&original); + + TgaImporter::TgaImporter importer; + CORRADE_VERIFY(importer.openData(data, size)); + Trade::ImageData2D* converted = importer.image2D(0); + CORRADE_VERIFY(converted); + + CORRADE_COMPARE(converted->size(), Vector2i(2, 3)); + CORRADE_COMPARE(converted->format(), Trade::ImageData2D::Format::BGR); + CORRADE_COMPARE(converted->type(), Trade::ImageData2D::Type::UnsignedByte); + CORRADE_COMPARE(std::string(reinterpret_cast(converted->data()), 2*3*3), + std::string(reinterpret_cast(original.data()), 2*3*3)); +} + +void TgaImageConverterTest::file() { + const std::string filename = Directory::join(TGAIMAGECONVERTER_TEST_DIR, "file.tga"); + Directory::rm(filename); + CORRADE_VERIFY(TgaImageConverter().convertToFile(&original, filename)); + + TgaImporter::TgaImporter importer; + CORRADE_VERIFY(importer.openFile(filename)); + Trade::ImageData2D* converted = importer.image2D(0); + CORRADE_VERIFY(converted); + + CORRADE_COMPARE(converted->size(), Vector2i(2, 3)); + CORRADE_COMPARE(converted->format(), Trade::ImageData2D::Format::BGR); + CORRADE_COMPARE(converted->type(), Trade::ImageData2D::Type::UnsignedByte); + CORRADE_COMPARE(std::string(reinterpret_cast(converted->data()), 2*3*3), + std::string(reinterpret_cast(original.data()), 2*3*3)); + + Directory::rm(filename); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Trade::TgaImageConverter::Test::TgaImageConverterTest) diff --git a/src/Plugins/TgaImageConverter/Test/configure.h.cmake b/src/Plugins/TgaImageConverter/Test/configure.h.cmake new file mode 100644 index 000000000..98c60f430 --- /dev/null +++ b/src/Plugins/TgaImageConverter/Test/configure.h.cmake @@ -0,0 +1,25 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 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. +*/ + +#define TGAIMAGECONVERTER_TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}" diff --git a/src/Plugins/TgaImageConverter/TgaImageConverter.conf b/src/Plugins/TgaImageConverter/TgaImageConverter.conf new file mode 100644 index 000000000..e69de29bb diff --git a/src/Plugins/TgaImageConverter/TgaImageConverter.cpp b/src/Plugins/TgaImageConverter/TgaImageConverter.cpp new file mode 100644 index 000000000..3ba43c062 --- /dev/null +++ b/src/Plugins/TgaImageConverter/TgaImageConverter.cpp @@ -0,0 +1,94 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 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 "TgaImageConverter.h" + +#include +#include +#include + +#include "TgaImporter/TgaHeader.h" + +namespace Magnum { namespace Trade { namespace TgaImageConverter { + +TgaImageConverter::TgaImageConverter() = default; + +TgaImageConverter::TgaImageConverter(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin): AbstractImageConverter(manager, std::move(plugin)) {} + +TgaImageConverter::Features TgaImageConverter::features() const { + return Feature::ConvertToData|Feature::ConvertToFile; +} + +std::pair TgaImageConverter::convertToData(const Image2D* const image) const { + if(image->format() != AbstractImage::Format::BGR && + image->format() != AbstractImage::Format::BGRA && + image->format() != AbstractImage::Format::Red) { + Error() << "Trade::TgaImageConverter::TgaImageConverter::convertToData(): unsupported image format" << image->format(); + return {nullptr, 0}; + } + + if(image->type() != AbstractImage::Type::UnsignedByte) { + Error() << "Trade::TgaImageConverter::TgaImageConverter::convertToData(): unsupported image type" << image->type(); + return {nullptr, 0}; + } + + /* Initialize data buffer */ + const UnsignedByte pixelSize = Image2D::pixelSize(image->format(), image->type()); + const std::size_t size = sizeof(TgaImporter::TgaHeader) + pixelSize*image->size().product(); + unsigned char* data = new unsigned char[size](); + + /* Fill header */ + auto header = reinterpret_cast(data); + header->imageType = image->format() == AbstractImage::Format::Red ? 3 : 2; + header->bpp = pixelSize*8; + header->width = image->size().x(); + header->height = image->size().y(); + + /* Fill data */ + std::copy(image->data(), image->data()+pixelSize*image->size().product(), data+sizeof(TgaImporter::TgaHeader)); + + return {data, size}; +} + +bool TgaImageConverter::convertToFile(const Image2D* const image, const std::string& filename) const { + /* Convert the image */ + const unsigned char* data; + std::size_t size; + std::tie(data, size) = convertToData(image); + if(!data) return false; + + /* Open file */ + std::ofstream out(filename.c_str()); + if(!out.good()) { + delete[] data; + return false; + } + + /* Write contents */ + out.write(reinterpret_cast(data), size); + delete[] data; + return true; +} + +}}} diff --git a/src/Plugins/TgaImageConverter/TgaImageConverter.h b/src/Plugins/TgaImageConverter/TgaImageConverter.h new file mode 100644 index 000000000..31bf183be --- /dev/null +++ b/src/Plugins/TgaImageConverter/TgaImageConverter.h @@ -0,0 +1,57 @@ +#ifndef Magnum_Trade_TgaImageConverter_TgaImageConverter_h +#define Magnum_Trade_TgaImageConverter_TgaImageConverter_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 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. +*/ + +/** @file + * @brief Class Magnum::Trade::TgaImageConverter::TgaImageConverter + */ + +#include + +namespace Magnum { namespace Trade { namespace TgaImageConverter { + +/** +@brief TGA image converter + +Supports images with format @ref AbstractImage::Format "AbstractImage::Format::BGR", +@ref AbstractImage::Format "AbstractImage::Format::BGRA" or @ref AbstractImage::Format "AbstractImage::Format::Red" +and type @ref AbstractImage::Type "AbstractImage::Type::UnsignedByte". +*/ +class TgaImageConverter: public AbstractImageConverter { + public: + /** @brief Default constructor */ + explicit TgaImageConverter(); + + /** @brief Plugin manager constructor */ + explicit TgaImageConverter(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin); + + Features features() const override; + std::pair convertToData(const Image2D* const image) const override; + bool convertToFile(const Image2D* const image, const std::string& filename) const override; +}; + +}}} + +#endif diff --git a/src/Plugins/TgaImageConverter/pluginRegistrationTgaImageConverter.cpp b/src/Plugins/TgaImageConverter/pluginRegistrationTgaImageConverter.cpp new file mode 100644 index 000000000..dd4b0082c --- /dev/null +++ b/src/Plugins/TgaImageConverter/pluginRegistrationTgaImageConverter.cpp @@ -0,0 +1,28 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 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 "TgaImageConverter.h" + +PLUGIN_REGISTER(TgaImageConverter, Magnum::Trade::TgaImageConverter::TgaImageConverter, + "cz.mosra.magnum.Trade.AbstractImageConverter/0.1")