diff --git a/doc/changelog.dox b/doc/changelog.dox index 2133c17c6..32f00832f 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -213,6 +213,17 @@ See also: to the complexity of this change, no backwards compatibility is provided. - The `magnum-info` utility was renamed to @ref magnum-gl-info. No backwards compatibility symlinks or aliases are provided. +- @ref PixelStorage::dataProperties(), @ref Image::dataProperties(), + @ref ImageView::dataProperties(), @ref Trade::ImageData::dataProperties(), and @ref GL::BufferImage::dataProperties() now return just a pair of two + values, as the third value is now accessible directly through + @ref Image::pixelSize() "*Image::pixelSize()" and no longer calculated + on-demand +- @ref CompressedPixelStorage::dataProperties(), + @ref CompressedImage::dataProperties(), + @ref CompressedImageView::dataProperties() and + @ref GL::CompressedBufferImage::dataProperties() now return just a pair + of two values, as the third value is accessible directly through + @ref CompressedPixelStorage::compressedBlockDataSize() - @ref ImageView and @ref CompressedImageView methods are no longer @cpp constexpr @ce. It might be possible to have them @cpp constexpr @ce in C++14, but the resulting increase in maintenance costs and compile times is diff --git a/src/Magnum/DebugTools/CompareImage.cpp b/src/Magnum/DebugTools/CompareImage.cpp index 0ee265a29..482a4e4a9 100644 --- a/src/Magnum/DebugTools/CompareImage.cpp +++ b/src/Magnum/DebugTools/CompareImage.cpp @@ -49,11 +49,11 @@ template Float calculateImageDelta(const ImageView2D& /* Precalculate parameters for pixel access */ Math::Vector2 dataOffset, dataSize; - std::tie(dataOffset, dataSize, std::ignore) = actual.dataProperties(); + std::tie(dataOffset, dataSize) = actual.dataProperties(); const char* const actualPixels = actual.data() + dataOffset.sum(); const std::size_t actualStride = dataSize.x(); - std::tie(dataOffset, dataSize, std::ignore) = expected.dataProperties(); + std::tie(dataOffset, dataSize) = expected.dataProperties(); const char* const expectedPixels = expected.data() + dataOffset.sum(); const std::size_t expectedStride = dataSize.x(); @@ -328,11 +328,11 @@ void printPixelDeltas(Debug& out, const std::vector& delta, const ImageVi /* Precalculate parameters for pixel access */ Math::Vector2 offset, size; - std::tie(offset, size, std::ignore) = actual.dataProperties(); + std::tie(offset, size) = actual.dataProperties(); const char* const actualPixels = actual.data() + offset.sum(); const std::size_t actualStride = size.x(); - std::tie(offset, size, std::ignore) = expected.dataProperties(); + std::tie(offset, size) = expected.dataProperties(); const char* const expectedPixels = expected.data() + offset.sum(); const std::size_t expectedStride = size.x(); diff --git a/src/Magnum/GL/BufferImage.h b/src/Magnum/GL/BufferImage.h index e5f825cea..45643599c 100644 --- a/src/Magnum/GL/BufferImage.h +++ b/src/Magnum/GL/BufferImage.h @@ -334,7 +334,7 @@ template class BufferImage { * * See @ref PixelStorage::dataProperties() for more information. */ - std::tuple, VectorTypeFor, std::size_t> dataProperties() const { + std::pair, VectorTypeFor> dataProperties() const { return Magnum::Implementation::imageDataProperties(*this); } @@ -666,7 +666,7 @@ template class CompressedBufferImage { * @requires_gl Compressed pixel storage is hardcoded in OpenGL ES and * WebGL. */ - std::tuple, VectorTypeFor, std::size_t> dataProperties() const { + std::pair, VectorTypeFor> dataProperties() const { return Magnum::Implementation::compressedImageDataProperties(*this); } diff --git a/src/Magnum/GL/Test/BufferImageGLTest.cpp b/src/Magnum/GL/Test/BufferImageGLTest.cpp index bb4687e58..56c869883 100644 --- a/src/Magnum/GL/Test/BufferImageGLTest.cpp +++ b/src/Magnum/GL/Test/BufferImageGLTest.cpp @@ -53,6 +53,9 @@ struct BufferImageGLTest: OpenGLTester { void constructMove(); void constructMoveCompressed(); + void dataProperties(); + void dataPropertiesCompressed(); + void setData(); void setDataGeneric(); void setDataCompressed(); @@ -80,6 +83,9 @@ BufferImageGLTest::BufferImageGLTest() { &BufferImageGLTest::constructMove, &BufferImageGLTest::constructMoveCompressed, + &BufferImageGLTest::dataProperties, + &BufferImageGLTest::dataPropertiesCompressed, + &BufferImageGLTest::setData, &BufferImageGLTest::setDataGeneric, &BufferImageGLTest::setDataCompressed, @@ -444,6 +450,31 @@ void BufferImageGLTest::constructMoveCompressed() { CORRADE_COMPARE(c.buffer().id(), id); } +void BufferImageGLTest::dataProperties() { + const char data[224]{}; + BufferImage3D image{ + PixelStorage{} + .setAlignment(8) + .setSkip({3, 2, 1}), + Magnum::PixelFormat::R8Unorm, {2, 4, 6}, data, BufferUsage::StaticDraw}; + CORRADE_COMPARE(image.dataProperties(), + (std::pair, Math::Vector3>{{3, 16, 32}, {8, 4, 6}})); +} + +void BufferImageGLTest::dataPropertiesCompressed() { + /* Yes, I know, this is totally bogus and doesn't match the BC1 format */ + const char data[1]{}; + CompressedBufferImage3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({3, 4, 5}) + .setCompressedBlockDataSize(16) + .setImageHeight(12) + .setSkip({5, 8, 11}), + CompressedPixelFormat::Bc1RGBAUnorm, {2, 8, 11}, data, BufferUsage::StaticDraw}; + CORRADE_COMPARE(image.dataProperties(), + (std::pair, Math::Vector3>{{2*16, 2*16, 9*16}, {1, 3, 3}})); +} + void BufferImageGLTest::setData() { const char data[4] = { 'a', 'b', 'c', 'd' }; BufferImage2D a{PixelStorage{}.setAlignment(1), diff --git a/src/Magnum/Image.h b/src/Magnum/Image.h index 4d776d5c5..665da1669 100644 --- a/src/Magnum/Image.h +++ b/src/Magnum/Image.h @@ -325,7 +325,7 @@ template class Image { * * See @ref PixelStorage::dataProperties() for more information. */ - std::tuple, VectorTypeFor, std::size_t> dataProperties() const { + std::pair, VectorTypeFor> dataProperties() const { return Implementation::imageDataProperties(*this); } @@ -563,7 +563,7 @@ template class CompressedImage { * See @ref CompressedPixelStorage::dataProperties() for more * information. */ - std::tuple, VectorTypeFor, std::size_t> dataProperties() const { + std::pair, VectorTypeFor> dataProperties() const { return Implementation::compressedImageDataProperties(*this); } diff --git a/src/Magnum/ImageView.h b/src/Magnum/ImageView.h index ca7e5fe36..8d11af276 100644 --- a/src/Magnum/ImageView.h +++ b/src/Magnum/ImageView.h @@ -373,7 +373,7 @@ template class ImageView { * * See @ref PixelStorage::dataProperties() for more information. */ - std::tuple, VectorTypeFor, std::size_t> dataProperties() const { + std::pair, VectorTypeFor> dataProperties() const { return Implementation::imageDataProperties(*this); } @@ -590,7 +590,7 @@ template class CompressedImageView { * See @ref CompressedPixelStorage::dataProperties() for more * information. */ - std::tuple, VectorTypeFor, std::size_t> dataProperties() const { + std::pair, VectorTypeFor> dataProperties() const { return Implementation::compressedImageDataProperties(*this); } diff --git a/src/Magnum/PixelStorage.cpp b/src/Magnum/PixelStorage.cpp index 4a14aeb84..25530e3f9 100644 --- a/src/Magnum/PixelStorage.cpp +++ b/src/Magnum/PixelStorage.cpp @@ -50,7 +50,7 @@ std::pair, Math::Vector3> PixelStorage:: size.product() ? dataSize : Math::Vector3{}}; } -std::tuple, Math::Vector3, std::size_t> CompressedPixelStorage::dataProperties(const Vector3i& size) const { +std::pair, Math::Vector3> CompressedPixelStorage::dataProperties(const Vector3i& size) const { CORRADE_ASSERT(_blockDataSize && _blockSize.product(), "CompressedPixelStorage::dataProperties(): expected non-zero storage parameters", {}); const Vector3i blockCount = (size + _blockSize - Vector3i{1})/_blockSize; @@ -62,7 +62,7 @@ std::tuple, Math::Vector3, std::size_t> const Vector3i skipBlockCount = (_skip + _blockSize - Vector3i{1})/_blockSize; const Math::Vector3 offset = (Math::Vector3{1, dataSize.x(), dataSize.xy().product()}*Math::Vector3{skipBlockCount})*_blockDataSize; - return std::make_tuple(offset, size.product() ? dataSize : Math::Vector3{}, _blockDataSize); + return std::make_pair(offset, size.product() ? dataSize : Math::Vector3{}); } bool CompressedPixelStorage::operator==(const CompressedPixelStorage& other) const { diff --git a/src/Magnum/PixelStorage.h b/src/Magnum/PixelStorage.h index 519037c56..94fec69ce 100644 --- a/src/Magnum/PixelStorage.h +++ b/src/Magnum/PixelStorage.h @@ -30,13 +30,15 @@ */ #include -#include +#include #include "Magnum/Magnum.h" #include "Magnum/Math/Vector3.h" #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) #include "Magnum/GL/PixelFormat.h" + +#include #endif namespace Magnum { @@ -265,7 +267,7 @@ class MAGNUM_EXPORT CompressedPixelStorage: public PixelStorage { * Expects @ref compressedBlockSize() and @ref compressedBlockDataSize() * to be non-zero. */ - std::tuple, Math::Vector3, std::size_t> dataProperties(const Vector3i& size) const; + std::pair, Math::Vector3> dataProperties(const Vector3i& size) const; /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT @@ -310,18 +312,17 @@ inline std::tuple, Math::Vector3, std::s namespace Implementation { /* Used in *Image::dataProperties() */ - template std::tuple, Math::Vector, std::size_t> imageDataProperties(const T& image) { + template std::pair, Math::Vector> imageDataProperties(const T& image) { Math::Vector3 offset, dataSize; std::tie(offset, dataSize) = image.storage().dataProperties(image.pixelSize(), Vector3i::pad(image.size(), 1)); - return std::make_tuple(Math::Vector::pad(offset), Math::Vector::pad(dataSize), image.pixelSize()); + return std::make_pair(Math::Vector::pad(offset), Math::Vector::pad(dataSize)); } /* Used in Compressed*Image::dataProperties() */ - template std::tuple, Math::Vector, std::size_t> compressedImageDataProperties(const T& image) { + template std::pair, Math::Vector> compressedImageDataProperties(const T& image) { Math::Vector3 offset, blockCount; - std::size_t blockSize; - std::tie(offset, blockCount, blockSize) = image.storage().dataProperties(Vector3i::pad(image.size(), 1)); - return std::make_tuple(Math::Vector::pad(offset), Math::Vector::pad(blockCount), blockSize); + std::tie(offset, blockCount) = image.storage().dataProperties(Vector3i::pad(image.size(), 1)); + return std::make_pair(Math::Vector::pad(offset), Math::Vector::pad(blockCount)); } /* Used in image query functions */ @@ -352,12 +353,11 @@ namespace Implementation { CORRADE_INTERNAL_ASSERT(image.storage().compressedBlockSize().product() && image.storage().compressedBlockDataSize()); Math::Vector3 offset, blockCount; - std::size_t blockDataSize; - std::tie(offset, blockCount, blockDataSize) = image.storage().dataProperties(Vector3i::pad(size, 1)); + std::tie(offset, blockCount) = image.storage().dataProperties(Vector3i::pad(size, 1)); const auto realBlockCount = Math::Vector3{(Vector3i::pad(size, 1) + image.storage().compressedBlockSize() - Vector3i{1})/image.storage().compressedBlockSize()}; - return {offset.sum(), (blockCount.product() - (blockCount.x() - realBlockCount.x()) - (blockCount.y() - realBlockCount.y())*blockCount.x())*blockDataSize}; + return {offset.sum(), (blockCount.product() - (blockCount.x() - realBlockCount.x()) - (blockCount.y() - realBlockCount.y())*blockCount.x())*image.storage().compressedBlockDataSize()}; } /* Used in image query functions */ @@ -373,7 +373,7 @@ namespace Implementation { } template std::ptrdiff_t pixelStorageSkipOffsetFor(const T& image, const Math::Vector& size) { - return std::get<0>(image.storage().dataProperties(image.pixelSize(), Vector3i::pad(size, 1))).sum(); + return image.storage().dataProperties(image.pixelSize(), Vector3i::pad(size, 1)).first.sum(); } template std::ptrdiff_t pixelStorageSkipOffset(const T& image) { return pixelStorageSkipOffsetFor(image, image.size()); diff --git a/src/Magnum/Test/ImageTest.cpp b/src/Magnum/Test/ImageTest.cpp index 49623e67e..dc2eb213e 100644 --- a/src/Magnum/Test/ImageTest.cpp +++ b/src/Magnum/Test/ImageTest.cpp @@ -61,6 +61,9 @@ struct ImageTest: TestSuite::Tester { void access(); void accessCompressed(); + void dataProperties(); + void dataPropertiesCompressed(); + void release(); void releaseCompressed(); }; @@ -93,6 +96,9 @@ ImageTest::ImageTest() { &ImageTest::access, &ImageTest::accessCompressed, + &ImageTest::dataProperties, + &ImageTest::dataPropertiesCompressed, + &ImageTest::release, &ImageTest::releaseCompressed}); } @@ -606,6 +612,31 @@ void ImageTest::accessCompressed() { CORRADE_COMPARE(ca.data(), data); } +void ImageTest::dataProperties() { + Image3D image{ + PixelStorage{} + .setAlignment(8) + .setSkip({3, 2, 1}), + PixelFormat::R8Unorm, {2, 4, 6}, + Containers::Array{224}}; + CORRADE_COMPARE(image.dataProperties(), + (std::pair, Math::Vector3>{{3, 16, 32}, {8, 4, 6}})); +} + +void ImageTest::dataPropertiesCompressed() { + /* Yes, I know, this is totally bogus and doesn't match the BC1 format */ + CompressedImage3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({3, 4, 5}) + .setCompressedBlockDataSize(16) + .setImageHeight(12) + .setSkip({5, 8, 11}), + CompressedPixelFormat::Bc1RGBAUnorm, {2, 8, 11}, + Containers::Array{1}}; + CORRADE_COMPARE(image.dataProperties(), + (std::pair, Math::Vector3>{{2*16, 2*16, 9*16}, {1, 3, 3}})); +} + void ImageTest::release() { char data[] = {'c', 'a', 'f', 'e'}; Image2D a(PixelFormat::RGBA8Unorm, {1, 1}, Containers::Array{data, 4}); diff --git a/src/Magnum/Test/ImageViewTest.cpp b/src/Magnum/Test/ImageViewTest.cpp index 46aec51c7..3bc0d8e61 100644 --- a/src/Magnum/Test/ImageViewTest.cpp +++ b/src/Magnum/Test/ImageViewTest.cpp @@ -48,6 +48,9 @@ struct ImageViewTest: TestSuite::Tester { void constructInvalidSize(); void constructCompressedInvalidSize(); + void dataProperties(); + void dataPropertiesCompressed(); + void setData(); void setDataCompressed(); @@ -70,6 +73,9 @@ ImageViewTest::ImageViewTest() { &ImageViewTest::constructInvalidSize, &ImageViewTest::constructCompressedInvalidSize, + &ImageViewTest::dataProperties, + &ImageViewTest::dataPropertiesCompressed, + &ImageViewTest::setData, &ImageViewTest::setDataCompressed, @@ -486,6 +492,32 @@ void ImageViewTest::constructCompressedInvalidSize() { } } +void ImageViewTest::dataProperties() { + const char data[224]{}; + ImageView3D image{ + PixelStorage{} + .setAlignment(8) + .setSkip({3, 2, 1}), + PixelFormat::R8Unorm, {2, 4, 6}, data}; + CORRADE_COMPARE(image.dataProperties(), + (std::pair, Math::Vector3>{{3, 16, 32}, {8, 4, 6}})); +} + +void ImageViewTest::dataPropertiesCompressed() { + /* Yes, I know, this is totally bogus and doesn't match the BC1 format */ + const char data[1]{}; + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({3, 4, 5}) + .setCompressedBlockDataSize(16) + .setImageHeight(12) + .setSkip({5, 8, 11}), + CompressedPixelFormat::Bc1RGBAUnorm, {2, 8, 11}, + data}; + CORRADE_COMPARE(image.dataProperties(), + (std::pair, Math::Vector3>{{2*16, 2*16, 9*16}, {1, 3, 3}})); +} + void ImageViewTest::setData() { const char data[3*3]{}; ImageView2D a{PixelStorage{}.setAlignment(1), diff --git a/src/Magnum/Test/PixelStorageTest.cpp b/src/Magnum/Test/PixelStorageTest.cpp index 261ae6aa3..78ed12943 100644 --- a/src/Magnum/Test/PixelStorageTest.cpp +++ b/src/Magnum/Test/PixelStorageTest.cpp @@ -246,7 +246,7 @@ void PixelStorageTest::dataPropertiesCompressed() { .setCompressedBlockDataSize(16); CORRADE_COMPARE(storage.dataProperties({2, 8, 11}), - (std::tuple{{}, {1, 2, 3}, 16})); + (std::pair{{}, {1, 2, 3}})); } void PixelStorageTest::dataPropertiesCompressedRowLength() { @@ -257,7 +257,7 @@ void PixelStorageTest::dataPropertiesCompressedRowLength() { .setSkip({5, 8, 0}); CORRADE_COMPARE(storage.dataProperties({2, 8, 11}), - (std::tuple{{2*9, 8*9, 0}, {4, 2, 3}, 9})); + (std::pair{{2*9, 8*9, 0}, {4, 2, 3}})); } void PixelStorageTest::dataPropertiesCompressedImageHeight() { @@ -268,7 +268,7 @@ void PixelStorageTest::dataPropertiesCompressedImageHeight() { .setSkip({5, 8, 11}); CORRADE_COMPARE(storage.dataProperties({2, 8, 11}), - (std::tuple{{2*16, 2*16, 9*16}, {1, 3, 3}, 16})); + (std::pair{{2*16, 2*16, 9*16}, {1, 3, 3}})); } void PixelStorageTest::dataOffsetSizeCompressed() { diff --git a/src/Magnum/Trade/ImageData.cpp b/src/Magnum/Trade/ImageData.cpp index 6bc1e0846..39d094a95 100644 --- a/src/Magnum/Trade/ImageData.cpp +++ b/src/Magnum/Trade/ImageData.cpp @@ -71,7 +71,7 @@ template UnsignedInt ImageData::pixelSize() return _pixelSize; } -template std::tuple, VectorTypeFor, std::size_t> ImageData::dataProperties() const { +template std::pair, VectorTypeFor> ImageData::dataProperties() const { CORRADE_ASSERT(!_compressed, "Trade::ImageData::dataProperties(): the image is compressed", {}); return Implementation::imageDataProperties(*this); } diff --git a/src/Magnum/Trade/ImageData.h b/src/Magnum/Trade/ImageData.h index cb7d11275..aa790d7b6 100644 --- a/src/Magnum/Trade/ImageData.h +++ b/src/Magnum/Trade/ImageData.h @@ -335,7 +335,7 @@ template class ImageData { * @ref PixelStorage::dataProperties() for more information. * @see @ref isCompressed() */ - std::tuple, VectorTypeFor, std::size_t> dataProperties() const; + std::pair, VectorTypeFor> dataProperties() const; /* compressed data properties are not available because the importers are not setting any block size pixel storage properties to avoid diff --git a/src/Magnum/Trade/Test/ImageDataTest.cpp b/src/Magnum/Trade/Test/ImageDataTest.cpp index 12a3ff7c2..880a13797 100644 --- a/src/Magnum/Trade/Test/ImageDataTest.cpp +++ b/src/Magnum/Trade/Test/ImageDataTest.cpp @@ -55,6 +55,7 @@ struct ImageDataTest: TestSuite::Tester { void toViewCompressedImplementationSpecific(); void access(); + void dataProperties(); void release(); void releaseCompressed(); @@ -82,6 +83,7 @@ ImageDataTest::ImageDataTest() { &ImageDataTest::toViewCompressedImplementationSpecific, &ImageDataTest::access, + &ImageDataTest::dataProperties, &ImageDataTest::release, &ImageDataTest::releaseCompressed}); @@ -496,6 +498,17 @@ void ImageDataTest::access() { CORRADE_COMPARE(ca.data(), data); } +void ImageDataTest::dataProperties() { + ImageData3D image{ + PixelStorage{} + .setAlignment(8) + .setSkip({3, 2, 1}), + PixelFormat::R8Unorm, {2, 4, 6}, + Containers::Array{224}}; + CORRADE_COMPARE(image.dataProperties(), + (std::pair, Math::Vector3>{{3, 16, 32}, {8, 4, 6}})); +} + void ImageDataTest::release() { char data[] = {'b', 'e', 'e', 'r'}; Trade::ImageData2D a{PixelFormat::RGBA8Unorm, {1, 1}, Containers::Array{data, 4}};