diff --git a/src/Image.h b/src/Image.h index c66291ba0..1bdc52633 100644 --- a/src/Image.h +++ b/src/Image.h @@ -96,7 +96,11 @@ template class Image: public AbstractImage { /** @brief %Image size */ typename DimensionTraits::VectorType size() const { return _size; } - /** @brief Pointer to raw data */ + /** + * @brief Pointer to raw data + * + * @see @ref release() + */ unsigned char* data() { return _data; } const unsigned char* data() const { return _data; } /**< @overload */ @@ -109,9 +113,19 @@ template class Image: public AbstractImage { * * Deletes previous data and replaces them with new. Note that the * data are not copied, but they are deleted on destruction. + * @see @ref release() */ void setData(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, void* data); + /** + * @brief Release data storage + * + * Returns the data pointer and resets internal state to default. + * Deleting the returned array is user responsibility. + * @see @ref setData() + */ + unsigned char* release(); + private: Math::Vector _size; unsigned char* _data; @@ -148,6 +162,14 @@ const return ImageReference(AbstractImage::format(), AbstractImage::type(), _size, _data); } +template inline unsigned char* Image::release() { + /** @todo I need `std::exchange` NOW. */ + unsigned char* const data = _data; + _size = {}; + _data = nullptr; + return data; +} + } #endif diff --git a/src/Test/ImageTest.cpp b/src/Test/ImageTest.cpp index 75849d5f7..1f81ace24 100644 --- a/src/Test/ImageTest.cpp +++ b/src/Test/ImageTest.cpp @@ -36,12 +36,14 @@ class ImageTest: public TestSuite::Tester { void moveConstructor(); void moveAssignment(); void toReference(); + void release(); }; ImageTest::ImageTest() { addTests({&ImageTest::moveConstructor, &ImageTest::moveAssignment, - &ImageTest::toReference}); + &ImageTest::toReference, + &ImageTest::release}); } void ImageTest::moveConstructor() { @@ -89,6 +91,15 @@ void ImageTest::toReference() { } } +void ImageTest::release() { + unsigned char data[] = {'c', 'a', 'f', 'e'}; + Image2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 4}, data); + const unsigned char* const pointer = a.release(); + CORRADE_COMPARE(pointer, data); + CORRADE_VERIFY(!a.data()); + CORRADE_VERIFY(a.size().isZero()); +} + }} CORRADE_TEST_MAIN(Magnum::Test::ImageTest) diff --git a/src/Trade/ImageData.h b/src/Trade/ImageData.h index 2c3652b26..a5e8691ba 100644 --- a/src/Trade/ImageData.h +++ b/src/Trade/ImageData.h @@ -86,10 +86,23 @@ template class ImageData: public AbstractImage { /** @brief %Image size */ typename DimensionTraits::VectorType size() const { return _size; } - /** @brief Pointer to raw data */ + /** + * @brief Pointer to raw data + * + * @see @ref release() + */ unsigned char* data() { return _data; } const unsigned char* data() const { return _data; } /**< @overload */ + /** + * @brief Release data storage + * + * Returns the data pointer and resets internal state to default. + * Deleting the returned array is user responsibility. + * @see @ref data() + */ + unsigned char* release(); + private: Math::Vector _size; unsigned char* _data; @@ -126,6 +139,14 @@ const return ImageReference(AbstractImage::format(), AbstractImage::type(), _size, _data); } +template inline unsigned char* ImageData::release() { + /** @todo I need `std::exchange` NOW. */ + unsigned char* const data = _data; + _size = {}; + _data = nullptr; + return data; +} + }} #endif diff --git a/src/Trade/Test/ImageDataTest.cpp b/src/Trade/Test/ImageDataTest.cpp index da3a7d39d..b805d2be9 100644 --- a/src/Trade/Test/ImageDataTest.cpp +++ b/src/Trade/Test/ImageDataTest.cpp @@ -36,12 +36,14 @@ class ImageDataTest: public TestSuite::Tester { void moveConstructor(); void moveAssignment(); void toReference(); + void release(); }; ImageDataTest::ImageDataTest() { addTests({&ImageDataTest::moveConstructor, &ImageDataTest::moveAssignment, - &ImageDataTest::toReference}); + &ImageDataTest::toReference, + &ImageDataTest::release}); } void ImageDataTest::moveConstructor() { @@ -89,6 +91,15 @@ void ImageDataTest::toReference() { } } +void ImageDataTest::release() { + unsigned char data[] = {'b', 'e', 'e', 'r'}; + ImageData2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 4}, data); + const unsigned char* const pointer = a.release(); + CORRADE_COMPARE(pointer, data); + CORRADE_VERIFY(!a.data()); + CORRADE_VERIFY(a.size().isZero()); +} + }}} CORRADE_TEST_MAIN(Magnum::Trade::Test::ImageDataTest)