From dfacd7fb2d63941e8627450a17799ee7cfe38f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 23 Feb 2020 02:36:40 +0100 Subject: [PATCH 1/2] Trade: support mip levels in image import. There's a new level option in each imageND() API, plus an imageNDLevelCount() query to get image level count. --- doc/changelog.dox | 7 + src/Magnum/Trade/AbstractImporter.cpp | 86 ++++- src/Magnum/Trade/AbstractImporter.h | 85 ++++- .../Trade/Test/AbstractImporterTest.cpp | 301 +++++++++++++++++- .../AnyImageImporter/AnyImageImporter.cpp | 6 +- .../AnyImageImporter/AnyImageImporter.h | 3 +- .../AnySceneImporter/AnySceneImporter.cpp | 11 +- .../AnySceneImporter/AnySceneImporter.h | 9 +- src/MagnumPlugins/ObjImporter/ObjImporter.cpp | 2 +- src/MagnumPlugins/TgaImporter/TgaImporter.cpp | 4 +- src/MagnumPlugins/TgaImporter/TgaImporter.h | 2 +- 11 files changed, 473 insertions(+), 43 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index e04f8cdc0c..e0700a352d 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -150,6 +150,13 @@ See also: and @ref SceneGraph::AbstractBasicTranslationRotation3D::rotateLocal(const Math::Quaternion&) "rotateLocal()" overloads taking a @ref Math::Quaternion +@subsubsection changelog-latest-new-trade Trade library + +- Ability to import image mip levels via an additional parameter in + @ref Trade::AbstractImporter::image2D(), + @ref Trade::AbstractImporter::image2DLevelCount() and similar APIs for 1D + and 3D images + @subsubsection changelog-latest-new-vk Vk library - Updated Vulkan headers for version 1.2 diff --git a/src/Magnum/Trade/AbstractImporter.cpp b/src/Magnum/Trade/AbstractImporter.cpp index 9853dd0cbd..3138c40db4 100644 --- a/src/Magnum/Trade/AbstractImporter.cpp +++ b/src/Magnum/Trade/AbstractImporter.cpp @@ -52,7 +52,7 @@ namespace Magnum { namespace Trade { std::string AbstractImporter::pluginInterface() { - return "cz.mosra.magnum.Trade.AbstractImporter/0.3"; + return "cz.mosra.magnum.Trade.AbstractImporter/0.3.1"; } #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT @@ -538,6 +538,16 @@ UnsignedInt AbstractImporter::image1DCount() const { UnsignedInt AbstractImporter::doImage1DCount() const { return 0; } +UnsignedInt AbstractImporter::image1DLevelCount(const UnsignedInt id) { + CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1DLevelCount(): no file opened", {}); + CORRADE_ASSERT(id < doImage1DCount(), "Trade::AbstractImporter::image1DLevelCount(): index" << id << "out of range for" << doImage1DCount() << "entries", {}); + const UnsignedInt out = doImage1DLevelCount(id); + CORRADE_ASSERT(out, "Trade::AbstractImporter::image1DLevelCount(): implementation reported zero levels", {}); + return out; +} + +UnsignedInt AbstractImporter::doImage1DLevelCount(UnsignedInt) { return 1; } + Int AbstractImporter::image1DForName(const std::string& name) { CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1DForName(): no file opened", {}); return doImage1DForName(name); @@ -553,15 +563,27 @@ std::string AbstractImporter::image1DName(const UnsignedInt id) { std::string AbstractImporter::doImage1DName(UnsignedInt) { return {}; } -Containers::Optional AbstractImporter::image1D(const UnsignedInt id) { +Containers::Optional AbstractImporter::image1D(const UnsignedInt id, const UnsignedInt level) { CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1D(): no file opened", {}); CORRADE_ASSERT(id < doImage1DCount(), "Trade::AbstractImporter::image1D(): index" << id << "out of range for" << doImage1DCount() << "entries", {}); - Containers::Optional image = doImage1D(id); + #ifndef CORRADE_NO_ASSERT + /* Check for the range only if requested level is nonzero, as + image*DLevelCount() is expected to return >= 1. This is done to prevent + random assertions and messages from a doImage*DLevelCount() to be + printed (e.g., many plugins delegate image loading and assert an access + to the manager for that), which may be confusing */ + if(level) { + const UnsignedInt levelCount = doImage1DLevelCount(id); + CORRADE_ASSERT(levelCount, "Trade::AbstractImporter::image1D(): implementation reported zero levels", {}); + CORRADE_ASSERT(level < levelCount, "Trade::AbstractImporter::image1D(): level" << level << "out of range for" << levelCount << "entries", {}); + } + #endif + Containers::Optional image = doImage1D(id, level); CORRADE_ASSERT(!image || !image->_data.deleter(), "Trade::AbstractImporter::image1D(): implementation is not allowed to use a custom Array deleter", {}); return image; } -Containers::Optional AbstractImporter::doImage1D(UnsignedInt) { +Containers::Optional AbstractImporter::doImage1D(UnsignedInt, UnsignedInt) { CORRADE_ASSERT(false, "Trade::AbstractImporter::image1D(): not implemented", {}); } @@ -572,6 +594,16 @@ UnsignedInt AbstractImporter::image2DCount() const { UnsignedInt AbstractImporter::doImage2DCount() const { return 0; } +UnsignedInt AbstractImporter::image2DLevelCount(const UnsignedInt id) { + CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image2DLevelCount(): no file opened", {}); + CORRADE_ASSERT(id < doImage2DCount(), "Trade::AbstractImporter::image2DLevelCount(): index" << id << "out of range for" << doImage2DCount() << "entries", {}); + const UnsignedInt out = doImage2DLevelCount(id); + CORRADE_ASSERT(out, "Trade::AbstractImporter::image2DLevelCount(): implementation reported zero levels", {}); + return out; +} + +UnsignedInt AbstractImporter::doImage2DLevelCount(UnsignedInt) { return 1; } + Int AbstractImporter::image2DForName(const std::string& name) { CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image2DForName(): no file opened", {}); return doImage2DForName(name); @@ -587,15 +619,27 @@ std::string AbstractImporter::image2DName(const UnsignedInt id) { std::string AbstractImporter::doImage2DName(UnsignedInt) { return {}; } -Containers::Optional AbstractImporter::image2D(const UnsignedInt id) { +Containers::Optional AbstractImporter::image2D(const UnsignedInt id, const UnsignedInt level) { CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image2D(): no file opened", {}); CORRADE_ASSERT(id < doImage2DCount(), "Trade::AbstractImporter::image2D(): index" << id << "out of range for" << doImage2DCount() << "entries", {}); - Containers::Optional image = doImage2D(id); + #ifndef CORRADE_NO_ASSERT + /* Check for the range only if requested level is nonzero, as + image*DLevelCount() is expected to return >= 1. This is done to prevent + random assertions and messages from a doImage*DLevelCount() to be + printed (e.g., many plugins delegate image loading and assert an access + to the manager for that), which may be confusing */ + if(level) { + const UnsignedInt levelCount = doImage2DLevelCount(id); + CORRADE_ASSERT(levelCount, "Trade::AbstractImporter::image2D(): implementation reported zero levels", {}); + CORRADE_ASSERT(level < levelCount, "Trade::AbstractImporter::image2D(): level" << level << "out of range for" << levelCount << "entries", {}); + } + #endif + Containers::Optional image = doImage2D(id, level); CORRADE_ASSERT(!image || !image->_data.deleter(), "Trade::AbstractImporter::image2D(): implementation is not allowed to use a custom Array deleter", {}); return image; } -Containers::Optional AbstractImporter::doImage2D(UnsignedInt) { +Containers::Optional AbstractImporter::doImage2D(UnsignedInt, UnsignedInt) { CORRADE_ASSERT(false, "Trade::AbstractImporter::image2D(): not implemented", {}); } @@ -606,6 +650,16 @@ UnsignedInt AbstractImporter::image3DCount() const { UnsignedInt AbstractImporter::doImage3DCount() const { return 0; } +UnsignedInt AbstractImporter::image3DLevelCount(const UnsignedInt id) { + CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3DLevelCount(): no file opened", {}); + CORRADE_ASSERT(id < doImage3DCount(), "Trade::AbstractImporter::image3DLevelCount(): index" << id << "out of range for" << doImage3DCount() << "entries", {}); + const UnsignedInt out = doImage3DLevelCount(id); + CORRADE_ASSERT(out, "Trade::AbstractImporter::image3DLevelCount(): implementation reported zero levels", {}); + return out; +} + +UnsignedInt AbstractImporter::doImage3DLevelCount(UnsignedInt) { return 1; } + Int AbstractImporter::image3DForName(const std::string& name) { CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3DForName(): no file opened", {}); return doImage3DForName(name); @@ -621,15 +675,27 @@ std::string AbstractImporter::image3DName(const UnsignedInt id) { std::string AbstractImporter::doImage3DName(UnsignedInt) { return {}; } -Containers::Optional AbstractImporter::image3D(const UnsignedInt id) { +Containers::Optional AbstractImporter::image3D(const UnsignedInt id, const UnsignedInt level) { CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3D(): no file opened", {}); CORRADE_ASSERT(id < doImage3DCount(), "Trade::AbstractImporter::image3D(): index" << id << "out of range for" << doImage3DCount() << "entries", {}); - Containers::Optional image = doImage3D(id); + #ifndef CORRADE_NO_ASSERT + /* Check for the range only if requested level is nonzero, as + image*DLevelCount() is expected to return >= 1. This is done to prevent + random assertions and messages from a doImage*DLevelCount() to be + printed (e.g., many plugins delegate image loading and assert an access + to the manager for that), which may be confusing */ + if(level) { + const UnsignedInt levelCount = doImage3DLevelCount(id); + CORRADE_ASSERT(levelCount, "Trade::AbstractImporter::image3D(): implementation reported zero levels", {}); + CORRADE_ASSERT(level < levelCount, "Trade::AbstractImporter::image3D(): level" << level << "out of range for" << levelCount << "entries", {}); + } + #endif + Containers::Optional image = doImage3D(id, level); CORRADE_ASSERT(!image || !image->_data.deleter(), "Trade::AbstractImporter::image3D(): implementation is not allowed to use a custom Array deleter", {}); return image; } -Containers::Optional AbstractImporter::doImage3D(UnsignedInt) { +Containers::Optional AbstractImporter::doImage3D(UnsignedInt, UnsignedInt) { CORRADE_ASSERT(false, "Trade::AbstractImporter::image3D(): not implemented", {}); } diff --git a/src/Magnum/Trade/AbstractImporter.h b/src/Magnum/Trade/AbstractImporter.h index 9bb052f703..d478609f32 100644 --- a/src/Magnum/Trade/AbstractImporter.h +++ b/src/Magnum/Trade/AbstractImporter.h @@ -243,6 +243,9 @@ checked by the implementation: there is any file opened. - All `do*()` implementations taking data ID as parameter are called only if the ID is from valid range. +- For `doImage*()` and @p level parameter being nonzero, implementations are + called only if it is from valid range. Level zero is always expected to be + present and thus no check is done in that case. @m_class{m-block m-warning} @@ -282,7 +285,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi * @brief Plugin interface * * @code{.cpp} - * "cz.mosra.magnum.Trade.AbstractImporter/0.3" + * "cz.mosra.magnum.Trade.AbstractImporter/0.3.1" * @endcode */ static std::string pluginInterface(); @@ -813,9 +816,20 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi * @brief One-dimensional image count * * Expects that a file is opened. + * @see @ref image1DLevelCount() */ UnsignedInt image1DCount() const; + /** + * @brief One-dimensional image mip level count + * @param id Image ID, from range [0, @ref image1DCount()) + * @m_since_latest + * + * Always returns at least one level, import failures are deferred to + * @ref image1D(). Expects that a file is opened. + */ + UnsignedInt image1DLevelCount(UnsignedInt id); + /** * @brief One-dimensional image ID for given name * @@ -837,19 +851,31 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi /** * @brief One-dimensional image * @param id Image ID, from range [0, @ref image1DCount()). + * @param level Mip level, from range [0, @ref image1DLevelCount()) * * Returns given image or @ref Containers::NullOpt if importing failed. * Expects that a file is opened. */ - Containers::Optional image1D(UnsignedInt id); + Containers::Optional image1D(UnsignedInt id, UnsignedInt level = 0); /** * @brief Two-dimensional image count * * Expects that a file is opened. + * @see @ref image2DLevelCount() */ UnsignedInt image2DCount() const; + /** + * @brief Two-dimensional image mip level count + * @param id Image ID, from range [0, @ref image2DCount()). + * @m_since_latest + * + * Always returns at least one level, import failures are deferred to + * @ref image2D(). Expects that a file is opened. + */ + UnsignedInt image2DLevelCount(UnsignedInt id); + /** * @brief Two-dimensional image ID for given name * @@ -871,19 +897,31 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi /** * @brief Two-dimensional image * @param id Image ID, from range [0, @ref image2DCount()). + * @param level Mip level, from range [0, @ref image2DLevelCount()) * * Returns given image or @ref Containers::NullOpt if importing failed. * Expects that a file is opened. */ - Containers::Optional image2D(UnsignedInt id); + Containers::Optional image2D(UnsignedInt id, UnsignedInt level = 0); /** * @brief Three-dimensional image count * * Expects that a file is opened. + * @see @ref image3DLevelCount() */ UnsignedInt image3DCount() const; + /** + * @brief Three-dimensional image mip level count + * @param id Image ID, from range [0, @ref image3DCount()) + * @m_since_latest + * + * Always returns at least one level, import failures are deferred to + * @ref image3D(). Expects that a file is opened. + */ + UnsignedInt image3DLevelCount(UnsignedInt id); + /** * @brief Three-dimensional image ID for given name * @@ -905,11 +943,12 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi /** * @brief Three-dimensional image * @param id Image ID, from range [0, @ref image3DCount()). + * @param level Mip level, from range [0, @ref image3DLevelCount()) * * Returns given image or @ref Containers::NullOpt if importing failed. * Expects that a file is opened. */ - Containers::Optional image3D(UnsignedInt id); + Containers::Optional image3D(UnsignedInt id, UnsignedInt level = 0); /*@}*/ @@ -1228,6 +1267,14 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi */ virtual UnsignedInt doImage1DCount() const; + /** + * @brief Implementation for @ref image1DLevelCount() + * + * Default implementation returns @cpp 1 @ce. See + * @ref doImage2DLevelCount() for expected implementation behavior. + */ + virtual UnsignedInt doImage1DLevelCount(UnsignedInt id); + /** * @brief Implementation for @ref image1DForName() * @@ -1243,7 +1290,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi virtual std::string doImage1DName(UnsignedInt id); /** @brief Implementation for @ref image1D() */ - virtual Containers::Optional doImage1D(UnsignedInt id); + virtual Containers::Optional doImage1D(UnsignedInt id, UnsignedInt level); /** * @brief Implementation for @ref image2DCount() @@ -1252,6 +1299,22 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi */ virtual UnsignedInt doImage2DCount() const; + /** + * @brief Implementation for @ref image2DLevelCount() + * + * Default implementation returns @cpp 1 @ce. Similarly to all other + * `*Count()` functions, this function isn't expected to fail --- if an + * import error occus, this function should return @cpp 1 @ce and the + * error state should be returned from @ref image2D() instead; if a + * file really contains a zero-level image, the implementation should + * exclude that image from @ref doImage2DCount() instead of returning + * @cpp 0 @ce here. + * + * Deliberately not @cpp const @ce to allow plugins cache decoded + * data. + */ + virtual UnsignedInt doImage2DLevelCount(UnsignedInt id); + /** * @brief Implementation for @ref image2DForName() * @@ -1267,7 +1330,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi virtual std::string doImage2DName(UnsignedInt id); /** @brief Implementation for @ref image2D() */ - virtual Containers::Optional doImage2D(UnsignedInt id); + virtual Containers::Optional doImage2D(UnsignedInt id, UnsignedInt level); /** * @brief Implementation for @ref image3DCount() @@ -1276,6 +1339,14 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi */ virtual UnsignedInt doImage3DCount() const; + /** + * @brief Implementation for @ref image3DLevelCount() + * + * Default implementation returns @cpp 1 @ce. See + * @ref doImage2DLevelCount() for expected implementation behavior. + */ + virtual UnsignedInt doImage3DLevelCount(UnsignedInt id); + /** * @brief Implementation for @ref image3DForName() * @@ -1291,7 +1362,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi virtual std::string doImage3DName(UnsignedInt id); /** @brief Implementation for @ref image3D() */ - virtual Containers::Optional doImage3D(UnsignedInt id); + virtual Containers::Optional doImage3D(UnsignedInt id, UnsignedInt level); /** @brief Implementation for @ref importerState() */ virtual const void* doImporterState() const; diff --git a/src/Magnum/Trade/Test/AbstractImporterTest.cpp b/src/Magnum/Trade/Test/AbstractImporterTest.cpp index 079befcb8b..60f4d699d1 100644 --- a/src/Magnum/Trade/Test/AbstractImporterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImporterTest.cpp @@ -207,6 +207,10 @@ struct AbstractImporterTest: TestSuite::Tester { void image1D(); void image1DCountNotImplemented(); void image1DCountNoFile(); + void image1DLevelCountNotImplemented(); + void image1DLevelCountNoFile(); + void image1DLevelCountOutOfRange(); + void image1DLevelCountZero(); void image1DForNameNotImplemented(); void image1DForNameNoFile(); void image1DNameNotImplemented(); @@ -215,11 +219,16 @@ struct AbstractImporterTest: TestSuite::Tester { void image1DNotImplemented(); void image1DNoFile(); void image1DOutOfRange(); + void image1DLevelOutOfRange(); void image1DCustomDeleter(); void image2D(); void image2DCountNotImplemented(); void image2DCountNoFile(); + void image2DLevelCountNotImplemented(); + void image2DLevelCountNoFile(); + void image2DLevelCountOutOfRange(); + void image2DLevelCountZero(); void image2DForNameNotImplemented(); void image2DForNameNoFile(); void image2DNameNotImplemented(); @@ -228,11 +237,16 @@ struct AbstractImporterTest: TestSuite::Tester { void image2DNotImplemented(); void image2DNoFile(); void image2DOutOfRange(); + void image2DLevelOutOfRange(); void image2DCustomDeleter(); void image3D(); void image3DCountNotImplemented(); void image3DCountNoFile(); + void image3DLevelCountNotImplemented(); + void image3DLevelCountNoFile(); + void image3DLevelCountOutOfRange(); + void image3DLevelCountZero(); void image3DForNameNotImplemented(); void image3DForNameNoFile(); void image3DNameNotImplemented(); @@ -241,6 +255,7 @@ struct AbstractImporterTest: TestSuite::Tester { void image3DNotImplemented(); void image3DNoFile(); void image3DOutOfRange(); + void image3DLevelOutOfRange(); void image3DCustomDeleter(); void importerState(); @@ -407,6 +422,10 @@ AbstractImporterTest::AbstractImporterTest() { &AbstractImporterTest::image1D, &AbstractImporterTest::image1DCountNotImplemented, &AbstractImporterTest::image1DCountNoFile, + &AbstractImporterTest::image1DLevelCountNotImplemented, + &AbstractImporterTest::image1DLevelCountNoFile, + &AbstractImporterTest::image1DLevelCountOutOfRange, + &AbstractImporterTest::image1DLevelCountZero, &AbstractImporterTest::image1DForNameNotImplemented, &AbstractImporterTest::image1DForNameNoFile, &AbstractImporterTest::image1DNameNotImplemented, @@ -415,11 +434,16 @@ AbstractImporterTest::AbstractImporterTest() { &AbstractImporterTest::image1DNotImplemented, &AbstractImporterTest::image1DNoFile, &AbstractImporterTest::image1DOutOfRange, + &AbstractImporterTest::image1DLevelOutOfRange, &AbstractImporterTest::image1DCustomDeleter, &AbstractImporterTest::image2D, &AbstractImporterTest::image2DCountNotImplemented, &AbstractImporterTest::image2DCountNoFile, + &AbstractImporterTest::image2DLevelCountNotImplemented, + &AbstractImporterTest::image2DLevelCountNoFile, + &AbstractImporterTest::image2DLevelCountOutOfRange, + &AbstractImporterTest::image2DLevelCountZero, &AbstractImporterTest::image2DForNameNotImplemented, &AbstractImporterTest::image2DForNameNoFile, &AbstractImporterTest::image2DNameNotImplemented, @@ -428,11 +452,16 @@ AbstractImporterTest::AbstractImporterTest() { &AbstractImporterTest::image2DNotImplemented, &AbstractImporterTest::image2DNoFile, &AbstractImporterTest::image2DOutOfRange, + &AbstractImporterTest::image2DLevelOutOfRange, &AbstractImporterTest::image2DCustomDeleter, &AbstractImporterTest::image3D, &AbstractImporterTest::image3DCountNotImplemented, &AbstractImporterTest::image3DCountNoFile, + &AbstractImporterTest::image3DLevelCountNotImplemented, + &AbstractImporterTest::image3DLevelCountNoFile, + &AbstractImporterTest::image3DLevelCountOutOfRange, + &AbstractImporterTest::image3DLevelCountZero, &AbstractImporterTest::image3DForNameNotImplemented, &AbstractImporterTest::image3DForNameNoFile, &AbstractImporterTest::image3DNameNotImplemented, @@ -441,6 +470,7 @@ AbstractImporterTest::AbstractImporterTest() { &AbstractImporterTest::image3DNotImplemented, &AbstractImporterTest::image3DNoFile, &AbstractImporterTest::image3DOutOfRange, + &AbstractImporterTest::image3DLevelOutOfRange, &AbstractImporterTest::image3DCustomDeleter, &AbstractImporterTest::importerState, @@ -2672,6 +2702,10 @@ void AbstractImporterTest::image1D() { void doClose() override {} UnsignedInt doImage1DCount() const override { return 8; } + UnsignedInt doImage1DLevelCount(UnsignedInt id) override { + if(id == 7) return 3; + else return {}; + } Int doImage1DForName(const std::string& name) override { if(name == "eighth") return 7; else return -1; @@ -2680,17 +2714,18 @@ void AbstractImporterTest::image1D() { if(id == 7) return "eighth"; else return {}; } - Containers::Optional doImage1D(UnsignedInt id) override { - if(id == 7) return ImageData1D{PixelFormat::RGBA8Unorm, {}, {}, &state}; + Containers::Optional doImage1D(UnsignedInt id, UnsignedInt level) override { + if(id == 7 && level == 2) return ImageData1D{PixelFormat::RGBA8Unorm, {}, {}, &state}; else return {}; } } importer; CORRADE_COMPARE(importer.image1DCount(), 8); + CORRADE_COMPARE(importer.image1DLevelCount(7), 3); CORRADE_COMPARE(importer.image1DForName("eighth"), 7); CORRADE_COMPARE(importer.image1DName(7), "eighth"); - auto data = importer.image1D(7); + auto data = importer.image1D(7, 2); CORRADE_VERIFY(data); CORRADE_COMPARE(data->importerState(), &state); } @@ -2719,6 +2754,67 @@ void AbstractImporterTest::image1DCountNoFile() { CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image1DCount(): no file opened\n"); } +void AbstractImporterTest::image1DLevelCountNotImplemented() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage1DCount() const override { return 8; } + } importer; + + CORRADE_COMPARE(importer.image1DLevelCount(7), 1); +} + +void AbstractImporterTest::image1DLevelCountNoFile() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return false; } + void doClose() override {} + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image1DLevelCount(7); + CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image1DLevelCount(): no file opened\n"); +} + +void AbstractImporterTest::image1DLevelCountOutOfRange() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage1DCount() const override { return 8; } + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image1DLevelCount(8); + CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image1DLevelCount(): index 8 out of range for 8 entries\n"); +} + +void AbstractImporterTest::image1DLevelCountZero() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage1DCount() const override { return 8; } + UnsignedInt doImage1DLevelCount(UnsignedInt) override { return 0; } + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image1DLevelCount(7); + /* This should print a similar message instead of a confusing + "level 1 out of range for 0 entries" */ + importer.image1D(7, 1); + CORRADE_COMPARE(out.str(), + "Trade::AbstractImporter::image1DLevelCount(): implementation reported zero levels\n" + "Trade::AbstractImporter::image1D(): implementation reported zero levels\n"); +} + void AbstractImporterTest::image1DForNameNotImplemented() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return {}; } @@ -2831,6 +2927,22 @@ void AbstractImporterTest::image1DOutOfRange() { CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image1D(): index 8 out of range for 8 entries\n"); } +void AbstractImporterTest::image1DLevelOutOfRange() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage1DCount() const override { return 8; } + UnsignedInt doImage1DLevelCount(UnsignedInt) override { return 3; } + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image1D(7, 3); + CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image1D(): level 3 out of range for 3 entries\n"); +} + void AbstractImporterTest::image1DCustomDeleter() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return {}; } @@ -2838,7 +2950,7 @@ void AbstractImporterTest::image1DCustomDeleter() { void doClose() override {} UnsignedInt doImage1DCount() const override { return 1; } - Containers::Optional doImage1D(UnsignedInt) override { + Containers::Optional doImage1D(UnsignedInt, UnsignedInt) override { return ImageData1D{PixelFormat::RGBA8Unorm, {}, Containers::Array{nullptr, 0, [](char*, std::size_t) {}}}; } } importer; @@ -2857,6 +2969,10 @@ void AbstractImporterTest::image2D() { void doClose() override {} UnsignedInt doImage2DCount() const override { return 8; } + UnsignedInt doImage2DLevelCount(UnsignedInt id) override { + if(id == 7) return 3; + else return {}; + } Int doImage2DForName(const std::string& name) override { if(name == "eighth") return 7; else return -1; @@ -2865,17 +2981,18 @@ void AbstractImporterTest::image2D() { if(id == 7) return "eighth"; else return {}; } - Containers::Optional doImage2D(UnsignedInt id) override { - if(id == 7) return ImageData2D{PixelFormat::RGBA8Unorm, {}, {}, &state}; + Containers::Optional doImage2D(UnsignedInt id, UnsignedInt level) override { + if(id == 7 && level == 2) return ImageData2D{PixelFormat::RGBA8Unorm, {}, {}, &state}; else return {}; } } importer; CORRADE_COMPARE(importer.image2DCount(), 8); + CORRADE_COMPARE(importer.image2DLevelCount(7), 3); CORRADE_COMPARE(importer.image2DForName("eighth"), 7); CORRADE_COMPARE(importer.image2DName(7), "eighth"); - auto data = importer.image2D(7); + auto data = importer.image2D(7, 2); CORRADE_VERIFY(data); CORRADE_COMPARE(data->importerState(), &state); } @@ -2904,6 +3021,67 @@ void AbstractImporterTest::image2DCountNoFile() { CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image2DCount(): no file opened\n"); } +void AbstractImporterTest::image2DLevelCountNotImplemented() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage2DCount() const override { return 8; } + } importer; + + CORRADE_COMPARE(importer.image2DLevelCount(7), 1); +} + +void AbstractImporterTest::image2DLevelCountNoFile() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return false; } + void doClose() override {} + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image2DLevelCount(7); + CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image2DLevelCount(): no file opened\n"); +} + +void AbstractImporterTest::image2DLevelCountOutOfRange() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage2DCount() const override { return 8; } + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image2DLevelCount(8); + CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image2DLevelCount(): index 8 out of range for 8 entries\n"); +} + +void AbstractImporterTest::image2DLevelCountZero() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage2DCount() const override { return 8; } + UnsignedInt doImage2DLevelCount(UnsignedInt) override { return 0; } + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image2DLevelCount(7); + /* This should print a similar message instead of a confusing + "level 1 out of range for 0 entries" */ + importer.image2D(7, 1); + CORRADE_COMPARE(out.str(), + "Trade::AbstractImporter::image2DLevelCount(): implementation reported zero levels\n" + "Trade::AbstractImporter::image2D(): implementation reported zero levels\n"); +} + void AbstractImporterTest::image2DForNameNotImplemented() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return {}; } @@ -3016,6 +3194,22 @@ void AbstractImporterTest::image2DOutOfRange() { CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image2D(): index 8 out of range for 8 entries\n"); } +void AbstractImporterTest::image2DLevelOutOfRange() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage2DCount() const override { return 8; } + UnsignedInt doImage2DLevelCount(UnsignedInt) override { return 3; } + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image2D(7, 3); + CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image2D(): level 3 out of range for 3 entries\n"); +} + void AbstractImporterTest::image2DCustomDeleter() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return {}; } @@ -3023,7 +3217,7 @@ void AbstractImporterTest::image2DCustomDeleter() { void doClose() override {} UnsignedInt doImage2DCount() const override { return 1; } - Containers::Optional doImage2D(UnsignedInt) override { + Containers::Optional doImage2D(UnsignedInt, UnsignedInt) override { return ImageData2D{PixelFormat::RGBA8Unorm, {}, Containers::Array{nullptr, 0, [](char*, std::size_t) {}}}; } } importer; @@ -3042,6 +3236,10 @@ void AbstractImporterTest::image3D() { void doClose() override {} UnsignedInt doImage3DCount() const override { return 8; } + UnsignedInt doImage3DLevelCount(UnsignedInt id) override { + if(id == 7) return 3; + else return {}; + } Int doImage3DForName(const std::string& name) override { if(name == "eighth") return 7; else return -1; @@ -3050,17 +3248,18 @@ void AbstractImporterTest::image3D() { if(id == 7) return "eighth"; else return {}; } - Containers::Optional doImage3D(UnsignedInt id) override { - if(id == 7) return ImageData3D{PixelFormat::RGBA8Unorm, {}, {}, &state}; + Containers::Optional doImage3D(UnsignedInt id, UnsignedInt level) override { + if(id == 7 && level == 2) return ImageData3D{PixelFormat::RGBA8Unorm, {}, {}, &state}; else return {}; } } importer; CORRADE_COMPARE(importer.image3DCount(), 8); + CORRADE_COMPARE(importer.image3DLevelCount(7), 3); CORRADE_COMPARE(importer.image3DForName("eighth"), 7); CORRADE_COMPARE(importer.image3DName(7), "eighth"); - auto data = importer.image3D(7); + auto data = importer.image3D(7, 2); CORRADE_VERIFY(data); CORRADE_COMPARE(data->importerState(), &state); } @@ -3089,6 +3288,68 @@ void AbstractImporterTest::image3DCountNoFile() { CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image3DCount(): no file opened\n"); } +void AbstractImporterTest::image3DLevelCountNotImplemented() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage3DCount() const override { return 8; } + } importer; + + CORRADE_COMPARE(importer.image3DLevelCount(7), 1); +} + +void AbstractImporterTest::image3DLevelCountNoFile() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return false; } + void doClose() override {} + } importer; + + std::ostringstream out; + Error redirectError{&out}; + + importer.image3DLevelCount(7); + CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image3DLevelCount(): no file opened\n"); +} + +void AbstractImporterTest::image3DLevelCountOutOfRange() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage3DCount() const override { return 8; } + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image3DLevelCount(8); + CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image3DLevelCount(): index 8 out of range for 8 entries\n"); +} + +void AbstractImporterTest::image3DLevelCountZero() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage3DCount() const override { return 8; } + UnsignedInt doImage3DLevelCount(UnsignedInt) override { return 0; } + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image3DLevelCount(7); + /* This should print a similar message instead of a confusing + "level 1 out of range for 0 entries" */ + importer.image3D(7, 1); + CORRADE_COMPARE(out.str(), + "Trade::AbstractImporter::image3DLevelCount(): implementation reported zero levels\n" + "Trade::AbstractImporter::image3D(): implementation reported zero levels\n"); +} + void AbstractImporterTest::image3DForNameNotImplemented() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return {}; } @@ -3201,6 +3462,22 @@ void AbstractImporterTest::image3DOutOfRange() { CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image3D(): index 8 out of range for 8 entries\n"); } +void AbstractImporterTest::image3DLevelOutOfRange() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doImage3DCount() const override { return 8; } + UnsignedInt doImage3DLevelCount(UnsignedInt) override { return 3; } + } importer; + + std::ostringstream out; + Error redirectError{&out}; + importer.image3D(7, 3); + CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::image3D(): level 3 out of range for 3 entries\n"); +} + void AbstractImporterTest::image3DCustomDeleter() { struct: AbstractImporter { ImporterFeatures doFeatures() const override { return {}; } @@ -3208,7 +3485,7 @@ void AbstractImporterTest::image3DCustomDeleter() { void doClose() override {} UnsignedInt doImage3DCount() const override { return 1; } - Containers::Optional doImage3D(UnsignedInt) override { + Containers::Optional doImage3D(UnsignedInt, UnsignedInt) override { return ImageData3D{PixelFormat::RGBA8Unorm, {}, Containers::Array{nullptr, 0, [](char*, std::size_t) {}}}; } } importer; diff --git a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp index ea5b1c28ce..84e4057265 100644 --- a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp +++ b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp @@ -199,9 +199,11 @@ void AnyImageImporter::doOpenData(Containers::ArrayView data) { UnsignedInt AnyImageImporter::doImage2DCount() const { return _in->image2DCount(); } -Containers::Optional AnyImageImporter::doImage2D(const UnsignedInt id) { return _in->image2D(id); } +UnsignedInt AnyImageImporter::doImage2DLevelCount(UnsignedInt id) { return _in->image2DLevelCount(id); } + +Containers::Optional AnyImageImporter::doImage2D(const UnsignedInt id, const UnsignedInt level) { return _in->image2D(id, level); } }} CORRADE_PLUGIN_REGISTER(AnyImageImporter, Magnum::Trade::AnyImageImporter, - "cz.mosra.magnum.Trade.AbstractImporter/0.3") + "cz.mosra.magnum.Trade.AbstractImporter/0.3.1") diff --git a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h index ee12f31e51..4c7a9e753e 100644 --- a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h +++ b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h @@ -143,7 +143,8 @@ class MAGNUM_ANYIMAGEIMPORTER_EXPORT AnyImageImporter: public AbstractImporter { MAGNUM_ANYIMAGEIMPORTER_LOCAL void doOpenData(Containers::ArrayView data) override; MAGNUM_ANYIMAGEIMPORTER_LOCAL UnsignedInt doImage2DCount() const override; - MAGNUM_ANYIMAGEIMPORTER_LOCAL Containers::Optional doImage2D(UnsignedInt id) override; + MAGNUM_ANYIMAGEIMPORTER_LOCAL UnsignedInt doImage2DLevelCount(UnsignedInt id) override; + MAGNUM_ANYIMAGEIMPORTER_LOCAL Containers::Optional doImage2D(UnsignedInt id, UnsignedInt level) override; Containers::Pointer _in; }; diff --git a/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp b/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp index d13b83eb11..18c86b14a8 100644 --- a/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp +++ b/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp @@ -196,21 +196,24 @@ std::string AnySceneImporter::doTextureName(const UnsignedInt id) { return _in-> Containers::Optional AnySceneImporter::doTexture(const UnsignedInt id) { return _in->texture(id); } UnsignedInt AnySceneImporter::doImage1DCount() const { return _in->image1DCount(); } +UnsignedInt AnySceneImporter::doImage1DLevelCount(UnsignedInt id) { return _in->image1DLevelCount(id); } Int AnySceneImporter::doImage1DForName(const std::string& name) { return _in->image1DForName(name); } std::string AnySceneImporter::doImage1DName(const UnsignedInt id) { return _in->image1DName(id); } -Containers::Optional AnySceneImporter::doImage1D(const UnsignedInt id) { return _in->image1D(id); } +Containers::Optional AnySceneImporter::doImage1D(const UnsignedInt id, const UnsignedInt level) { return _in->image1D(id, level); } UnsignedInt AnySceneImporter::doImage2DCount() const { return _in->image2DCount(); } +UnsignedInt AnySceneImporter::doImage2DLevelCount(UnsignedInt id) { return _in->image2DLevelCount(id); } Int AnySceneImporter::doImage2DForName(const std::string& name) { return _in->image2DForName(name); } std::string AnySceneImporter::doImage2DName(const UnsignedInt id) { return _in->image2DName(id); } -Containers::Optional AnySceneImporter::doImage2D(const UnsignedInt id) { return _in->image2D(id); } +Containers::Optional AnySceneImporter::doImage2D(const UnsignedInt id, const UnsignedInt level) { return _in->image2D(id, level); } UnsignedInt AnySceneImporter::doImage3DCount() const { return _in->image3DCount(); } +UnsignedInt AnySceneImporter::doImage3DLevelCount(UnsignedInt id) { return _in->image3DLevelCount(id); } Int AnySceneImporter::doImage3DForName(const std::string& name) { return _in->image3DForName(name); } std::string AnySceneImporter::doImage3DName(const UnsignedInt id) { return _in->image3DName(id); } -Containers::Optional AnySceneImporter::doImage3D(const UnsignedInt id) { return _in->image3D(id); } +Containers::Optional AnySceneImporter::doImage3D(const UnsignedInt id, const UnsignedInt level) { return _in->image3D(id, level); } }} CORRADE_PLUGIN_REGISTER(AnySceneImporter, Magnum::Trade::AnySceneImporter, - "cz.mosra.magnum.Trade.AbstractImporter/0.3") + "cz.mosra.magnum.Trade.AbstractImporter/0.3.1") diff --git a/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h b/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h index 9b4cc87353..1cb4868b0b 100644 --- a/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h +++ b/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h @@ -196,19 +196,22 @@ class MAGNUM_ANYSCENEIMPORTER_EXPORT AnySceneImporter: public AbstractImporter { MAGNUM_ANYSCENEIMPORTER_LOCAL Containers::Optional doTexture(UnsignedInt id) override; MAGNUM_ANYSCENEIMPORTER_LOCAL UnsignedInt doImage1DCount() const override; + MAGNUM_ANYSCENEIMPORTER_LOCAL UnsignedInt doImage1DLevelCount(UnsignedInt id) override; MAGNUM_ANYSCENEIMPORTER_LOCAL Int doImage1DForName(const std::string& name) override; MAGNUM_ANYSCENEIMPORTER_LOCAL std::string doImage1DName(UnsignedInt id) override; - MAGNUM_ANYSCENEIMPORTER_LOCAL Containers::Optional doImage1D(UnsignedInt id) override; + MAGNUM_ANYSCENEIMPORTER_LOCAL Containers::Optional doImage1D(UnsignedInt id, UnsignedInt level) override; MAGNUM_ANYSCENEIMPORTER_LOCAL UnsignedInt doImage2DCount() const override; + MAGNUM_ANYSCENEIMPORTER_LOCAL UnsignedInt doImage2DLevelCount(UnsignedInt id) override; MAGNUM_ANYSCENEIMPORTER_LOCAL Int doImage2DForName(const std::string& name) override; MAGNUM_ANYSCENEIMPORTER_LOCAL std::string doImage2DName(UnsignedInt id) override; - MAGNUM_ANYSCENEIMPORTER_LOCAL Containers::Optional doImage2D(UnsignedInt id) override; + MAGNUM_ANYSCENEIMPORTER_LOCAL Containers::Optional doImage2D(UnsignedInt id, UnsignedInt level) override; MAGNUM_ANYSCENEIMPORTER_LOCAL UnsignedInt doImage3DCount() const override; + MAGNUM_ANYSCENEIMPORTER_LOCAL UnsignedInt doImage3DLevelCount(UnsignedInt id) override; MAGNUM_ANYSCENEIMPORTER_LOCAL Int doImage3DForName(const std::string& name) override; MAGNUM_ANYSCENEIMPORTER_LOCAL std::string doImage3DName(UnsignedInt id) override; - MAGNUM_ANYSCENEIMPORTER_LOCAL Containers::Optional doImage3D(UnsignedInt id) override; + MAGNUM_ANYSCENEIMPORTER_LOCAL Containers::Optional doImage3D(UnsignedInt id, UnsignedInt level) override; Containers::Pointer _in; }; diff --git a/src/MagnumPlugins/ObjImporter/ObjImporter.cpp b/src/MagnumPlugins/ObjImporter/ObjImporter.cpp index 2f284df09d..e81778c785 100644 --- a/src/MagnumPlugins/ObjImporter/ObjImporter.cpp +++ b/src/MagnumPlugins/ObjImporter/ObjImporter.cpp @@ -448,4 +448,4 @@ Containers::Optional ObjImporter::doMesh3D(UnsignedInt id) { }} CORRADE_PLUGIN_REGISTER(ObjImporter, Magnum::Trade::ObjImporter, - "cz.mosra.magnum.Trade.AbstractImporter/0.3") + "cz.mosra.magnum.Trade.AbstractImporter/0.3.1") diff --git a/src/MagnumPlugins/TgaImporter/TgaImporter.cpp b/src/MagnumPlugins/TgaImporter/TgaImporter.cpp index c9f85af46f..9eed9ac4f1 100644 --- a/src/MagnumPlugins/TgaImporter/TgaImporter.cpp +++ b/src/MagnumPlugins/TgaImporter/TgaImporter.cpp @@ -71,7 +71,7 @@ void TgaImporter::doOpenData(const Containers::ArrayView data) { UnsignedInt TgaImporter::doImage2DCount() const { return 1; } -Containers::Optional TgaImporter::doImage2D(UnsignedInt) { +Containers::Optional TgaImporter::doImage2D(UnsignedInt, UnsignedInt) { /* Check if the file is long enough */ if(_in.size() < std::streamoff(sizeof(Implementation::TgaHeader))) { Error() << "Trade::TgaImporter::image2D(): the file is too short:" << _in.size() << "bytes"; @@ -149,4 +149,4 @@ Containers::Optional TgaImporter::doImage2D(UnsignedInt) { }} CORRADE_PLUGIN_REGISTER(TgaImporter, Magnum::Trade::TgaImporter, - "cz.mosra.magnum.Trade.AbstractImporter/0.3") + "cz.mosra.magnum.Trade.AbstractImporter/0.3.1") diff --git a/src/MagnumPlugins/TgaImporter/TgaImporter.h b/src/MagnumPlugins/TgaImporter/TgaImporter.h index 11aca871be..0b2085e172 100644 --- a/src/MagnumPlugins/TgaImporter/TgaImporter.h +++ b/src/MagnumPlugins/TgaImporter/TgaImporter.h @@ -110,7 +110,7 @@ class MAGNUM_TGAIMPORTER_EXPORT TgaImporter: public AbstractImporter { void MAGNUM_TGAIMPORTER_LOCAL doOpenData(Containers::ArrayView data) override; void MAGNUM_TGAIMPORTER_LOCAL doClose() override; UnsignedInt MAGNUM_TGAIMPORTER_LOCAL doImage2DCount() const override; - Containers::Optional MAGNUM_TGAIMPORTER_LOCAL doImage2D(UnsignedInt id) override; + Containers::Optional MAGNUM_TGAIMPORTER_LOCAL doImage2D(UnsignedInt id, UnsignedInt level) override; Containers::Array _in; }; From 92a99406280f081d5b321ae07e1fff1ddc87efb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 25 Feb 2020 11:14:40 +0100 Subject: [PATCH 2/2] AnyImageImporter: make the plugin movable. Needed for caching in importers that support mip level import. --- .../AnyImageImporter/AnyImageImporter.cpp | 2 ++ .../AnyImageImporter/AnyImageImporter.h | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp index 84e4057265..7cb387011e 100644 --- a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp +++ b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp @@ -39,6 +39,8 @@ AnyImageImporter::AnyImageImporter(PluginManager::Manager& man AnyImageImporter::AnyImageImporter(PluginManager::AbstractManager& manager, const std::string& plugin): AbstractImporter{manager, plugin} {} +AnyImageImporter::AnyImageImporter(AnyImageImporter&&) noexcept = default; + AnyImageImporter::~AnyImageImporter() = default; ImporterFeatures AnyImageImporter::doFeatures() const { return ImporterFeature::OpenData; } diff --git a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h index 4c7a9e753e..4ddf5e923b 100644 --- a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h +++ b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h @@ -133,6 +133,23 @@ class MAGNUM_ANYIMAGEIMPORTER_EXPORT AnyImageImporter: public AbstractImporter { /** @brief Plugin manager constructor */ explicit AnyImageImporter(PluginManager::AbstractManager& manager, const std::string& plugin); + /** @brief Copying is not allowed */ + AnyImageImporter(const AnyImageImporter&) = delete; + + /** + * @brief Move constructor + * + * See @ref Corrade::PluginManager::AbstractPlugin::AbstractPlugin(AbstractPlugin&&) + * for caveats. + */ + AnyImageImporter(AnyImageImporter&&) noexcept; + + /** @brief Copying is not allowed */ + AnyImageImporter& operator=(const AnyImageImporter&) = delete; + + /** @brief Only move construction is allowed */ + AnyImageImporter& operator=(AnyImageImporter&&) = delete; + ~AnyImageImporter(); private: