From 26766d313520d338d20c6597069c5d3e6cf9917e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 24 Jul 2018 17:01:52 +0200 Subject: [PATCH] Trade: make it possible to attach importer state to image data. The data are immutable by design, so it's a special "move constructor". Usable when a plugin in proxying image import to external importers (such as AnyImageImporter) and wants to attach its own state to the result. --- src/Magnum/Trade/ImageData.cpp | 4 +++ src/Magnum/Trade/ImageData.h | 11 ++++++ src/Magnum/Trade/Test/ImageDataTest.cpp | 47 +++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/src/Magnum/Trade/ImageData.cpp b/src/Magnum/Trade/ImageData.cpp index 39d094a95..b4bf82db0 100644 --- a/src/Magnum/Trade/ImageData.cpp +++ b/src/Magnum/Trade/ImageData.cpp @@ -41,6 +41,10 @@ template ImageData::ImageData(const Compress template ImageData::ImageData(const CompressedPixelStorage storage, const UnsignedInt format, const VectorTypeFor& size, Containers::Array&& data, const void* const importerState) noexcept: ImageData{storage, compressedPixelFormatWrap(format), size, std::move(data), importerState} {} +template ImageData::ImageData(ImageData&& other, const void* const importerState) noexcept: ImageData{std::move(other)} { + _importerState = importerState; +} + template PixelStorage ImageData::storage() const { CORRADE_ASSERT(!_compressed, "Trade::ImageData::storage(): the image is compressed", {}); return _storage; diff --git a/src/Magnum/Trade/ImageData.h b/src/Magnum/Trade/ImageData.h index 38c604c2b..224998cb1 100644 --- a/src/Magnum/Trade/ImageData.h +++ b/src/Magnum/Trade/ImageData.h @@ -218,6 +218,17 @@ template class ImageData { */ template explicit ImageData(CompressedPixelStorage storage, T format, const VectorTypeFor& size, Containers::Array&& data, const void* importerState = nullptr) noexcept; + /** + * @brief Construct from existing data with attached importer state + * + * Useful in cases where importer plugins proxy image loading through + * other importers but want to attach its own importer state to the + * imported data. Importer state from the @p other object is replaced + * with @p importerState, data ownership is transferred and everything + * else stays the same. + */ + explicit ImageData(ImageData&& other, const void* importerState) noexcept; + /** @brief Copying is not allowed */ ImageData(const ImageData&) = delete; diff --git a/src/Magnum/Trade/Test/ImageDataTest.cpp b/src/Magnum/Trade/Test/ImageDataTest.cpp index ae40ca863..9cadc386c 100644 --- a/src/Magnum/Trade/Test/ImageDataTest.cpp +++ b/src/Magnum/Trade/Test/ImageDataTest.cpp @@ -49,6 +49,9 @@ struct ImageDataTest: TestSuite::Tester { void constructMoveCompressedGeneric(); void constructMoveCompressedImplementationSpecific(); + void constructMoveAttachState(); + void constructMoveCompressedAttachState(); + void toViewGeneric(); void toViewImplementationSpecific(); void toViewCompressedGeneric(); @@ -77,6 +80,9 @@ ImageDataTest::ImageDataTest() { &ImageDataTest::constructMoveCompressedGeneric, &ImageDataTest::constructMoveCompressedImplementationSpecific, + &ImageDataTest::constructMoveAttachState, + &ImageDataTest::constructMoveCompressedAttachState, + &ImageDataTest::toViewGeneric, &ImageDataTest::toViewImplementationSpecific, &ImageDataTest::toViewCompressedGeneric, @@ -440,6 +446,47 @@ void ImageDataTest::constructMoveCompressedImplementationSpecific() { CORRADE_COMPARE(c.importerState(), &state); } +void ImageDataTest::constructMoveAttachState() { + auto data = new char[3*6]; + int stateOld, stateNew; + ImageData2D a{PixelStorage{}.setAlignment(1), + GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, Containers::Array{data, 3*6}, &stateOld}; + ImageData2D b{std::move(a), &stateNew}; + + CORRADE_COMPARE(a.data(), nullptr); + CORRADE_COMPARE(a.size(), Vector2i{}); + + CORRADE_VERIFY(!b.isCompressed()); + CORRADE_COMPARE(b.storage().alignment(), 1); + CORRADE_COMPARE(b.format(), pixelFormatWrap(GL::PixelFormat::RGB)); + CORRADE_COMPARE(b.formatExtra(), 1337); + CORRADE_COMPARE(b.pixelSize(), 6); + CORRADE_COMPARE(b.size(), (Vector2i{1, 3})); + CORRADE_COMPARE(b.data(), data); + CORRADE_COMPARE(b.data().size(), 3*6); + CORRADE_COMPARE(b.importerState(), &stateNew); +} + +void ImageDataTest::constructMoveCompressedAttachState() { + auto data = new char[8]; + int stateOld, stateNew; + ImageData2D a{ + CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}), + GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4}, Containers::Array{data, 8}, &stateOld}; + ImageData2D b{std::move(a), &stateNew}; + + CORRADE_COMPARE(a.data(), nullptr); + CORRADE_COMPARE(a.size(), Vector2i{}); + + CORRADE_VERIFY(b.isCompressed()); + CORRADE_COMPARE(b.compressedStorage().compressedBlockSize(), Vector3i{4}); + CORRADE_COMPARE(b.compressedFormat(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1)); + CORRADE_COMPARE(b.size(), (Vector2i{4, 4})); + CORRADE_COMPARE(b.data(), data); + CORRADE_COMPARE(b.data().size(), 8); + CORRADE_COMPARE(b.importerState(), &stateNew); +} + void ImageDataTest::toViewGeneric() { auto data = new char[3*4]; const ImageData2D a{PixelStorage{}.setAlignment(1),