diff --git a/doc/changelog.dox b/doc/changelog.dox index 11b4471f0..d3586e2de 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -1020,7 +1020,7 @@ See also: the target implementation. - @relativeref{Trade,AnyImageImporter} and @relativeref{Trade,AnySceneImporter} now can propagate also file callbacks - to the concrete plugin. + and @ref Trade::AbstractImporter::importerState() to the concrete plugin - @relativeref{Trade,AnyImageConverter} now implements also conversion of 3D and multi-level 2D/3D images for formats that support it (such as Basis Universal or OpenEXR) diff --git a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp index 916cd34f9..bbbfbed55 100644 --- a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp +++ b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.cpp @@ -345,6 +345,8 @@ UnsignedInt AnyImageImporter::doImage3DLevelCount(UnsignedInt id) { return _in-> Containers::Optional AnyImageImporter::doImage3D(const UnsignedInt id, const UnsignedInt level) { return _in->image3D(id, level); } +const void* AnyImageImporter::doImporterState() const { return _in->importerState(); } + }} CORRADE_PLUGIN_REGISTER(AnyImageImporter, Magnum::Trade::AnyImageImporter, diff --git a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h index 00312d993..a0f326290 100644 --- a/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h +++ b/src/MagnumPlugins/AnyImageImporter/AnyImageImporter.h @@ -157,10 +157,11 @@ propagated to the concrete implementation. A warning is emitted in case an option set is not present in the default configuration of the target plugin. Calls to the @ref image1DCount() / @ref image2DCount() / @ref image3DCount(), -@ref image1DLevelCount() / @ref image2DLevelCount() / @ref image3DLevelCount() -and @ref image1D() / @ref image2D() / @ref image3D() functions are then proxied -to the concrete implementation. The @ref close() function closes and discards -the internally instantiated plugin; @ref isOpened() works as usual. +@ref image1DLevelCount() / @ref image2DLevelCount() / @ref image3DLevelCount(), +@ref image1D() / @ref image2D() / @ref image3D() and @ref importerState() +functions are then proxied to the concrete implementation. The @ref close() +function closes and discards the internally instantiated plugin; +@ref isOpened() works as usual. Besides delegating the flags, the @ref AnyImageImporter itself recognizes @ref ImporterFlag::Verbose, printing info about the concrete plugin being used @@ -213,6 +214,8 @@ class MAGNUM_ANYIMAGEIMPORTER_EXPORT AnyImageImporter: public AbstractImporter { MAGNUM_ANYIMAGEIMPORTER_LOCAL UnsignedInt doImage3DLevelCount(UnsignedInt id) override; MAGNUM_ANYIMAGEIMPORTER_LOCAL Containers::Optional doImage3D(UnsignedInt id, UnsignedInt level) override; + MAGNUM_ANYIMAGEIMPORTER_LOCAL const void* doImporterState() const override; + Containers::Pointer _in; }; diff --git a/src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp b/src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp index 2186491bf..4522da154 100644 --- a/src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp +++ b/src/MagnumPlugins/AnyImageImporter/Test/AnyImageImporterTest.cpp @@ -26,9 +26,11 @@ */ #include +#include #include #include #include +#include #include #include #include @@ -70,6 +72,8 @@ struct AnyImageImporterTest: TestSuite::Tester { void imageLevels2D(); void imageLevels3D(); + void importerState(); + /* Explicitly forbid system-wide plugin dependencies */ PluginManager::Manager _manager{"nonexistent"}; }; @@ -242,7 +246,9 @@ AnyImageImporterTest::AnyImageImporterTest() { &AnyImageImporterTest::images3D, &AnyImageImporterTest::imageLevels1D, &AnyImageImporterTest::imageLevels2D, - &AnyImageImporterTest::imageLevels3D}); + &AnyImageImporterTest::imageLevels3D, + + &AnyImageImporterTest::importerState}); /* Load the plugin directly from the build tree. Otherwise it's static and already loaded. */ @@ -653,6 +659,33 @@ void AnyImageImporterTest::imageLevels3D() { CORRADE_COMPARE(image->size(), (Vector3i{2, 1, 3})); } +void AnyImageImporterTest::importerState() { + PluginManager::Manager manager{MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR}; + #ifdef ANYIMAGEIMPORTER_PLUGIN_FILENAME + CORRADE_VERIFY(manager.load(ANYIMAGEIMPORTER_PLUGIN_FILENAME) & PluginManager::LoadState::Loaded); + #endif + + /* Catch also ABI and interface mismatch errors */ + if(!(manager.load("StbImageImporter") & PluginManager::LoadState::Loaded)) + CORRADE_SKIP("StbImageImporter plugin can't be loaded."); + + /* Ensure StbImageImporter is picked, and not for example + DevIlImageImporter */ + manager.setPreferredPlugins("GifImporter", {"StbImageImporter"}); + + Containers::Pointer importer = manager.instantiate("AnyImageImporter"); + CORRADE_VERIFY(importer->openFile(Utility::Path::join(ANYIMAGEIMPORTER_TEST_DIR, "dispose_bgnd.gif"))); + + /* Testing the same as in StbImageImporterTest::animatedGif(). Importer + state should expose the delays, in milliseconds. */ + CORRADE_COMPARE(importer->image2DCount(), 5); + CORRADE_VERIFY(importer->importerState()); + CORRADE_COMPARE_AS( + Containers::arrayView(reinterpret_cast(importer->importerState()), importer->image2DCount()), + Containers::arrayView({1000, 1000, 1000, 1000, 1000}), + TestSuite::Compare::Container); +} + }}}} CORRADE_TEST_MAIN(Magnum::Trade::Test::AnyImageImporterTest) diff --git a/src/MagnumPlugins/AnyImageImporter/Test/CMakeLists.txt b/src/MagnumPlugins/AnyImageImporter/Test/CMakeLists.txt index b1fbc1378..990023fcb 100644 --- a/src/MagnumPlugins/AnyImageImporter/Test/CMakeLists.txt +++ b/src/MagnumPlugins/AnyImageImporter/Test/CMakeLists.txt @@ -54,6 +54,8 @@ corrade_add_test(AnyImageImporterTest AnyImageImporterTest.cpp 8x8.astc # Generated by AnyImageConverterTest::propagateConfiguration2D() depth32f-custom-channels.exr + # From StbImageImporter test data + dispose_bgnd.gif # From KtxImporter test data 1d-mipmaps.ktx2 2d-mipmaps.ktx2 diff --git a/src/MagnumPlugins/AnyImageImporter/Test/dispose_bgnd.gif b/src/MagnumPlugins/AnyImageImporter/Test/dispose_bgnd.gif new file mode 100644 index 000000000..d68504010 Binary files /dev/null and b/src/MagnumPlugins/AnyImageImporter/Test/dispose_bgnd.gif differ diff --git a/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp b/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp index 6456176e9..04d3fed65 100644 --- a/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp +++ b/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp @@ -347,6 +347,8 @@ Int AnySceneImporter::doImage3DForName(const Containers::StringView name) { retu Containers::String AnySceneImporter::doImage3DName(const UnsignedInt id) { return _in->image3DName(id); } Containers::Optional AnySceneImporter::doImage3D(const UnsignedInt id, const UnsignedInt level) { return _in->image3D(id, level); } +const void* AnySceneImporter::doImporterState() const { return _in->importerState(); } + }} CORRADE_PLUGIN_REGISTER(AnySceneImporter, Magnum::Trade::AnySceneImporter, diff --git a/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h b/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h index 3c738b922..89d5efdfa 100644 --- a/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h +++ b/src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h @@ -164,10 +164,10 @@ the target plugin. Calls to the @ref animation(), @ref scene(), @ref light(), @ref camera(), @ref skin2D(), @ref skin3D(), @ref mesh(), @ref material(), @ref texture(), -@ref image1D(), @ref image2D(), @ref image3D() and corresponding -count-/name-related functions are then proxied to the concrete implementation. -The @ref close() function closes and discards the internally instantiated -plugin; @ref isOpened() works as usual. +@ref image1D(), @ref image2D(), @ref image3D(), corresponding +count-/name-related functions and the @ref importerState() function are then +proxied to the concrete implementation. The @ref close() function closes and +discards the internally instantiated plugin; @ref isOpened() works as usual. While the @ref meshAttributeName(), @ref meshAttributeForName(), @ref sceneFieldName() and @ref sceneFieldForName() APIs can be called without a @@ -302,6 +302,8 @@ class MAGNUM_ANYSCENEIMPORTER_EXPORT AnySceneImporter: public AbstractImporter { MAGNUM_ANYSCENEIMPORTER_LOCAL Containers::String doImage3DName(UnsignedInt id) override; MAGNUM_ANYSCENEIMPORTER_LOCAL Containers::Optional doImage3D(UnsignedInt id, UnsignedInt level) override; + MAGNUM_ANYSCENEIMPORTER_LOCAL const void* doImporterState() const override; + Containers::Pointer _in; }; diff --git a/src/MagnumPlugins/AnySceneImporter/Test/AnySceneImporterTest.cpp b/src/MagnumPlugins/AnySceneImporter/Test/AnySceneImporterTest.cpp index dafe60bf9..14f1539a6 100644 --- a/src/MagnumPlugins/AnySceneImporter/Test/AnySceneImporterTest.cpp +++ b/src/MagnumPlugins/AnySceneImporter/Test/AnySceneImporterTest.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "Magnum/Math/Vector3.h" @@ -107,6 +108,8 @@ struct AnySceneImporterTest: TestSuite::Tester { void imageLevels2D(); void imageLevels3D(); + void importerState(); + /* Explicitly forbid system-wide plugin dependencies */ PluginManager::Manager _manager{"nonexistent"}; }; @@ -240,7 +243,9 @@ AnySceneImporterTest::AnySceneImporterTest() { &AnySceneImporterTest::images3D, &AnySceneImporterTest::imageLevels1D, &AnySceneImporterTest::imageLevels2D, - &AnySceneImporterTest::imageLevels3D}); + &AnySceneImporterTest::imageLevels3D, + + &AnySceneImporterTest::importerState}); /* Load the plugin directly from the build tree. Otherwise it's static and already loaded. */ @@ -891,6 +896,23 @@ void AnySceneImporterTest::imageLevels3D() { CORRADE_COMPARE(image->size(), (Vector3i{1, 1, 3})); } +void AnySceneImporterTest::importerState() { + PluginManager::Manager manager{MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR}; + #ifdef ANYSCENEIMPORTER_PLUGIN_FILENAME + CORRADE_VERIFY(manager.load(ANYSCENEIMPORTER_PLUGIN_FILENAME) & PluginManager::LoadState::Loaded); + #endif + + /* Catch also ABI and interface mismatch errors */ + if(manager.load("GltfImporter") < PluginManager::LoadState::Loaded) + CORRADE_SKIP("GltfImporter plugin can't be loaded."); + + Containers::Pointer importer = manager.instantiate("AnySceneImporter"); + CORRADE_VERIFY(importer->openFile(Utility::Path::join(ANYSCENEIMPORTER_TEST_DIR, "meshes.gltf"))); + + CORRADE_VERIFY(importer->importerState()); + CORRADE_COMPARE(static_cast(importer->importerState())->root()["asset"]["version"].asString(), "2.0"); +} + }}}} CORRADE_TEST_MAIN(Magnum::Trade::Test::AnySceneImporterTest)