From d4c5b3f5666e05f22ad33a987fbe8fa1cbef2a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 8 Apr 2021 17:33:52 +0200 Subject: [PATCH] Trade: refresh the AbstractImageConverter API. First and foremost I need to expand the interface to support 3D image conversion. But the interface was not great to begin with, so this takes the opportunity of an API break and does several things: * The `export*()` names were rather strange and I don't even remember why I chose that name (maybe because at first I wanted to have an "exporter" API as a counterpart to importers?) * In addition, there was no way to convert a compressed image to a compressed image (or to an uncompressed image) and adding the two missing variants would be a lot of combinations. So instead the new convert() returns an ImageData, which can be both, and thus also allows the converters to produce compressed or uncompressed output based on some runtime setting, without having to implement two (four?) separate functions for that and requiring users to know beforehand what type of an image will be created. * The ImageConverterFeature enum was named in a really strange way as well, with ConvertCompressedImage meaning "convert to a compressed image" while "ConvertCompressedData" instead meant "convert a compressed image to a data". Utter chaos. It also all implied 2D and on the other hand had a redundant `Image` in the name, so I went and remade the whole thing. As mentioned above, two of the enums now mean the same thing, and are both replaced with Convert2D. * Finally, similarly as changes elsewhere, I took this opportunity to get rid of std::string in the convertToFile() APIs. --- doc/changelog.dox | 24 + doc/generated/colormaps.cpp | 3 +- doc/generated/easings.cpp | 1 + doc/generated/primitives.cpp | 17 +- doc/generated/shaders.cpp | 3 +- src/Magnum/DebugTools/CompareImage.cpp | 3 +- src/Magnum/DebugTools/Screenshot.cpp | 3 +- .../DebugTools/Test/ScreenshotGLTest.cpp | 2 +- src/Magnum/Image.h | 21 - .../TextureTools/distancefieldconverter.cpp | 2 +- src/Magnum/Trade/AbstractImageConverter.cpp | 194 +++++--- src/Magnum/Trade/AbstractImageConverter.h | 378 ++++++++++++---- src/Magnum/Trade/ImageData.h | 1 + .../Trade/Test/AbstractImageConverterTest.cpp | 428 ++++++++++-------- src/Magnum/Trade/imageconverter.cpp | 2 +- .../AnyImageConverter/AnyImageConverter.cpp | 20 +- .../AnyImageConverter/AnyImageConverter.h | 4 +- .../Test/AnyImageConverterTest.cpp | 19 +- .../MagnumFontConverter.cpp | 2 +- .../Test/TgaImageConverterTest.cpp | 12 +- .../TgaImageConverter/TgaImageConverter.cpp | 12 +- .../TgaImageConverter/TgaImageConverter.h | 2 +- 22 files changed, 728 insertions(+), 425 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 93ee9a8e8..a797692ca 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -477,6 +477,30 @@ See also: @ref MAGNUM_BUILD_DEPRECATED is enabled, the returned type acts as a @ref Corrade::Containers::Optional but has (deprecated) implicit conversion to a @ref Corrade::Containers::Pointer to avoid breaking user code. +- @cpp Trade::ImageConverterFeature::ConvertImage @ce and + @cpp Trade::ImageConverterFeature::ConvertCompressedImage @ce; + @cpp Trade::AbstractImageConverter::exportToImage() @ce and + @cpp Trade::AbstractImageConverter::exportToCompressedImage() @ce are + deprecated in favor of an unifying + @ref Trade::ImageConverterFeature::Convert2D and a corresponding + @ref Trade::AbstractImageConverter::convert() that returns an + @ref Trade::ImageData2D and thus can handle both cases and follows a naming + scheme used elsewhere +- @cpp Trade::ImageConverterFeature::ConvertFile @ce, + @cpp Trade::ImageConverterFeature::ConvertCompressedFile @ce, + @cpp Trade::ImageConverterFeature::ConvertData @ce and + @cpp Trade::ImageConverterFeature::ConvertCompressedData @ce are deprecated + in favor of @ref Trade::ImageConverterFeature::Convert2DToFile, + @ref Trade::ImageConverterFeature::ConvertCompressed2DToFile, + @ref Trade::ImageConverterFeature::Convert2DToData and + @ref Trade::ImageConverterFeature::ConvertCompressed2DToData that more + clearly imply what's converted to what and make room for 3D image + conversion as well +- @cpp Trade::AbstractImageConverter::exportToData() @ce and + @cpp Trade::AbstractImageConverter::exportToFile() @ce are deprecated in + favor of @ref Trade::AbstractImageConverter::convertToData() and + @ref Trade::AbstractImageConverter::convertToFile() that follow a naming + scheme used elsewhere - The signature of @ref Trade::AbstractSceneConverter::convertToFile() was changed to have input first and output second, for consistency with other interfaces, together with a switch to @ref Containers::StringView. The diff --git a/doc/generated/colormaps.cpp b/doc/generated/colormaps.cpp index 8047a3a4d..c811e620a 100644 --- a/doc/generated/colormaps.cpp +++ b/doc/generated/colormaps.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include "Magnum/PixelFormat.h" @@ -62,7 +63,7 @@ int main() { {std::size_t(OutputSize.y()), std::size_t(OutputSize.x())}}; Utility::copy(src, dst); - if(!converter->exportToFile(ImageView2D{PixelFormat::RGB8Unorm, OutputSize, data}, image.second)) + if(!converter->convertToFile(ImageView2D{PixelFormat::RGB8Unorm, OutputSize, data}, image.second)) return 2; } } diff --git a/doc/generated/easings.cpp b/doc/generated/easings.cpp index 85b471c34..6e925cb6d 100644 --- a/doc/generated/easings.cpp +++ b/doc/generated/easings.cpp @@ -40,6 +40,7 @@ attribute to the element if you'd ever need that. */ +#include #include #include #include diff --git a/doc/generated/primitives.cpp b/doc/generated/primitives.cpp index 1a3bd00e1..ab42a42de 100644 --- a/doc/generated/primitives.cpp +++ b/doc/generated/primitives.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -198,7 +199,7 @@ int PrimitiveVisualizer::exec() { GL::AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), GL::FramebufferBlit::Color); Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); - converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + converter->convertToFile(result, Utility::Directory::join("../", "primitives-" + filename)); } } @@ -217,7 +218,7 @@ int PrimitiveVisualizer::exec() { GL::AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), GL::FramebufferBlit::Color); Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); - converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + converter->convertToFile(result, Utility::Directory::join("../", "primitives-" + filename)); } } @@ -242,7 +243,7 @@ int PrimitiveVisualizer::exec() { GL::AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), GL::FramebufferBlit::Color); Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); - converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + converter->convertToFile(result, Utility::Directory::join("../", "primitives-" + filename)); } } @@ -273,7 +274,7 @@ int PrimitiveVisualizer::exec() { GL::AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), GL::FramebufferBlit::Color); Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); - converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + converter->convertToFile(result, Utility::Directory::join("../", "primitives-" + filename)); } } @@ -304,7 +305,7 @@ int PrimitiveVisualizer::exec() { GL::AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), GL::FramebufferBlit::Color); Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); - converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + converter->convertToFile(result, Utility::Directory::join("../", "primitives-" + filename)); } } @@ -348,7 +349,7 @@ int PrimitiveVisualizer::exec() { GL::AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), GL::FramebufferBlit::Color); Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); - converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + converter->convertToFile(result, Utility::Directory::join("../", "primitives-" + filename)); } } @@ -371,7 +372,7 @@ int PrimitiveVisualizer::exec() { GL::AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), GL::FramebufferBlit::Color); Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); - converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + converter->convertToFile(result, Utility::Directory::join("../", "primitives-" + filename)); } } @@ -394,7 +395,7 @@ int PrimitiveVisualizer::exec() { GL::AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), GL::FramebufferBlit::Color); Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); - converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + converter->convertToFile(result, Utility::Directory::join("../", "primitives-" + filename)); } } diff --git a/doc/generated/shaders.cpp b/doc/generated/shaders.cpp index 35042926c..09dd64280 100644 --- a/doc/generated/shaders.cpp +++ b/doc/generated/shaders.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -145,7 +146,7 @@ int ShaderVisualizer::exec() { GL::AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), GL::FramebufferBlit::Color); Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA8Unorm}); - converter->exportToFile(result, Utility::Directory::join("../", "shaders-" + filename)); + converter->convertToFile(result, Utility::Directory::join("../", "shaders-" + filename)); } _importer.reset(); diff --git a/src/Magnum/DebugTools/CompareImage.cpp b/src/Magnum/DebugTools/CompareImage.cpp index 73a37e779..2b9f4db6d 100644 --- a/src/Magnum/DebugTools/CompareImage.cpp +++ b/src/Magnum/DebugTools/CompareImage.cpp @@ -29,6 +29,7 @@ #include #include #include +#include /* for Directory */ #include #include #include @@ -734,7 +735,7 @@ void ImageComparatorBase::saveDiagnostic(TestSuite::ComparisonStatusFlags, Utili we're in the middle of a fail anyway (and everything will print messages to the output nevertheless). */ Containers::Pointer converter = _state->converterManager().loadAndInstantiate("AnyImageConverter"); - if(converter && converter->exportToFile(image, filename)) + if(converter && converter->convertToFile(image, filename)) out << "->" << filename; } diff --git a/src/Magnum/DebugTools/Screenshot.cpp b/src/Magnum/DebugTools/Screenshot.cpp index 1c5aac681..1619e27b2 100644 --- a/src/Magnum/DebugTools/Screenshot.cpp +++ b/src/Magnum/DebugTools/Screenshot.cpp @@ -26,6 +26,7 @@ #include "Screenshot.h" #include +#include #include #include @@ -78,7 +79,7 @@ bool screenshot(PluginManager::Manager& manager, return false; Image2D image = framebuffer.read(framebuffer.viewport(), {format}); - if(!converter->exportToFile(image, filename)) + if(!converter->convertToFile(image, filename)) return false; Debug{} << "DebugTools::screenshot(): saved a" << format << "image of size" << image.size() << "to" << filename; diff --git a/src/Magnum/DebugTools/Test/ScreenshotGLTest.cpp b/src/Magnum/DebugTools/Test/ScreenshotGLTest.cpp index 1a37d3afe..75b77d5cf 100644 --- a/src/Magnum/DebugTools/Test/ScreenshotGLTest.cpp +++ b/src/Magnum/DebugTools/Test/ScreenshotGLTest.cpp @@ -311,7 +311,7 @@ void ScreenshotGLTest::saveFailed() { MAGNUM_VERIFY_NO_GL_ERROR(); CORRADE_VERIFY(!succeeded); - CORRADE_COMPARE(out.str(), "Trade::AnyImageConverter::exportToFile(): cannot determine the format of image.poo\n"); + CORRADE_COMPARE(out.str(), "Trade::AnyImageConverter::convertToFile(): cannot determine the format of image.poo\n"); } }}}} diff --git a/src/Magnum/Image.h b/src/Magnum/Image.h index 0b8d31fbc..ed0150d9a 100644 --- a/src/Magnum/Image.h +++ b/src/Magnum/Image.h @@ -47,11 +47,6 @@ template StridedA namespace Magnum { -#ifndef DOXYGEN_GENERATING_OUTPUT -/** @todo remove once AbstractImageConverter returns ImageData instead */ -namespace Trade { class AbstractImageConverter; } -#endif - /** @brief Image @@ -471,14 +466,6 @@ template class Image { Containers::Array release(); private: - #ifndef DOXYGEN_GENERATING_OUTPUT - /* For custom deleter checks. Not done in the constructors here because - the restriction is pointless when used outside of plugin - implementations. */ - /** @todo figure out a better way (return ImageData there instead?) */ - friend Trade::AbstractImageConverter; - #endif - PixelStorage _storage; PixelFormat _format; UnsignedInt _formatExtra; @@ -702,14 +689,6 @@ template class CompressedImage { Containers::Array release(); private: - #ifndef DOXYGEN_GENERATING_OUTPUT - /* For custom deleter checks. Not done in the constructors here because - the restriction is pointless when used outside of plugin - implementations. */ - /** @todo figure out a better way (return ImageData there instead?) */ - friend Trade::AbstractImageConverter; - #endif - /* To be made public once block size and block data size are stored together with the image */ explicit CompressedImage(CompressedPixelStorage storage, UnsignedInt format, const VectorTypeFor& size, Containers::Array&& data) noexcept; diff --git a/src/Magnum/TextureTools/distancefieldconverter.cpp b/src/Magnum/TextureTools/distancefieldconverter.cpp index 087b93988..aa230cc30 100644 --- a/src/Magnum/TextureTools/distancefieldconverter.cpp +++ b/src/Magnum/TextureTools/distancefieldconverter.cpp @@ -215,7 +215,7 @@ int DistanceFieldConverter::exec() { /* Save image */ Image2D result{PixelFormat::R8Unorm}; output.image(0, result); - if(!converter->exportToFile(result, args.value("output"))) { + if(!converter->convertToFile(result, args.value("output"))) { Error() << "Cannot save file" << args.value("output"); return 5; } diff --git a/src/Magnum/Trade/AbstractImageConverter.cpp b/src/Magnum/Trade/AbstractImageConverter.cpp index 29db56c33..fc01a90b3 100644 --- a/src/Magnum/Trade/AbstractImageConverter.cpp +++ b/src/Magnum/Trade/AbstractImageConverter.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include /* for Directory */ #include #include #include @@ -45,7 +47,7 @@ namespace Magnum { namespace Trade { std::string AbstractImageConverter::pluginInterface() { return /* [interface] */ -"cz.mosra.magnum.Trade.AbstractImageConverter/0.2.1" +"cz.mosra.magnum.Trade.AbstractImageConverter/0.3" /* [interface] */ ; } @@ -93,109 +95,181 @@ void AbstractImageConverter::clearFlags(ImageConverterFlags flags) { setFlags(_flags & ~flags); } -Containers::Optional AbstractImageConverter::exportToImage(const ImageView2D& image) { - CORRADE_ASSERT(features() & ImageConverterFeature::ConvertImage, - "Trade::AbstractImageConverter::exportToImage(): feature not supported", {}); +Containers::Optional AbstractImageConverter::convert(const ImageView2D& image) { + CORRADE_ASSERT(features() & ImageConverterFeature::Convert2D, + "Trade::AbstractImageConverter::convert(): 2D image conversion not supported", {}); - Containers::Optional out = doExportToImage(image); - CORRADE_ASSERT(!out || !out->_data.deleter(), "Trade::AbstractImageConverter::exportToImage(): implementation is not allowed to use a custom Array deleter", {}); + Containers::Optional out = doConvert(image); + CORRADE_ASSERT(!out || !out->_data.deleter(), "Trade::AbstractImageConverter::convert(): implementation is not allowed to use a custom Array deleter", {}); return out; } -Containers::Optional AbstractImageConverter::doExportToImage(const ImageView2D&) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::exportToImage(): feature advertised but not implemented", {}); +Containers::Optional AbstractImageConverter::doConvert(const ImageView2D&) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convert(): 2D image conversion advertised but not implemented", {}); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +Containers::Optional AbstractImageConverter::exportToImage(const ImageView2D& image) { + Containers::Optional out = convert(image); + if(!out) return {}; + if(out->isCompressed()) { + Error{} << "Trade::AbstractImageConverter::exportToImage(): implementation returned a compressed image"; + return {}; + } + + const PixelStorage storage = out->storage(); + const PixelFormat format = out->format(); + const UnsignedInt formatExtra = out->formatExtra(); + const UnsignedInt pixelSize = out->pixelSize(); + const Vector2i size = out->size(); + return Image2D{storage, format, formatExtra, pixelSize, size, out->release()}; } Containers::Optional AbstractImageConverter::exportToCompressedImage(const ImageView2D& image) { - CORRADE_ASSERT(features() & ImageConverterFeature::ConvertCompressedImage, - "Trade::AbstractImageConverter::exportToCompressedImage(): feature not supported", {}); + Containers::Optional out = convert(image); + if(!out) return {}; + if(!out->isCompressed()) { + Error{} << "Trade::AbstractImageConverter::exportToCompressedImage(): implementation returned an uncompressed image"; + return {}; + } + + const CompressedPixelStorage storage = out->compressedStorage(); + const CompressedPixelFormat format = out->compressedFormat(); + const Vector2i size = out->size(); + return CompressedImage2D{storage, format, size, out->release()}; +} +#endif - Containers::Optional out = doExportToCompressedImage(image); - CORRADE_ASSERT(!out || !out->_data.deleter(), "Trade::AbstractImageConverter::exportToCompressedImage(): implementation is not allowed to use a custom Array deleter", {}); +Containers::Optional AbstractImageConverter::convert(const CompressedImageView2D& image) { + CORRADE_ASSERT(features() & ImageConverterFeature::ConvertCompressed2D, + "Trade::AbstractImageConverter::convert(): compressed 2D image conversion not supported", {}); + + Containers::Optional out = doConvert(image); + CORRADE_ASSERT(!out || !out->_data.deleter(), "Trade::AbstractImageConverter::convert(): implementation is not allowed to use a custom Array deleter", {}); return out; } -Containers::Optional AbstractImageConverter::doExportToCompressedImage(const ImageView2D&) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::exportToCompressedImage(): feature advertised but not implemented", {}); +Containers::Optional AbstractImageConverter::doConvert(const CompressedImageView2D&) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convert(): compressed 2D image conversion advertised but not implemented", {}); } -Containers::Array AbstractImageConverter::exportToData(const ImageView2D& image) { - CORRADE_ASSERT(features() & ImageConverterFeature::ConvertData, - "Trade::AbstractImageConverter::exportToData(): feature not supported", nullptr); +Containers::Optional AbstractImageConverter::convert(const ImageData2D& image) { + return image.isCompressed() ? convert(CompressedImageView2D(image)) : convert(ImageView2D(image)); +} - Containers::Array out = doExportToData(image); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::exportToData(): implementation is not allowed to use a custom Array deleter", {}); +Containers::Array AbstractImageConverter::convertToData(const ImageView2D& image) { + CORRADE_ASSERT(features() >= ImageConverterFeature::Convert2DToData, + "Trade::AbstractImageConverter::convertToData(): 2D image conversion not supported", nullptr); + + Containers::Array out = doConvertToData(image); + CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); return out; } -Containers::Array AbstractImageConverter::doExportToData(const ImageView2D&) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::exportToData(): feature advertised but not implemented", nullptr); +Containers::Array AbstractImageConverter::doConvertToData(const ImageView2D&) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): 2D image conversion advertised but not implemented", nullptr); } -Containers::Array AbstractImageConverter::exportToData(const CompressedImageView2D& image) { - CORRADE_ASSERT(features() & ImageConverterFeature::ConvertCompressedData, - "Trade::AbstractImageConverter::exportToData(): feature not supported", nullptr); +#ifdef MAGNUM_BUILD_DEPRECATED +Containers::Array AbstractImageConverter::exportToData(const ImageView2D& image) { + return convertToData(image); +} +#endif - Containers::Array out = doExportToData(image); - CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::exportToData(): implementation is not allowed to use a custom Array deleter", {}); +Containers::Array AbstractImageConverter::convertToData(const CompressedImageView2D& image) { + CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressed2DToData, + "Trade::AbstractImageConverter::convertToData(): compressed 2D image conversion not supported", nullptr); + + Containers::Array out = doConvertToData(image); + CORRADE_ASSERT(!out.deleter(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter", {}); return out; } -Containers::Array AbstractImageConverter::doExportToData(const CompressedImageView2D&) { - CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::exportToData(): feature advertised but not implemented", nullptr); +Containers::Array AbstractImageConverter::doConvertToData(const CompressedImageView2D&) { + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractImageConverter::convertToData(): compressed 2D image conversion advertised but not implemented", nullptr); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +Containers::Array AbstractImageConverter::exportToData(const CompressedImageView2D& image) { + return convertToData(image); +} +#endif + +Containers::Array AbstractImageConverter::convertToData(const ImageData2D& image) { + return image.isCompressed() ? convertToData(CompressedImageView2D(image)) : convertToData(ImageView2D(image)); } +#ifdef MAGNUM_BUILD_DEPRECATED Containers::Array AbstractImageConverter::exportToData(const ImageData2D& image) { - return image.isCompressed() ? exportToData(CompressedImageView2D(image)) : exportToData(ImageView2D(image)); + return convertToData(image); } +#endif -bool AbstractImageConverter::exportToFile(const ImageView2D& image, const std::string& filename) { - CORRADE_ASSERT(features() & ImageConverterFeature::ConvertFile, - "Trade::AbstractImageConverter::exportToFile(): feature not supported", {}); +bool AbstractImageConverter::convertToFile(const ImageView2D& image, const Containers::StringView filename) { + CORRADE_ASSERT(features() & ImageConverterFeature::Convert2DToFile, + "Trade::AbstractImageConverter::convertToFile(): 2D image conversion not supported", {}); - return doExportToFile(image, filename); + return doConvertToFile(image, filename); } -bool AbstractImageConverter::doExportToFile(const ImageView2D& image, const std::string& filename) { - CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertData, "Trade::AbstractImageConverter::exportToFile(): feature advertised but not implemented", false); +bool AbstractImageConverter::doConvertToFile(const ImageView2D& image, const Containers::StringView filename) { + CORRADE_ASSERT(features() >= ImageConverterFeature::Convert2DToData, "Trade::AbstractImageConverter::convertToFile(): 2D image conversion advertised but not implemented", false); - const auto data = doExportToData(image); + const auto data = doConvertToData(image); /* No deleter checks as it doesn't matter here */ if(!data) return false; if(!Utility::Directory::write(filename, data)) { - Error() << "Trade::AbstractImageConverter::exportToFile(): cannot write to file" << filename; + Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } return true; } -bool AbstractImageConverter::exportToFile(const CompressedImageView2D& image, const std::string& filename) { - CORRADE_ASSERT(features() & ImageConverterFeature::ConvertCompressedFile, - "Trade::AbstractImageConverter::exportToFile(): feature not supported", {}); +#ifdef MAGNUM_BUILD_DEPRECATED +bool AbstractImageConverter::exportToFile(const ImageView2D& image, const std::string& filename) { + return convertToFile(image, filename); +} +#endif + +bool AbstractImageConverter::convertToFile(const CompressedImageView2D& image, const Containers::StringView filename) { + CORRADE_ASSERT(features() & ImageConverterFeature::ConvertCompressed2DToFile, + "Trade::AbstractImageConverter::convertToFile(): compressed 2D image conversion not supported", {}); - return doExportToFile(image, filename); + return doConvertToFile(image, filename); } -bool AbstractImageConverter::doExportToFile(const CompressedImageView2D& image, const std::string& filename) { - CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressedData, "Trade::AbstractImageConverter::exportToFile(): feature advertised but not implemented", false); +bool AbstractImageConverter::doConvertToFile(const CompressedImageView2D& image, Containers::StringView filename) { + CORRADE_ASSERT(features() >= ImageConverterFeature::ConvertCompressed2DToData, "Trade::AbstractImageConverter::convertToFile(): compressed 2D image conversion advertised but not implemented", false); - const auto data = doExportToData(image); + const auto data = doConvertToData(image); /* No deleter checks as it doesn't matter here */ if(!data) return false; if(!Utility::Directory::write(filename, data)) { - Error() << "Trade::AbstractImageConverter::exportToFile(): cannot write to file" << filename; + Error() << "Trade::AbstractImageConverter::convertToFile(): cannot write to file" << filename; return false; } return true; } +#ifdef MAGNUM_BUILD_DEPRECATED +bool AbstractImageConverter::exportToFile(const CompressedImageView2D& image, const std::string& filename) { + return convertToFile(image, filename); +} +#endif + +bool AbstractImageConverter::convertToFile(const ImageData2D& image, const Containers::StringView filename) { + return image.isCompressed() ? convertToFile(CompressedImageView2D(image), filename) : convertToFile(ImageView2D(image), filename); +} + +#ifdef MAGNUM_BUILD_DEPRECATED bool AbstractImageConverter::exportToFile(const ImageData2D& image, const std::string& filename) { - return image.isCompressed() ? exportToFile(CompressedImageView2D(image), filename) : exportToFile(ImageView2D(image), filename); + return convertToFile(image, filename); } +#endif Debug& operator<<(Debug& debug, const ImageConverterFeature value) { debug << "Trade::ImageConverterFeature" << Debug::nospace; @@ -203,28 +277,28 @@ Debug& operator<<(Debug& debug, const ImageConverterFeature value) { switch(value) { /* LCOV_EXCL_START */ #define _c(v) case ImageConverterFeature::v: return debug << "::" #v; - _c(ConvertImage) - _c(ConvertCompressedImage) - _c(ConvertFile) - _c(ConvertCompressedFile) - _c(ConvertData) - _c(ConvertCompressedData) + _c(Convert2D) + _c(ConvertCompressed2D) + _c(Convert2DToFile) + _c(ConvertCompressed2DToFile) + _c(Convert2DToData) + _c(ConvertCompressed2DToData) #undef _c /* LCOV_EXCL_STOP */ } - return debug << "(" << Debug::nospace << reinterpret_cast(UnsignedByte(value)) << Debug::nospace << ")"; + return debug << "(" << Debug::nospace << reinterpret_cast(UnsignedInt(value)) << Debug::nospace << ")"; } Debug& operator<<(Debug& debug, const ImageConverterFeatures value) { return Containers::enumSetDebugOutput(debug, value, "Trade::ImageConverterFeatures{}", { - ImageConverterFeature::ConvertImage, - ImageConverterFeature::ConvertCompressedImage, - ImageConverterFeature::ConvertData, - ImageConverterFeature::ConvertCompressedData, - /* These are implied by Convert[Compressed]Data, so have to be last */ - ImageConverterFeature::ConvertFile, - ImageConverterFeature::ConvertCompressedFile}); + ImageConverterFeature::Convert2D, + ImageConverterFeature::ConvertCompressed2D, + ImageConverterFeature::Convert2DToData, + ImageConverterFeature::ConvertCompressed2DToData, + /* These are implied by Convert[Compressed]ToData, so have to be last */ + ImageConverterFeature::Convert2DToFile, + ImageConverterFeature::ConvertCompressed2DToFile}); } Debug& operator<<(Debug& debug, const ImageConverterFlag value) { diff --git a/src/Magnum/Trade/AbstractImageConverter.h b/src/Magnum/Trade/AbstractImageConverter.h index ddcf5127c..a8db45c57 100644 --- a/src/Magnum/Trade/AbstractImageConverter.h +++ b/src/Magnum/Trade/AbstractImageConverter.h @@ -43,44 +43,106 @@ namespace Magnum { namespace Trade { @see @ref ImageConverterFeatures, @ref AbstractImageConverter::features() */ -enum class ImageConverterFeature: UnsignedByte { +enum class ImageConverterFeature: UnsignedInt { /** - * Conversion to image with different format with - * @ref AbstractImageConverter::exportToImage() + * Convert a 2D image with + * @ref AbstractImageConverter::convert(const ImageView2D&) + * @m_since_latest */ - ConvertImage = 1 << 0, + Convert2D = 1 << 0, + #ifdef MAGNUM_BUILD_DEPRECATED /** - * Conversion to compressed image with - * @ref AbstractImageConverter::exportToCompressedImage() + * @copydoc ImageConverterFeature::Convert2D + * @m_deprecated_since_latest Use @ref ImageConverterFeature::Convert2D + * instead. */ - ConvertCompressedImage = 1 << 1, + ConvertImage CORRADE_DEPRECATED_ENUM("use ImageConverterFeature::Convert2D instead") = Convert2D, /** - * Exporting to file with - * @ref AbstractImageConverter::exportToFile(const ImageView2D&, const std::string&) + * @copydoc ImageConverterFeature::Convert2D + * @m_deprecated_since_latest Use @ref ImageConverterFeature::Convert2D + * instead. Since @ref AbstractImageConverter::convert() is now + * capable of returning both uncompressed and compressed images, this + * feature is the same as @ref ImageConverterFeature::Convert2D, as + * opposed to @ref ImageConverterFeature::ConvertCompressed2D, which + * is about *input* images. */ - ConvertFile = 1 << 2, + ConvertCompressedImage CORRADE_DEPRECATED_ENUM("use ImageConverterFeature::Convert2D instead") = Convert2D, + #endif /** - * Exporting to file with - * @ref AbstractImageConverter::exportToFile(const CompressedImageView2D&, const std::string&) + * Convert a compressed 2D image with + * @ref AbstractImageConverter::convert(const CompressedImageView2D&) + * @m_since_latest */ - ConvertCompressedFile = 1 << 3, + ConvertCompressed2D = 1 << 1, /** - * Exporting to raw data with - * @ref AbstractImageConverter::exportToData(const ImageView2D&). - * Implies @ref ImageConverterFeature::ConvertFile. + * Convert a 2D image to a file with + * @ref AbstractImageConverter::convertToFile(const ImageView2D&, Containers::StringView) + * @m_since_latest */ - ConvertData = ConvertFile|(1 << 4), + Convert2DToFile = 1 << 2, + #ifdef MAGNUM_BUILD_DEPRECATED /** - * Exporting compressed image to raw data with - * @ref AbstractImageConverter::exportToData(const CompressedImageView2D&). - * Implies @ref ImageConverterFeature::ConvertCompressedFile. + * @copydoc ImageConverterFeature::Convert2DToFile + * @m_deprecated_since_latest Use + * @ref ImageConverterFeature::Convert2DToFile instead. */ - ConvertCompressedData = ConvertCompressedFile|(1 << 4) + ConvertFile CORRADE_DEPRECATED_ENUM("use ImageConverterFeature::Convert2DToFile instead") = Convert2DToFile, + #endif + + /** + * Convert a compressed 2D image to a file with + * @ref AbstractImageConverter::convertToFile(const CompressedImageView2D&, Containers::StringView) + * @m_since_latest + */ + ConvertCompressed2DToFile = 1 << 3, + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copydoc ImageConverterFeature::ConvertCompressed2DToFile + * @m_deprecated_since_latest Use + * @ref ImageConverterFeature::ConvertCompressed2DToFile instead. + */ + ConvertCompressedFile CORRADE_DEPRECATED_ENUM("use ImageConverterFeature::ConvertCompressed2DToFile instead") = ConvertCompressed2DToFile, + #endif + + /** + * Convert a 2D image to raw data with + * @ref AbstractImageConverter::convertToData(const ImageView2D&). + * Implies @ref ImageConverterFeature::Convert2DToFile. + * @m_since_latest + */ + Convert2DToData = Convert2DToFile|(1 << 4), + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copydoc ImageConverterFeature::Convert2DToData + * @m_deprecated_since_latest Use + * @ref ImageConverterFeature::Convert2DToData instead. + */ + ConvertData CORRADE_DEPRECATED_ENUM("use ImageConverterFeature::Convert2DToData instead") = Convert2DToData, + #endif + + /** + * Convert a compressed 2D image to raw data with + * @ref AbstractImageConverter::convertToData(const CompressedImageView2D&). + * Implies @ref ImageConverterFeature::ConvertCompressed2DToFile. + * @m_since_latest + */ + ConvertCompressed2DToData = ConvertCompressed2DToFile|(1 << 4), + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copydoc ImageConverterFeature::ConvertCompressed2DToData + * @m_deprecated_since_latest Use + * @ref ImageConverterFeature::ConvertCompressed2DToData instead. + */ + ConvertCompressedData CORRADE_DEPRECATED_ENUM("use ImageConverterFeature::ConvertCompressed2DToData instead") = ConvertCompressed2DToData, + #endif }; /** @@ -170,24 +232,24 @@ the plugin module has been unloaded. @section Trade-AbstractImageConverter-subclassing Subclassing The plugin needs to implement the @ref doFeatures() function and one or more of -@ref doExportToImage(), @ref doExportToCompressedImage(), @ref doExportToData() -or @ref doExportToFile() functions based on what features are supported. +@ref doConvert(), @ref doConvertToData() or @ref doConvertToFile() functions +based on what features are supported. You don't need to do most of the redundant sanity checks, these things are checked by the implementation: -- The function @ref doExportToImage() is called only if - @ref ImageConverterFeature::ConvertImage is supported. -- The function @ref doExportToCompressedImage() is called only if - @ref ImageConverterFeature::ConvertCompressedImage is supported. -- The function @ref doExportToData(const ImageView2D&) is called only if - @ref ImageConverterFeature::ConvertData is supported. -- The function @ref doExportToData(const CompressedImageView2D&) is called - only if @ref ImageConverterFeature::ConvertCompressedData is supported. -- The function @ref doExportToFile(const ImageView2D&, const std::string&) is - called only if @ref ImageConverterFeature::ConvertFile is supported. -- The function @ref doExportToFile(const CompressedImageView2D&, const std::string&) - is called only if @ref ImageConverterFeature::ConvertCompressedFile is +- The function @ref doConvert(const ImageView2D&) is called only if + @ref ImageConverterFeature::Convert2D is supported. +- The function @ref doConvert(const CompressedImageView2D&) is called only if + @ref ImageConverterFeature::ConvertCompressed2D is supported. +- The function @ref doConvertToData(const ImageView2D&) is called only if + @ref ImageConverterFeature::Convert2DToData is supported. +- The function @ref doConvertToData(const CompressedImageView2D&) is called + only if @ref ImageConverterFeature::ConvertCompressed2DToData is supported. +- The function @ref doConvertToFile(const ImageView2D&, Containers::StringView) + is called only if @ref ImageConverterFeature::Convert2DToFile is supported. +- The function @ref doConvertToFile(const CompressedImageView2D&, Containers::StringView) + is called only if @ref ImageConverterFeature::ConvertCompressed2DToFile is supported. @m_class{m-block m-warning} @@ -292,86 +354,194 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract void clearFlags(ImageConverterFlags flags); /** - * @brief Convert image to different format + * @brief Convert a 2D image + * @m_since_latest * - * Available only if @ref ImageConverterFeature::ConvertImage is + * Available only if @ref ImageConverterFeature::Convert2D is * supported. Returns converted image on success, - * @ref Containers::NullOpt otherwise. - * @see @ref features(), @ref exportToData(), @ref exportToFile() + * @ref Containers::NullOpt otherwise. The implementation is allowed to + * return both a compressed an an uncompressed image, see documentation + * of a particular converter for more information. + * @see @ref features(), @ref convert(const CompressedImageView2D&), + * @ref convert(const ImageData2D&), @ref convertToData(), + * @ref convertToFile(), @ref ImageData::isCompressed() */ - Containers::Optional exportToImage(const ImageView2D& image); + Containers::Optional convert(const ImageView2D& image); + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Convert image to compressed format + * @brief @copybrief convert(const ImageView2D&) + * @m_deprecated_since_latest Use @ref convert(const ImageView2D&) + * instead. + */ + CORRADE_DEPRECATED("use convert(const ImageView2D&) instead") Containers::Optional exportToImage(const ImageView2D& image); + + /** + * @brief Convert a 2D image to compressed format + * @m_deprecated_since_latest Use @ref convert(const ImageView2D&) + * instead. + */ + CORRADE_DEPRECATED("use convert(const ImageView2D&) instead") Containers::Optional exportToCompressedImage(const ImageView2D& image); + #endif + + /** + * @brief Convert a compressed 2D image + * @m_since_latest * - * Available only if @ref ImageConverterFeature::ConvertCompressedImage - * is supported. Returns converted image on success, - * @ref Containers::NullOpt otherwise. - * @see @ref features(), @ref exportToData(), @ref exportToFile() + * Available only if @ref ImageConverterFeature::ConvertCompressed2D is + * supported. Returns converted image on success, + * @ref Containers::NullOpt otherwise. The implementation is allowed to + * return both a compressed an an uncompressed image, see documentation + * of a particular converter for more information. + * @see @ref features(), @ref convert(const ImageView2D&), + * @ref convert(const ImageData2D&), @ref convertToData(), + * @ref convertToFile(), @ref ImageData::isCompressed() */ - Containers::Optional exportToCompressedImage(const ImageView2D& image); + Containers::Optional convert(const CompressedImageView2D& image); /** - * @brief Export image to raw data + * @brief Convert a 2D image data + * @m_since_latest * - * Available only if @ref ImageConverterFeature::ConvertData is - * supported. Returns data on success, zero-sized array otherwise. - * @see @ref features(), @ref exportToImage(), - * @ref exportToFile(const ImageView2D&, const std::string&) + * Based on whether the image is compressed or not, calls either + * @ref convert(const ImageView2D&) or + * @ref convert(const CompressedImageView2D&). See documentation of + * these two functions for details. + * @see @ref ImageData::isCompressed() */ - Containers::Array exportToData(const ImageView2D& image); + Containers::Optional convert(const ImageData2D& image); /** - * @brief Export compressed image to raw data + * @brief Convert a 2D image to a raw data + * @m_since_latest * - * Available only if @ref ImageConverterFeature::ConvertCompressedData - * is supported. Returns data on success, zero-sized array otherwise. - * @see @ref features(), @ref exportToCompressedImage(), - * @ref exportToFile(const CompressedImageView2D&, const std::string&) + * Available only if @ref ImageConverterFeature::Convert2DToData is + * supported. Returns data on success, @cpp nullptr @ce otherwise. + * @see @ref features(), @ref convertToData(const CompressedImageView2D&), + * @ref convertToData(const ImageData2D&), @ref convert(), + * @ref convertToFile() */ - Containers::Array exportToData(const CompressedImageView2D& image); + Containers::Array convertToData(const ImageView2D& image); + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Export image to raw data + * @brief @copybrief convertToData(const ImageView2D&) + * @m_deprecated_since_latest Use @ref convertToData(const ImageView2D&) + * instead. + */ + CORRADE_DEPRECATED("use convertToData(const ImageView2D&) instead") Containers::Array exportToData(const ImageView2D& image); + #endif + + /** + * @brief Convert a compressed 2D image to a raw data + * @m_since_latest + * + * Available only if @ref ImageConverterFeature::ConvertCompressed2DToData + * is supported. Returns data on success, @cpp nullptr @ce otherwise. + * @see @ref features(), @ref convertToData(const ImageView2D&), + * @ref convertToData(const ImageData2D&), @ref convert(), + * @ref convertToFile() + */ + Containers::Array convertToData(const CompressedImageView2D& image); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief convertToData(const CompressedImageView2D&) + * @m_deprecated_since_latest Use + * @ref convertToData(const CompressedImageView2D&) instead. + */ + CORRADE_DEPRECATED("use convertToData(const CompressedImageView2D&) instead") Containers::Array exportToData(const CompressedImageView2D& image); + #endif + + /** + * @brief Convert a 2D image data to a raw data + * @m_since_latest * * Based on whether the image is compressed or not, calls either - * @ref exportToData(const ImageView2D&) or - * @ref exportToData(const CompressedImageView2D&). See documentation - * of those two functions for details. + * @ref convertToData(const ImageView2D&) or + * @ref convertToData(const CompressedImageView2D&). See documentation + * of these two functions for details. + * @see @ref ImageData::isCompressed() */ - Containers::Array exportToData(const ImageData2D& image); + Containers::Array convertToData(const ImageData2D& image); + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Export image to file + * @brief @copybrief convertToData(const ImageData2D&) + * @m_deprecated_since_latest Use @ref convertToData(const ImageData2D&) + * instead. + */ + CORRADE_DEPRECATED("use convertToData(const ImageView2D&) instead") Containers::Array exportToData(const ImageData2D& image); + #endif + + /** + * @brief Convert a 2D image to a file + * @m_since_latest * - * Available only if @ref ImageConverterFeature::ConvertFile or - * @ref ImageConverterFeature::ConvertData is supported. Returns + * Available only if @ref ImageConverterFeature::Convert2DToFile or + * @ref ImageConverterFeature::Convert2DToData is supported. Returns * @cpp true @ce on success, @cpp false @ce otherwise. - * @see @ref features(), @ref exportToImage(), - * @ref exportToData(const ImageView2D&) + * @see @ref features(), @ref convertToFile(const CompressedImageView2D&, Containers::StringView), + * @ref convertToFile(const ImageData2D&, Containers::StringView), + * @ref convert(), @ref convertToData() */ - bool exportToFile(const ImageView2D& image, const std::string& filename); + bool convertToFile(const ImageView2D& image, Containers::StringView filename); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief convertToFile(const ImageView2D&, Containers::StringView) + * @m_deprecated_since_latest Use + * @ref convertToFile(const ImageView2D&, Containers::StringView) + * instead. + */ + CORRADE_DEPRECATED("use convertToFile(const ImageView2D&, Containers::StringView) instead") bool exportToFile(const ImageView2D& image, const std::string& filename); + #endif /** - * @brief Export compressed image to file + * @brief Convert a compressed 2D image to a file + * @m_since_latest * - * Available only if @ref ImageConverterFeature::ConvertCompressedFile - * or @ref ImageConverterFeature::ConvertCompressedData is supported. - * Returns @cpp true @ce on success, @cpp false @ce otherwise. - * @see @ref features(), @ref exportToCompressedImage(), - * @ref exportToData(const CompressedImageView2D&) + * Available only if @ref ImageConverterFeature::ConvertCompressed2DToFile + * or @ref ImageConverterFeature::ConvertCompressed2DToData is + * supported. Returns @cpp true @ce on success, @cpp false @ce + * otherwise. + * @see @ref features(), @ref convertToFile(const ImageView2D&, Containers::StringView), + * @ref convertToFile(const ImageData2D&, Containers::StringView), + * @ref convert(), @ref convertToData() + */ + bool convertToFile(const CompressedImageView2D& image, Containers::StringView filename); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief convertToFile(const CompressedImageView2D&, Containers::StringView) + * @m_deprecated_since_latest Use + * @ref convertToFile(const CompressedImageView2D&, Containers::StringView) + * instead. */ - bool exportToFile(const CompressedImageView2D& image, const std::string& filename); + CORRADE_DEPRECATED("use convertToFile(const CompressedImageView2D&, Containers::StringView) instead") bool exportToFile(const CompressedImageView2D& image, const std::string& filename); + #endif /** - * @brief Export image to file + * @brief Convert a 2D image data to a file + * @m_since_latest * * Based on whether the image is compressed or not, calls either - * @ref exportToFile(const ImageView2D&, const std::string&) or - * @ref exportToFile(const CompressedImageView2D&, const std::string&). - * See documentation of those two functions for details. + * @ref convertToFile(const ImageView2D&, Containers::StringView) or + * @ref convertToFile(const CompressedImageView2D&, Containers::StringView). + * See documentation of these two functions for details. + * @see @ref ImageData::isCompressed() */ - bool exportToFile(const ImageData2D& image, const std::string& filename); + bool convertToFile(const ImageData2D& image, Containers::StringView filename); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief @copybrief convertToFile(const ImageData2D&, Containers::StringView) + * @m_deprecated_since_latest Use + * @ref convertToFile(const ImageData2D&, Containers::StringView) + * instead. + */ + CORRADE_DEPRECATED("use convertToFile(const ImageData2D&, Containers::StringView) instead") bool exportToFile(const ImageData2D& image, const std::string& filename); + #endif private: /** @brief Implementation for @ref features() */ @@ -392,35 +562,49 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract */ virtual void doSetFlags(ImageConverterFlags flags); - /** @brief Implementation for @ref exportToImage() */ - virtual Containers::Optional doExportToImage(const ImageView2D& image); + /** + * @brief Implementation for @ref convert(const ImageView2D&) + * @m_since_latest + */ + virtual Containers::Optional doConvert(const ImageView2D& image); - /** @brief Implementation for @ref exportToCompressedImage() */ - virtual Containers::Optional doExportToCompressedImage(const ImageView2D& image); + /** + * @brief Implementation for @ref convert(const CompressedImageView2D&) + * @m_since_latest + */ + virtual Containers::Optional doConvert(const CompressedImageView2D& image); - /** @brief Implementation for @ref exportToData(const ImageView2D&) */ - virtual Containers::Array doExportToData(const ImageView2D& image); + /** + * @brief Implementation for @ref convertToData(const ImageView2D&) + * @m_since_latest + */ + virtual Containers::Array doConvertToData(const ImageView2D& image); - /** @brief Implementation for @ref exportToData(const CompressedImageView2D&) */ - virtual Containers::Array doExportToData(const CompressedImageView2D& image); + /** + * @brief Implementation for @ref convertToData(const CompressedImageView2D&) + * @m_since_latest + */ + virtual Containers::Array doConvertToData(const CompressedImageView2D& image); /** - * @brief Implementation for @ref exportToFile(const ImageView2D&, const std::string&) + * @brief Implementation for @ref convertToFile(const ImageView2D&, Containers::StringView) + * @m_since_latest * - * If @ref ImageConverterFeature::ConvertData is supported, default - * implementation calls @ref doExportToData(const ImageView2D&) and + * If @ref ImageConverterFeature::Convert2DToData is supported, default + * implementation calls @ref doConvertToData(const ImageView2D&) and * saves the result to given file. */ - virtual bool doExportToFile(const ImageView2D& image, const std::string& filename); + virtual bool doConvertToFile(const ImageView2D& image, Containers::StringView filename); /** - * @brief Implementation for @ref exportToFile(const CompressedImageView2D&, const std::string&) + * @brief Implementation for @ref convertToFile(const CompressedImageView2D&, Containers::StringView) + * @m_since_latest * - * If @ref ImageConverterFeature::ConvertCompressedData is supported, - * default implementation calls @ref doExportToData(const CompressedImageView2D&) + * If @ref ImageConverterFeature::ConvertCompressed2DToData is + * supported, default implementation calls @ref doConvertToData(const CompressedImageView2D&) * and saves the result to given file. */ - virtual bool doExportToFile(const CompressedImageView2D& image, const std::string& filename); + virtual bool doConvertToFile(const CompressedImageView2D& image, Containers::StringView filename); ImageConverterFlags _flags; }; diff --git a/src/Magnum/Trade/ImageData.h b/src/Magnum/Trade/ImageData.h index 54e2b1245..0d8047712 100644 --- a/src/Magnum/Trade/ImageData.h +++ b/src/Magnum/Trade/ImageData.h @@ -675,6 +675,7 @@ template class ImageData { the restriction is pointless when used outside of plugin implementations. */ friend AbstractImporter; + friend AbstractImageConverter; explicit ImageData(CompressedPixelStorage storage, UnsignedInt format, const VectorTypeFor& size, Containers::Array&& data, const void* importerState = nullptr) noexcept; diff --git a/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp b/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp index 4378effe2..bc1eb317e 100644 --- a/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImageConverterTest.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include #include @@ -53,37 +55,39 @@ struct AbstractImageConverterTest: TestSuite::Tester { void thingNotSupported(); - void exportToImage(); - void exportToImageNotImplemented(); - void exportToImageCustomDeleter(); + void convert2D(); + void convert2DNotImplemented(); + void convert2DCustomDeleter(); - void exportToCompressedImage(); - void exportToCompressedImageNotImplemented(); - void exportToCompressedImageCustomDeleter(); + void convertCompressed2D(); + void convertCompressed2DNotImplemented(); + void convertCompressed2DCustomDeleter(); - void exportToData(); - void exportToDataNotImplemented(); - void exportToDataCustomDeleter(); + void convertImageData2D(); - void exportCompressedToData(); - void exportCompressedToDataNotImplemented(); - void exportCompressedToDataCustomDeleter(); + void convert2DToData(); + void convert2DToDataNotImplemented(); + void convert2DToDataCustomDeleter(); - void exportImageDataToData(); + void convertCompressed2DToData(); + void convertCompressed2DToDataNotImplemented(); + void convertCompressed2DToDataCustomDeleter(); - void exportToFile(); - void exportToFileThroughData(); - void exportToFileThroughDataFailed(); - void exportToFileThroughDataNotWritable(); - void exportToFileNotImplemented(); + void convertImageData2DToData(); - void exportCompressedToFile(); - void exportCompressedToFileThroughData(); - void exportCompressedToFileThroughDataFailed(); - void exportCompressedToFileThroughDataNotWritable(); - void exportCompressedToFileNotImplemented(); + void convert2DToFile(); + void convert2DToFileThroughData(); + void convert2DToFileThroughDataFailed(); + void convert2DToFileThroughDataNotWritable(); + void convert2DToFileNotImplemented(); - void exportImageDataToFile(); + void convertCompressed2DToFile(); + void convertCompressed2DToFileThroughData(); + void convertCompressed2DToFileThroughDataFailed(); + void convertCompressed2DToFileThroughDataNotWritable(); + void convertCompressed2DToFileNotImplemented(); + + void convertImageData2DToFile(); void debugFeature(); void debugFeatures(); @@ -100,37 +104,39 @@ AbstractImageConverterTest::AbstractImageConverterTest() { &AbstractImageConverterTest::thingNotSupported, - &AbstractImageConverterTest::exportToImage, - &AbstractImageConverterTest::exportToImageNotImplemented, - &AbstractImageConverterTest::exportToImageCustomDeleter, + &AbstractImageConverterTest::convert2D, + &AbstractImageConverterTest::convert2DNotImplemented, + &AbstractImageConverterTest::convert2DCustomDeleter, + + &AbstractImageConverterTest::convertCompressed2D, + &AbstractImageConverterTest::convertCompressed2DNotImplemented, + &AbstractImageConverterTest::convertCompressed2DCustomDeleter, - &AbstractImageConverterTest::exportToCompressedImage, - &AbstractImageConverterTest::exportToCompressedImageNotImplemented, - &AbstractImageConverterTest::exportToCompressedImageCustomDeleter, + &AbstractImageConverterTest::convertImageData2D, - &AbstractImageConverterTest::exportToData, - &AbstractImageConverterTest::exportToDataNotImplemented, - &AbstractImageConverterTest::exportToDataCustomDeleter, + &AbstractImageConverterTest::convert2DToData, + &AbstractImageConverterTest::convert2DToDataNotImplemented, + &AbstractImageConverterTest::convert2DToDataCustomDeleter, - &AbstractImageConverterTest::exportCompressedToData, - &AbstractImageConverterTest::exportCompressedToDataNotImplemented, - &AbstractImageConverterTest::exportCompressedToDataCustomDeleter, + &AbstractImageConverterTest::convertCompressed2DToData, + &AbstractImageConverterTest::convertCompressed2DToDataNotImplemented, + &AbstractImageConverterTest::convertCompressed2DToDataCustomDeleter, - &AbstractImageConverterTest::exportImageDataToData, + &AbstractImageConverterTest::convertImageData2DToData, - &AbstractImageConverterTest::exportToFile, - &AbstractImageConverterTest::exportToFileThroughData, - &AbstractImageConverterTest::exportToFileThroughDataFailed, - &AbstractImageConverterTest::exportToFileThroughDataNotWritable, - &AbstractImageConverterTest::exportToFileNotImplemented, + &AbstractImageConverterTest::convert2DToFile, + &AbstractImageConverterTest::convert2DToFileThroughData, + &AbstractImageConverterTest::convert2DToFileThroughDataFailed, + &AbstractImageConverterTest::convert2DToFileThroughDataNotWritable, + &AbstractImageConverterTest::convert2DToFileNotImplemented, - &AbstractImageConverterTest::exportCompressedToFile, - &AbstractImageConverterTest::exportCompressedToFileThroughData, - &AbstractImageConverterTest::exportCompressedToFileThroughDataFailed, - &AbstractImageConverterTest::exportCompressedToFileThroughDataNotWritable, - &AbstractImageConverterTest::exportCompressedToFileNotImplemented, + &AbstractImageConverterTest::convertCompressed2DToFile, + &AbstractImageConverterTest::convertCompressed2DToFileThroughData, + &AbstractImageConverterTest::convertCompressed2DToFileThroughDataFailed, + &AbstractImageConverterTest::convertCompressed2DToFileThroughDataNotWritable, + &AbstractImageConverterTest::convertCompressed2DToFileNotImplemented, - &AbstractImageConverterTest::exportImageDataToFile, + &AbstractImageConverterTest::convertImageData2DToFile, &AbstractImageConverterTest::debugFeature, &AbstractImageConverterTest::debugFeatures, @@ -209,241 +215,271 @@ void AbstractImageConverterTest::thingNotSupported() { std::ostringstream out; Error redirectError{&out}; - converter.exportToImage(ImageView2D{PixelFormat::R8Unorm, {4, 6}, Containers::ArrayView{nullptr, 24}}); - converter.exportToCompressedImage(ImageView2D{PixelFormat::R8Unorm, {16, 8}, Containers::ArrayView{nullptr, 128}}); - converter.exportToData(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, Containers::ArrayView{nullptr, 96}}); - converter.exportToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, Containers::ArrayView{nullptr, 64}}); - converter.exportToFile(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, {nullptr, 96}}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out")); - converter.exportToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, {nullptr, 64}}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out")); + converter.convert(ImageView2D{PixelFormat::R8Unorm, {4, 6}, Containers::ArrayView{nullptr, 24}}); + converter.convert(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, {nullptr, 64}}); + converter.convertToData(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, Containers::ArrayView{nullptr, 96}}); + converter.convertToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, Containers::ArrayView{nullptr, 64}}); + converter.convertToFile(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, {nullptr, 96}}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out")); + converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, {nullptr, 64}}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out")); CORRADE_COMPARE(out.str(), - "Trade::AbstractImageConverter::exportToImage(): feature not supported\n" - "Trade::AbstractImageConverter::exportToCompressedImage(): feature not supported\n" - "Trade::AbstractImageConverter::exportToData(): feature not supported\n" - "Trade::AbstractImageConverter::exportToData(): feature not supported\n" - "Trade::AbstractImageConverter::exportToFile(): feature not supported\n" - "Trade::AbstractImageConverter::exportToFile(): feature not supported\n"); + "Trade::AbstractImageConverter::convert(): 2D image conversion not supported\n" + "Trade::AbstractImageConverter::convert(): compressed 2D image conversion not supported\n" + "Trade::AbstractImageConverter::convertToData(): 2D image conversion not supported\n" + "Trade::AbstractImageConverter::convertToData(): compressed 2D image conversion not supported\n" + "Trade::AbstractImageConverter::convertToFile(): 2D image conversion not supported\n" + "Trade::AbstractImageConverter::convertToFile(): compressed 2D image conversion not supported\n"); } -void AbstractImageConverterTest::exportToImage() { +void AbstractImageConverterTest::convert2D() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertImage; } - Containers::Optional doExportToImage(const ImageView2D& image) override { - return Image2D{PixelFormat::RGBA8Unorm, image.size(), Containers::Array{96}}; + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2D; } + Containers::Optional doConvert(const ImageView2D& image) override { + return ImageData2D{PixelFormat::RGBA8Unorm, image.size(), Containers::Array{96}}; } } converter; - Containers::Optional actual = converter.exportToImage(ImageView2D{PixelFormat::R8Unorm, {4, 6}, Containers::ArrayView{nullptr, 24}}); + Containers::Optional actual = converter.convert(ImageView2D{PixelFormat::R8Unorm, {4, 6}, Containers::ArrayView{nullptr, 24}}); CORRADE_VERIFY(actual); + CORRADE_VERIFY(!actual->isCompressed()); CORRADE_COMPARE(actual->data().size(), 96); CORRADE_COMPARE(actual->size(), (Vector2i{4, 6})); } -void AbstractImageConverterTest::exportToImageNotImplemented() { +void AbstractImageConverterTest::convert2DNotImplemented() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertImage; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2D; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToImage(ImageView2D{PixelFormat::R8Unorm, {4, 6}, Containers::ArrayView{nullptr, 128}}); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToImage(): feature advertised but not implemented\n"); + converter.convert(ImageView2D{PixelFormat::R8Unorm, {4, 6}, Containers::ArrayView{nullptr, 128}}); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convert(): 2D image conversion advertised but not implemented\n"); } -void AbstractImageConverterTest::exportToImageCustomDeleter() { +void AbstractImageConverterTest::convert2DCustomDeleter() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertImage; } - Containers::Optional doExportToImage(const ImageView2D&) override { - return Image2D{PixelFormat::RGBA8Unorm, {}, Containers::Array{nullptr, 0, [](char*, std::size_t) {}}}; + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2D; } + Containers::Optional doConvert(const ImageView2D&) override { + return ImageData2D{PixelFormat::RGBA8Unorm, {}, Containers::Array{nullptr, 0, [](char*, std::size_t) {}}}; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToImage(ImageView2D{PixelFormat::R8Unorm, {}}); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToImage(): implementation is not allowed to use a custom Array deleter\n"); + converter.convert(ImageView2D{PixelFormat::R8Unorm, {}}); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convert(): implementation is not allowed to use a custom Array deleter\n"); } -void AbstractImageConverterTest::exportToCompressedImage() { +void AbstractImageConverterTest::convertCompressed2D() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedImage; } - Containers::Optional doExportToCompressedImage(const ImageView2D& image) override { - return CompressedImage2D{CompressedPixelFormat::Bc1RGBAUnorm, image.size(), Containers::Array{64}}; + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2D; } + Containers::Optional doConvert(const CompressedImageView2D& image) override { + return ImageData2D{image.format(), image.size(), Containers::Array{64}}; } } converter; - Containers::Optional actual = converter.exportToCompressedImage(ImageView2D{PixelFormat::R8Unorm, {16, 8}, Containers::ArrayView{nullptr, 128}}); + Containers::Optional actual = converter.convert(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, Containers::ArrayView{nullptr, 128}}); CORRADE_VERIFY(actual); + CORRADE_VERIFY(actual->isCompressed()); CORRADE_COMPARE(actual->data().size(), 64); CORRADE_COMPARE(actual->size(), (Vector2i{16, 8})); } -void AbstractImageConverterTest::exportToCompressedImageNotImplemented() { +void AbstractImageConverterTest::convertCompressed2DNotImplemented() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedImage; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2D; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToCompressedImage(ImageView2D{PixelFormat::R8Unorm, {16, 8}, Containers::ArrayView{nullptr, 128}}); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToCompressedImage(): feature advertised but not implemented\n"); + converter.convert(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, Containers::ArrayView{nullptr, 128}}); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convert(): compressed 2D image conversion advertised but not implemented\n"); } -void AbstractImageConverterTest::exportToCompressedImageCustomDeleter() { +void AbstractImageConverterTest::convertCompressed2DCustomDeleter() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedImage; } - Containers::Optional doExportToCompressedImage(const ImageView2D&) override { - return CompressedImage2D{CompressedPixelFormat::Bc1RGBAUnorm, {}, Containers::Array{nullptr, 0, [](char*, std::size_t) {}}}; + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2D; } + Containers::Optional doConvert(const CompressedImageView2D&) override { + return ImageData2D{CompressedPixelFormat::Bc1RGBAUnorm, {}, Containers::Array{nullptr, 0, [](char*, std::size_t) {}}}; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToCompressedImage(ImageView2D{PixelFormat::R8Unorm, {}}); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToCompressedImage(): implementation is not allowed to use a custom Array deleter\n"); + converter.convert(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {}}); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convert(): implementation is not allowed to use a custom Array deleter\n"); } -void AbstractImageConverterTest::exportToData() { +void AbstractImageConverterTest::convertImageData2D() { + struct: Trade::AbstractImageConverter { + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2D|ImageConverterFeature::ConvertCompressed2D; } + + Containers::Optional doConvert(const ImageView2D&) override { + return ImageData2D{PixelFormat::R8Unorm, {}, Containers::array({'B'})}; + }; + + Containers::Optional doConvert(const CompressedImageView2D&) override { + return ImageData2D{PixelFormat::R8Unorm, {}, Containers::array({'C'})}; + }; + } converter; + + { + /* Should get "B" when converting uncompressed */ + ImageData2D image{PixelFormat::RGBA8Unorm, {}, nullptr}; + Containers::Optional out = converter.convert(image); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(out->data(), + Containers::arrayView({'B'}), + TestSuite::Compare::Container); + } { + /* Should get "C" when converting compressed */ + ImageData2D image{CompressedPixelFormat::Bc1RGBUnorm, {}, nullptr}; + Containers::Optional out = converter.convert(image); + CORRADE_VERIFY(out); + CORRADE_COMPARE_AS(out->data(), + Containers::arrayView({'C'}), + TestSuite::Compare::Container); + } +} + +void AbstractImageConverterTest::convert2DToData() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertData; } - Containers::Array doExportToData(const ImageView2D& image) override { + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } + Containers::Array doConvertToData(const ImageView2D& image) override { return Containers::Array{nullptr, std::size_t(image.size().product())}; } } converter; - Containers::Array actual = converter.exportToData(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, Containers::ArrayView{nullptr, 96}}); + Containers::Array actual = converter.convertToData(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, Containers::ArrayView{nullptr, 96}}); CORRADE_COMPARE(actual.size(), 24); } -void AbstractImageConverterTest::exportToDataNotImplemented() { +void AbstractImageConverterTest::convert2DToDataNotImplemented() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertData; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToData(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, Containers::ArrayView{nullptr, 96}}); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToData(): feature advertised but not implemented\n"); + converter.convertToData(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, Containers::ArrayView{nullptr, 96}}); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convertToData(): 2D image conversion advertised but not implemented\n"); } -void AbstractImageConverterTest::exportToDataCustomDeleter() { +void AbstractImageConverterTest::convert2DToDataCustomDeleter() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertData; } - Containers::Array doExportToData(const ImageView2D&) override { + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } + Containers::Array doConvertToData(const ImageView2D&) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToData(ImageView2D{PixelFormat::RGBA8Unorm, {}}); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToData(): implementation is not allowed to use a custom Array deleter\n"); + converter.convertToData(ImageView2D{PixelFormat::RGBA8Unorm, {}}); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter\n"); } -void AbstractImageConverterTest::exportCompressedToData() { +void AbstractImageConverterTest::convertCompressed2DToData() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedData; } - Containers::Array doExportToData(const CompressedImageView2D& image) override { + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } + Containers::Array doConvertToData(const CompressedImageView2D& image) override { return Containers::Array{nullptr, std::size_t(image.size().product())}; } } converter; - Containers::Array actual = converter.exportToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, Containers::ArrayView{nullptr, 64}}); + Containers::Array actual = converter.convertToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, Containers::ArrayView{nullptr, 64}}); CORRADE_COMPARE(actual.size(), 128); } -void AbstractImageConverterTest::exportCompressedToDataNotImplemented() { +void AbstractImageConverterTest::convertCompressed2DToDataNotImplemented() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertData; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, Containers::ArrayView{nullptr, 64}}); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToData(): feature advertised but not implemented\n"); + converter.convertToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, Containers::ArrayView{nullptr, 64}}); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convertToData(): compressed 2D image conversion advertised but not implemented\n"); } -void AbstractImageConverterTest::exportCompressedToDataCustomDeleter() { +void AbstractImageConverterTest::convertCompressed2DToDataCustomDeleter() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedData; } - Containers::Array doExportToData(const CompressedImageView2D&) override { + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } + Containers::Array doConvertToData(const CompressedImageView2D&) override { return Containers::Array{nullptr, 0, [](char*, std::size_t) {}}; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {}}); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToData(): implementation is not allowed to use a custom Array deleter\n"); + converter.convertToData(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {}}); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convertToData(): implementation is not allowed to use a custom Array deleter\n"); } /* Used by convertImageDataToData() and convertImageDataToFile() */ -class ImageDataConverter: public Trade::AbstractImageConverter { +class ImageData2DConverter: public Trade::AbstractImageConverter { private: - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertData|ImageConverterFeature::ConvertCompressedData; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData|ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doExportToData(const ImageView2D&) override { + Containers::Array doConvertToData(const ImageView2D&) override { return Containers::array({'B'}); }; - Containers::Array doExportToData(const CompressedImageView2D&) override { + Containers::Array doConvertToData(const CompressedImageView2D&) override { return Containers::array({'C'}); }; }; -void AbstractImageConverterTest::exportImageDataToData() { - ImageDataConverter converter; +void AbstractImageConverterTest::convertImageData2DToData() { + ImageData2DConverter converter; - { - /* Should get "B" when converting uncompressed */ - ImageData2D image{PixelFormat::RGBA8Unorm, {}, nullptr}; - CORRADE_COMPARE_AS(converter.exportToData(image), - Containers::arrayView({'B'}), - TestSuite::Compare::Container); - } { - /* Should get "C" when converting compressed */ - ImageData2D image{CompressedPixelFormat::Bc1RGBUnorm, {}, nullptr}; - CORRADE_COMPARE_AS(converter.exportToData(image), - Containers::arrayView({'C'}), - TestSuite::Compare::Container); - } + /* Should get "B" when converting uncompressed */ + CORRADE_COMPARE_AS(converter.convertToData(ImageData2D{PixelFormat::RGBA8Unorm, {}, nullptr}), + Containers::arrayView({'B'}), + TestSuite::Compare::Container); + + /* Should get "C" when converting compressed */ + CORRADE_COMPARE_AS(converter.convertToData(ImageData2D{CompressedPixelFormat::Bc1RGBUnorm, {}, nullptr}), + Containers::arrayView({'C'}), + TestSuite::Compare::Container); } -void AbstractImageConverterTest::exportToFile() { +void AbstractImageConverterTest::convert2DToFile() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertData; } - bool doExportToFile(const ImageView2D& image, const std::string& filename) override { + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToFile; } + bool doConvertToFile(const ImageView2D& image, Containers::StringView filename) override { return Utility::Directory::write(filename, Containers::arrayView( {char(image.size().x()), char(image.size().y())})); } @@ -455,16 +491,16 @@ void AbstractImageConverterTest::exportToFile() { Utility::Directory::rm(filename); CORRADE_VERIFY(!Utility::Directory::exists(filename)); - CORRADE_VERIFY(converter.exportToFile(ImageView2D{PixelFormat::RGBA8Unorm, {0xf0, 0x0d}, {nullptr, 0xf0*0x0d*4}}, filename)); + CORRADE_VERIFY(converter.convertToFile(ImageView2D{PixelFormat::RGBA8Unorm, {0xf0, 0x0d}, {nullptr, 0xf0*0x0d*4}}, filename)); CORRADE_COMPARE_AS(filename, "\xf0\x0d", TestSuite::Compare::FileToString); } -void AbstractImageConverterTest::exportToFileThroughData() { +void AbstractImageConverterTest::convert2DToFileThroughData() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertData; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } - Containers::Array doExportToData(const ImageView2D& image) override { + Containers::Array doConvertToData(const ImageView2D& image) override { return Containers::array({char(image.size().x()), char(image.size().y())}); }; } converter; @@ -475,17 +511,17 @@ void AbstractImageConverterTest::exportToFileThroughData() { Utility::Directory::rm(filename); CORRADE_VERIFY(!Utility::Directory::exists(filename)); - /* doExportToFile() should call doExportToData() */ - CORRADE_VERIFY(converter.exportToFile(ImageView2D(PixelFormat::RGBA8Unorm, {0xfe, 0xed}, {nullptr, 0xfe*0xed*4}), filename)); + /* doConvertToFile() should call doConvertToData() */ + CORRADE_VERIFY(converter.convertToFile(ImageView2D(PixelFormat::RGBA8Unorm, {0xfe, 0xed}, {nullptr, 0xfe*0xed*4}), filename)); CORRADE_COMPARE_AS(filename, "\xfe\xed", TestSuite::Compare::FileToString); } -void AbstractImageConverterTest::exportToFileThroughDataFailed() { +void AbstractImageConverterTest::convert2DToFileThroughDataFailed() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertData; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } - Containers::Array doExportToData(const ImageView2D&) override { + Containers::Array doConvertToData(const ImageView2D&) override { return {}; }; } converter; @@ -500,47 +536,47 @@ void AbstractImageConverterTest::exportToFileThroughDataFailed() { should be printed (the base implementation assumes the plugin does it) */ std::ostringstream out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.exportToFile(ImageView2D(PixelFormat::RGBA8Unorm, {0xfe, 0xed}, {nullptr, 0xfe*0xed*4}), filename)); + CORRADE_VERIFY(!converter.convertToFile(ImageView2D(PixelFormat::RGBA8Unorm, {0xfe, 0xed}, {nullptr, 0xfe*0xed*4}), filename)); CORRADE_VERIFY(!Utility::Directory::exists(filename)); CORRADE_COMPARE(out.str(), ""); } -void AbstractImageConverterTest::exportToFileThroughDataNotWritable() { +void AbstractImageConverterTest::convert2DToFileThroughDataNotWritable() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertData; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToData; } - Containers::Array doExportToData(const ImageView2D& image) override { + Containers::Array doConvertToData(const ImageView2D& image) override { return Containers::array({char(image.size().x()), char(image.size().y())}); }; } converter; std::ostringstream out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.exportToFile(ImageView2D{PixelFormat::RGBA8Unorm, {0xfe, 0xed}, {nullptr, 0xfe*0xed*4}}, "/some/path/that/does/not/exist")); + CORRADE_VERIFY(!converter.convertToFile(ImageView2D{PixelFormat::RGBA8Unorm, {0xfe, 0xed}, {nullptr, 0xfe*0xed*4}}, "/some/path/that/does/not/exist")); CORRADE_COMPARE(out.str(), "Utility::Directory::write(): can't open /some/path/that/does/not/exist\n" - "Trade::AbstractImageConverter::exportToFile(): cannot write to file /some/path/that/does/not/exist\n"); + "Trade::AbstractImageConverter::convertToFile(): cannot write to file /some/path/that/does/not/exist\n"); } -void AbstractImageConverterTest::exportToFileNotImplemented() { +void AbstractImageConverterTest::convert2DToFileNotImplemented() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertFile; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::Convert2DToFile; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToFile(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, {nullptr, 96}}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out")); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToFile(): feature advertised but not implemented\n"); + converter.convertToFile(ImageView2D{PixelFormat::RGBA8Unorm, {4, 6}, {nullptr, 96}}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out")); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convertToFile(): 2D image conversion advertised but not implemented\n"); } -void AbstractImageConverterTest::exportCompressedToFile() { +void AbstractImageConverterTest::convertCompressed2DToFile() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedFile; } - bool doExportToFile(const CompressedImageView2D& image, const std::string& filename) override { + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToFile; } + bool doConvertToFile(const CompressedImageView2D& image, Containers::StringView filename) override { return Utility::Directory::write(filename, Containers::arrayView( {char(image.size().x()), char(image.size().y())})); } @@ -552,16 +588,16 @@ void AbstractImageConverterTest::exportCompressedToFile() { Utility::Directory::rm(filename); CORRADE_VERIFY(!Utility::Directory::exists(filename)); - CORRADE_VERIFY(converter.exportToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {0xd0, 0x0d}, {nullptr, 64}}, filename)); + CORRADE_VERIFY(converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {0xd0, 0x0d}, {nullptr, 64}}, filename)); CORRADE_COMPARE_AS(filename, "\xd0\x0d", TestSuite::Compare::FileToString); } -void AbstractImageConverterTest::exportCompressedToFileThroughData() { +void AbstractImageConverterTest::convertCompressed2DToFileThroughData() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedData; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doExportToData(const CompressedImageView2D& image) override { + Containers::Array doConvertToData(const CompressedImageView2D& image) override { return Containers::array({char(image.size().x()), char(image.size().y())}); }; } converter; @@ -572,17 +608,17 @@ void AbstractImageConverterTest::exportCompressedToFileThroughData() { Utility::Directory::rm(filename); CORRADE_VERIFY(!Utility::Directory::exists(filename)); - /* doExportToFile() should call doExportToData() */ - CORRADE_VERIFY(converter.exportToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {0xb0, 0xd9}, {nullptr, 64}}, filename)); + /* doConvertToFile() should call doConvertToData() */ + CORRADE_VERIFY(converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {0xb0, 0xd9}, {nullptr, 64}}, filename)); CORRADE_COMPARE_AS(filename, "\xb0\xd9", TestSuite::Compare::FileToString); } -void AbstractImageConverterTest::exportCompressedToFileThroughDataFailed() { +void AbstractImageConverterTest::convertCompressed2DToFileThroughDataFailed() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedData; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doExportToData(const CompressedImageView2D&) override { + Containers::Array doConvertToData(const CompressedImageView2D&) override { return {}; }; } converter; @@ -597,73 +633,69 @@ void AbstractImageConverterTest::exportCompressedToFileThroughDataFailed() { should be printed (the base implementation assumes the plugin does it) */ std::ostringstream out; Error redirectError{&out}; - CORRADE_VERIFY(!converter.exportToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {0xb0, 0xd9}, {nullptr, 64}}, filename)); + CORRADE_VERIFY(!converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {0xb0, 0xd9}, {nullptr, 64}}, filename)); CORRADE_VERIFY(!Utility::Directory::exists(filename)); CORRADE_COMPARE(out.str(), ""); } -void AbstractImageConverterTest::exportCompressedToFileThroughDataNotWritable() { +void AbstractImageConverterTest::convertCompressed2DToFileThroughDataNotWritable() { struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedData; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToData; } - Containers::Array doExportToData(const CompressedImageView2D& image) override { + Containers::Array doConvertToData(const CompressedImageView2D& image) override { return Containers::array({char(image.size().x()), char(image.size().y())}); }; } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, {nullptr, 64}}, "/some/path/that/does/not/exist"); + converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, {nullptr, 64}}, "/some/path/that/does/not/exist"); CORRADE_COMPARE(out.str(), "Utility::Directory::write(): can't open /some/path/that/does/not/exist\n" - "Trade::AbstractImageConverter::exportToFile(): cannot write to file /some/path/that/does/not/exist\n"); + "Trade::AbstractImageConverter::convertToFile(): cannot write to file /some/path/that/does/not/exist\n"); } -void AbstractImageConverterTest::exportCompressedToFileNotImplemented() { +void AbstractImageConverterTest::convertCompressed2DToFileNotImplemented() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); #endif struct: AbstractImageConverter { - ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressedFile; } + ImageConverterFeatures doFeatures() const override { return ImageConverterFeature::ConvertCompressed2DToFile; } } converter; std::ostringstream out; Error redirectError{&out}; - converter.exportToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, {nullptr, 64}}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out")); - CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::exportToFile(): feature advertised but not implemented\n"); + converter.convertToFile(CompressedImageView2D{CompressedPixelFormat::Bc1RGBAUnorm, {16, 8}, {nullptr, 64}}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out")); + CORRADE_COMPARE(out.str(), "Trade::AbstractImageConverter::convertToFile(): compressed 2D image conversion advertised but not implemented\n"); } -void AbstractImageConverterTest::exportImageDataToFile() { - ImageDataConverter converter; +void AbstractImageConverterTest::convertImageData2DToFile() { + ImageData2DConverter converter; - { - /* Should get "B" when converting uncompressed */ - ImageData2D image{PixelFormat::RGBA16F, {}, nullptr}; - CORRADE_VERIFY(converter.exportToFile(image, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); - CORRADE_COMPARE_AS(Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out"), - "B", TestSuite::Compare::FileToString); - } { - /* Should get "C" when converting compressed */ - ImageData2D image{CompressedPixelFormat::Bc2RGBAUnorm, {}, nullptr}; - CORRADE_VERIFY(converter.exportToFile(image, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); - CORRADE_COMPARE_AS(Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out"), - "C", TestSuite::Compare::FileToString); - } + /* Should get "B" when converting uncompressed */ + CORRADE_VERIFY(converter.convertToFile(ImageData2D{PixelFormat::RGBA16F, {}, nullptr}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_COMPARE_AS(Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out"), + "B", TestSuite::Compare::FileToString); + + /* Should get "C" when converting compressed */ + CORRADE_VERIFY(converter.convertToFile(ImageData2D{CompressedPixelFormat::Bc2RGBAUnorm, {}, nullptr}, Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out"))); + CORRADE_COMPARE_AS(Utility::Directory::join(TRADE_TEST_OUTPUT_DIR, "image.out"), + "C", TestSuite::Compare::FileToString); } void AbstractImageConverterTest::debugFeature() { std::ostringstream out; - Debug{&out} << ImageConverterFeature::ConvertCompressedImage << ImageConverterFeature(0xf0); - CORRADE_COMPARE(out.str(), "Trade::ImageConverterFeature::ConvertCompressedImage Trade::ImageConverterFeature(0xf0)\n"); + Debug{&out} << ImageConverterFeature::ConvertCompressed2D << ImageConverterFeature(0xdeadbeef); + CORRADE_COMPARE(out.str(), "Trade::ImageConverterFeature::ConvertCompressed2D Trade::ImageConverterFeature(0xdeadbeef)\n"); } void AbstractImageConverterTest::debugFeatures() { std::ostringstream out; - Debug{&out} << (ImageConverterFeature::ConvertData|ImageConverterFeature::ConvertCompressedFile) << ImageConverterFeatures{}; - CORRADE_COMPARE(out.str(), "Trade::ImageConverterFeature::ConvertData|Trade::ImageConverterFeature::ConvertCompressedFile Trade::ImageConverterFeatures{}\n"); + Debug{&out} << (ImageConverterFeature::Convert2DToData|ImageConverterFeature::ConvertCompressed2DToFile) << ImageConverterFeatures{}; + CORRADE_COMPARE(out.str(), "Trade::ImageConverterFeature::Convert2DToData|Trade::ImageConverterFeature::ConvertCompressed2DToFile Trade::ImageConverterFeatures{}\n"); } void AbstractImageConverterTest::debugFlag() { diff --git a/src/Magnum/Trade/imageconverter.cpp b/src/Magnum/Trade/imageconverter.cpp index 27dc0001f..17a304e5a 100644 --- a/src/Magnum/Trade/imageconverter.cpp +++ b/src/Magnum/Trade/imageconverter.cpp @@ -332,7 +332,7 @@ key=true; configuration subgroups are delimited with /.)") Implementation::setOptions(*converter, args.value("converter-options")); /* Save output file */ - if(!converter->exportToFile(*image, output)) { + if(!converter->convertToFile(*image, output)) { Error() << "Cannot save file" << output; return 5; } diff --git a/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.cpp b/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.cpp index b25b90c55..c92cbae8a 100644 --- a/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.cpp +++ b/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.cpp @@ -25,6 +25,8 @@ #include "AnyImageConverter.h" +#include +#include /* for Directory */ #include #include #include @@ -42,10 +44,10 @@ AnyImageConverter::AnyImageConverter(PluginManager::AbstractManager& manager, co AnyImageConverter::~AnyImageConverter() = default; ImageConverterFeatures AnyImageConverter::doFeatures() const { - return ImageConverterFeature::ConvertFile|ImageConverterFeature::ConvertCompressedFile; + return ImageConverterFeature::Convert2DToFile|ImageConverterFeature::ConvertCompressed2DToFile; } -bool AnyImageConverter::doExportToFile(const ImageView2D& image, const std::string& filename) { +bool AnyImageConverter::doConvertToFile(const ImageView2D& image, const Containers::StringView filename) { CORRADE_INTERNAL_ASSERT(manager()); /** @todo lowercase only the extension, once Directory::split() is done */ @@ -73,18 +75,18 @@ bool AnyImageConverter::doExportToFile(const ImageView2D& image, const std::stri Utility::String::endsWith(normalized, ".vst")) plugin = "TgaImageConverter"; else { - Error{} << "Trade::AnyImageConverter::exportToFile(): cannot determine the format of" << filename; + Error{} << "Trade::AnyImageConverter::convertToFile(): cannot determine the format of" << filename; return false; } /* Try to load the plugin */ if(!(manager()->load(plugin) & PluginManager::LoadState::Loaded)) { - Error{} << "Trade::AnyImageConverter::exportToFile(): cannot load the" << plugin << "plugin"; + Error{} << "Trade::AnyImageConverter::convertToFile(): cannot load the" << plugin << "plugin"; return false; } if(flags() & ImageConverterFlag::Verbose) { Debug d; - d << "Trade::AnyImageConverter::exportToFile(): using" << plugin; + d << "Trade::AnyImageConverter::convertToFile(): using" << plugin; PluginManager::PluginMetadata* metadata = manager()->metadata(plugin); CORRADE_INTERNAL_ASSERT(metadata); if(plugin != metadata->name()) @@ -97,19 +99,19 @@ bool AnyImageConverter::doExportToFile(const ImageView2D& image, const std::stri /* Try to convert the file (error output should be printed by the plugin itself) */ - return converter->exportToFile(image, filename); + return converter->convertToFile(image, filename); } -bool AnyImageConverter::doExportToFile(const CompressedImageView2D&, const std::string& filename) { +bool AnyImageConverter::doConvertToFile(const CompressedImageView2D&, const Containers::StringView filename) { CORRADE_INTERNAL_ASSERT(manager()); /* No file formats to store compressed data yet */ - Error{} << "Trade::AnyImageConverter::exportToFile(): cannot determine the format of" << filename << "to store compressed data"; + Error{} << "Trade::AnyImageConverter::convertToFile(): cannot determine the format of" << filename << "to store compressed data"; return false; } }} CORRADE_PLUGIN_REGISTER(AnyImageConverter, Magnum::Trade::AnyImageConverter, - "cz.mosra.magnum.Trade.AbstractImageConverter/0.2.1") + "cz.mosra.magnum.Trade.AbstractImageConverter/0.3") diff --git a/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.h b/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.h index d37fa26da..c2133b902 100644 --- a/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.h +++ b/src/MagnumPlugins/AnyImageConverter/AnyImageConverter.h @@ -117,8 +117,8 @@ class MAGNUM_ANYIMAGECONVERTER_EXPORT AnyImageConverter: public AbstractImageCon private: MAGNUM_ANYIMAGECONVERTER_LOCAL ImageConverterFeatures doFeatures() const override; - MAGNUM_ANYIMAGECONVERTER_LOCAL bool doExportToFile(const ImageView2D& image, const std::string& filename) override; - MAGNUM_ANYIMAGECONVERTER_LOCAL bool doExportToFile(const CompressedImageView2D& image, const std::string& filename) override; + MAGNUM_ANYIMAGECONVERTER_LOCAL bool doConvertToFile(const ImageView2D& image, Containers::StringView filename) override; + MAGNUM_ANYIMAGECONVERTER_LOCAL bool doConvertToFile(const CompressedImageView2D& image, Containers::StringView filename) override; }; }} diff --git a/src/MagnumPlugins/AnyImageConverter/Test/AnyImageConverterTest.cpp b/src/MagnumPlugins/AnyImageConverter/Test/AnyImageConverterTest.cpp index 11be20553..6bf445a5c 100644 --- a/src/MagnumPlugins/AnyImageConverter/Test/AnyImageConverterTest.cpp +++ b/src/MagnumPlugins/AnyImageConverter/Test/AnyImageConverterTest.cpp @@ -24,6 +24,7 @@ */ #include +#include #include #include #include @@ -121,7 +122,7 @@ void AnyImageConverterTest::convert() { /* Just test that the exported file exists */ Containers::Pointer converter = _manager.instantiate("AnyImageConverter"); - CORRADE_VERIFY(converter->exportToFile(Image, filename)); + CORRADE_VERIFY(converter->convertToFile(Image, filename)); CORRADE_VERIFY(Utility::Directory::exists(filename)); } @@ -133,14 +134,14 @@ void AnyImageConverterTest::detect() { std::ostringstream out; Error redirectError{&out}; - CORRADE_VERIFY(!converter->exportToFile(Image, data.filename)); + CORRADE_VERIFY(!converter->convertToFile(Image, data.filename)); /* Can't use raw string literals in macros on GCC 4.8 */ #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT CORRADE_COMPARE(out.str(), Utility::formatString( -"PluginManager::Manager::load(): plugin {0} is not static and was not found in nonexistent\nTrade::AnyImageConverter::exportToFile(): cannot load the {0} plugin\n", data.plugin)); +"PluginManager::Manager::load(): plugin {0} is not static and was not found in nonexistent\nTrade::AnyImageConverter::convertToFile(): cannot load the {0} plugin\n", data.plugin)); #else CORRADE_COMPARE(out.str(), Utility::formatString( -"PluginManager::Manager::load(): plugin {0} was not found\nTrade::AnyImageConverter::exportToFile(): cannot load the {0} plugin\n", data.plugin)); +"PluginManager::Manager::load(): plugin {0} was not found\nTrade::AnyImageConverter::convertToFile(): cannot load the {0} plugin\n", data.plugin)); #endif } @@ -149,9 +150,9 @@ void AnyImageConverterTest::unknown() { Error redirectError{&output}; Containers::Pointer converter = _manager.instantiate("AnyImageConverter"); - CORRADE_VERIFY(!converter->exportToFile(Image, "image.xcf")); + CORRADE_VERIFY(!converter->convertToFile(Image, "image.xcf")); - CORRADE_COMPARE(output.str(), "Trade::AnyImageConverter::exportToFile(): cannot determine the format of image.xcf\n"); + CORRADE_COMPARE(output.str(), "Trade::AnyImageConverter::convertToFile(): cannot determine the format of image.xcf\n"); } void AnyImageConverterTest::verbose() { @@ -169,12 +170,12 @@ void AnyImageConverterTest::verbose() { std::ostringstream out; { Debug redirectOutput{&out}; - CORRADE_VERIFY(converter->exportToFile(Image, filename)); + CORRADE_VERIFY(converter->convertToFile(Image, filename)); } CORRADE_VERIFY(Utility::Directory::exists(filename)); CORRADE_COMPARE(out.str(), - "Trade::AnyImageConverter::exportToFile(): using TgaImageConverter\n" - "Trade::TgaImageConverter::exportToData(): converting from RGB to BGR\n"); + "Trade::AnyImageConverter::convertToFile(): using TgaImageConverter\n" + "Trade::TgaImageConverter::convertToData(): converting from RGB to BGR\n"); } }}}} diff --git a/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp b/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp index eb0c2dfdb..c9078ceb1 100644 --- a/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp +++ b/src/MagnumPlugins/MagnumFontConverter/MagnumFontConverter.cpp @@ -120,7 +120,7 @@ std::vector>> MagnumFontConverter std::copy(confStr.begin(), confStr.end(), confData.begin()); /* Save cache image */ - auto tgaData = Trade::TgaImageConverter().exportToData(cache.image()); + auto tgaData = Trade::TgaImageConverter().convertToData(cache.image()); std::vector>> out; out.emplace_back(filename + ".conf", std::move(confData)); diff --git a/src/MagnumPlugins/TgaImageConverter/Test/TgaImageConverterTest.cpp b/src/MagnumPlugins/TgaImageConverter/Test/TgaImageConverterTest.cpp index 5ea5b0706..b7fc615a8 100644 --- a/src/MagnumPlugins/TgaImageConverter/Test/TgaImageConverterTest.cpp +++ b/src/MagnumPlugins/TgaImageConverter/Test/TgaImageConverterTest.cpp @@ -63,8 +63,8 @@ constexpr struct { } VerboseData[] { {"", {}, "", ""}, {"verbose", ImageConverterFlag::Verbose, - "Trade::TgaImageConverter::exportToData(): converting from RGB to BGR\n", - "Trade::TgaImageConverter::exportToData(): converting from RGBA to BGRA\n"} + "Trade::TgaImageConverter::convertToData(): converting from RGB to BGR\n", + "Trade::TgaImageConverter::convertToData(): converting from RGBA to BGRA\n"} }; /* Padded to four byte alignment (the resulting file is *not* padded) */ @@ -118,9 +118,9 @@ void TgaImageConverterTest::wrongFormat() { Error redirectError{&out}; Containers::Pointer converter = _converterManager.instantiate("TgaImageConverter"); - const auto data = converter->exportToData(image); + const auto data = converter->convertToData(image); CORRADE_VERIFY(!data); - CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::exportToData(): unsupported pixel format PixelFormat::RG8Unorm\n"); + CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::convertToData(): unsupported pixel format PixelFormat::RG8Unorm\n"); } void TgaImageConverterTest::rgb() { @@ -134,7 +134,7 @@ void TgaImageConverterTest::rgb() { Containers::Array array; { Debug redirectOutput{&out}; - array = converter->exportToData(OriginalRGB); + array = converter->convertToData(OriginalRGB); } CORRADE_VERIFY(out); @@ -165,7 +165,7 @@ void TgaImageConverterTest::rgba() { Containers::Array array; { Debug redirectOutput{&out}; - array = converter->exportToData(OriginalRGBA); + array = converter->convertToData(OriginalRGBA); } CORRADE_VERIFY(out); diff --git a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp index da34778fc..ca1a4e3c1 100644 --- a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp +++ b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp @@ -43,9 +43,9 @@ TgaImageConverter::TgaImageConverter() = default; TgaImageConverter::TgaImageConverter(PluginManager::AbstractManager& manager, const std::string& plugin): AbstractImageConverter{manager, plugin} {} -ImageConverterFeatures TgaImageConverter::doFeatures() const { return ImageConverterFeature::ConvertData; } +ImageConverterFeatures TgaImageConverter::doFeatures() const { return ImageConverterFeature::Convert2DToData; } -Containers::Array TgaImageConverter::doExportToData(const ImageView2D& image) { +Containers::Array TgaImageConverter::doConvertToData(const ImageView2D& image) { /* Initialize data buffer */ const auto pixelSize = UnsignedByte(image.pixelSize()); Containers::Array data{Containers::ValueInit, sizeof(Implementation::TgaHeader) + pixelSize*image.size().product()}; @@ -61,7 +61,7 @@ Containers::Array TgaImageConverter::doExportToData(const ImageView2D& ima header->imageType = 3; break; default: - Error() << "Trade::TgaImageConverter::exportToData(): unsupported pixel format" << image.format(); + Error() << "Trade::TgaImageConverter::convertToData(): unsupported pixel format" << image.format(); return nullptr; } header->bpp = pixelSize*8; @@ -75,12 +75,12 @@ Containers::Array TgaImageConverter::doExportToData(const ImageView2D& ima if(image.format() == PixelFormat::RGB8Unorm) { if(flags() & ImageConverterFlag::Verbose) - Debug{} << "Trade::TgaImageConverter::exportToData(): converting from RGB to BGR"; + Debug{} << "Trade::TgaImageConverter::convertToData(): converting from RGB to BGR"; for(Vector3ub& pixel: Containers::arrayCast(pixels)) pixel = Math::gather<'b', 'g', 'r'>(pixel); } else if(image.format() == PixelFormat::RGBA8Unorm) { if(flags() & ImageConverterFlag::Verbose) - Debug{} << "Trade::TgaImageConverter::exportToData(): converting from RGBA to BGRA"; + Debug{} << "Trade::TgaImageConverter::convertToData(): converting from RGBA to BGRA"; for(Vector4ub& pixel: Containers::arrayCast(pixels)) pixel = Math::gather<'b', 'g', 'r', 'a'>(pixel); } @@ -91,4 +91,4 @@ Containers::Array TgaImageConverter::doExportToData(const ImageView2D& ima }} CORRADE_PLUGIN_REGISTER(TgaImageConverter, Magnum::Trade::TgaImageConverter, - "cz.mosra.magnum.Trade.AbstractImageConverter/0.2.1") + "cz.mosra.magnum.Trade.AbstractImageConverter/0.3") diff --git a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h index be3ebc6cd..8c88cad0e 100644 --- a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h +++ b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.h @@ -104,7 +104,7 @@ class MAGNUM_TGAIMAGECONVERTER_EXPORT TgaImageConverter: public AbstractImageCon private: ImageConverterFeatures MAGNUM_TGAIMAGECONVERTER_LOCAL doFeatures() const override; - Containers::Array MAGNUM_TGAIMAGECONVERTER_LOCAL doExportToData(const ImageView2D& image) override; + Containers::Array MAGNUM_TGAIMAGECONVERTER_LOCAL doConvertToData(const ImageView2D& image) override; }; }}