From 1cfd2dc7b5c361e10d36c4a5f6569646fc0e00b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 2 Aug 2016 20:57:01 +0200 Subject: [PATCH] Fix image data size computation with pixel storage skip applied. It now tries to find smallest line/rectangle/cube that covers the area. Previously it was a bit more in some cases. --- src/Magnum/BufferImage.h | 4 +- src/Magnum/Image.h | 4 +- src/Magnum/ImageView.h | 2 +- src/Magnum/PixelStorage.cpp | 10 +- src/Magnum/PixelStorage.h | 63 ++++++------ src/Magnum/Test/PixelStorageTest.cpp | 99 ++++++++++++------- src/Magnum/Trade/ImageData.cpp | 2 +- src/Magnum/Trade/ImageData.h | 2 +- .../TgaImageConverter/TgaImageConverter.cpp | 2 +- 9 files changed, 110 insertions(+), 78 deletions(-) diff --git a/src/Magnum/BufferImage.h b/src/Magnum/BufferImage.h index 7e351e6eb..8d63773be 100644 --- a/src/Magnum/BufferImage.h +++ b/src/Magnum/BufferImage.h @@ -145,7 +145,7 @@ template class BufferImage { * * See @ref PixelStorage::dataProperties() for more information. */ - std::tuple, std::size_t> dataProperties() const { + std::tuple, VectorTypeFor, std::size_t> dataProperties() const { return Implementation::imageDataProperties(*this); } @@ -333,7 +333,7 @@ template class CompressedBufferImage { * @requires_gl Compressed pixel storage is hardcoded in OpenGL ES and * WebGL. */ - std::tuple, std::size_t> dataProperties() const { + std::tuple, VectorTypeFor, std::size_t> dataProperties() const { return Implementation::compressedImageDataProperties(*this); } #endif diff --git a/src/Magnum/Image.h b/src/Magnum/Image.h index 50762aadf..c62379a44 100644 --- a/src/Magnum/Image.h +++ b/src/Magnum/Image.h @@ -135,7 +135,7 @@ template class Image { * * See @ref PixelStorage::dataProperties() for more information. */ - std::tuple, std::size_t> dataProperties() const { + std::tuple, VectorTypeFor, std::size_t> dataProperties() const { return Implementation::imageDataProperties(*this); } @@ -339,7 +339,7 @@ template class CompressedImage { * @requires_gl Compressed pixel storage is hardcoded in OpenGL ES and * WebGL. */ - std::tuple, std::size_t> dataProperties() const { + std::tuple, VectorTypeFor, std::size_t> dataProperties() const { return Implementation::compressedImageDataProperties(*this); } #endif diff --git a/src/Magnum/ImageView.h b/src/Magnum/ImageView.h index cdc5067f4..3775bbcee 100644 --- a/src/Magnum/ImageView.h +++ b/src/Magnum/ImageView.h @@ -134,7 +134,7 @@ template class ImageView { * * See @ref PixelStorage::dataProperties() for more information. */ - std::tuple, std::size_t> dataProperties() const { + std::tuple, VectorTypeFor, std::size_t> dataProperties() const { return Implementation::imageDataProperties(*this); } diff --git a/src/Magnum/PixelStorage.cpp b/src/Magnum/PixelStorage.cpp index 704875b9b..dd41e0752 100644 --- a/src/Magnum/PixelStorage.cpp +++ b/src/Magnum/PixelStorage.cpp @@ -156,7 +156,7 @@ std::size_t PixelStorage::pixelSize(PixelFormat format, PixelType type) { CORRADE_ASSERT_UNREACHABLE(); } -std::tuple, std::size_t> PixelStorage::dataProperties(const PixelFormat format, const PixelType type, const Vector3i& size) const { +std::tuple, Math::Vector3, std::size_t> PixelStorage::dataProperties(const PixelFormat format, const PixelType type, const Vector3i& size) const { const std::size_t pixelSize = PixelStorage::pixelSize(format, type); const Math::Vector3 dataSize{ std::size_t(((( @@ -170,13 +170,13 @@ std::tuple, std::size_t> PixelStorage::d std::size_t(size.y()), #endif std::size_t(size.z())}; - const std::size_t offset = (Math::Vector3{pixelSize, dataSize.x(), dataSize.xy().product()}*Math::Vector3{_skip}).sum(); - return std::make_tuple(offset, size.product() ? dataSize : Math::Vector3{}, pixelSize); + return std::make_tuple(Math::Vector3{pixelSize, dataSize.x(), dataSize.xy().product()}*Math::Vector3{_skip}, + size.product() ? dataSize : Math::Vector3{}, pixelSize); } #ifndef MAGNUM_TARGET_GLES -std::tuple, std::size_t> CompressedPixelStorage::dataProperties(const Vector3i& size) const { +std::tuple, Math::Vector3, std::size_t> 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; @@ -186,7 +186,7 @@ std::tuple, std::size_t> CompressedPixel std::size_t(blockCount.z())}; const Vector3i skipBlockCount = (_skip + _blockSize - Vector3i{1})/_blockSize; - const std::size_t offset = (Math::Vector3{1, dataSize.x(), dataSize.xy().product()}*Math::Vector3{skipBlockCount}).sum()*_blockDataSize; + 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); } diff --git a/src/Magnum/PixelStorage.h b/src/Magnum/PixelStorage.h index bd8b0420c..d0283d7e2 100644 --- a/src/Magnum/PixelStorage.h +++ b/src/Magnum/PixelStorage.h @@ -203,14 +203,14 @@ class MAGNUM_EXPORT PixelStorage { /** * @brief Data properties for given parameters * - * Returns byte offset, (row length, row count, layer count) and pixel - * size for image of given @p size with current pixel storage - * parameters, @p format and @p type. The offset reflects the @ref skip() - * parameter. Adding byte offset and product of the vector gives - * minimal byte count to store given data. + * Returns byte offset in each direction, (row length, row count, layer + * count) and pixel size for image of given @p size with current pixel + * storage parameters, @p format and @p type. The offset reflects the + * @ref skip() parameter. Adding byte offset and product of the vector + * gives minimal byte count to store given data. * @see @ref pixelSize() */ - std::tuple, std::size_t> dataProperties(PixelFormat format, PixelType type, const Vector3i& size) const; + std::tuple, Math::Vector3, std::size_t> dataProperties(PixelFormat format, PixelType type, const Vector3i& size) const; #ifndef DOXYGEN_GENERATING_OUTPUT protected: @@ -306,15 +306,16 @@ class MAGNUM_EXPORT CompressedPixelStorage: public PixelStorage { /** * @brief Data properties for given parameters * - * Returns byte offset, count of blocks in each dimension and block - * data size for image of given @p size with current pixel storage - * parameters. Adding byte offset and product of the vector multiplied - * with block data size gives minimal byte count to store given data. + * Returns byte offset in each dimension, count of blocks in each + * dimension and block data size for image of given @p size with + * current pixel storage parameters. Adding byte offset and product of + * the vector multiplied with block data size gives minimal byte count + * to store given data. * * Expects @ref compressedBlockSize() and @ref compressedBlockDataSize() * to be non-zero. */ - std::tuple, std::size_t> dataProperties(const Vector3i& size) const; + std::tuple, Math::Vector3, std::size_t> dataProperties(const Vector3i& size) const; /* Overloads to remove WTF-factor from method chaining order */ #ifndef DOXYGEN_GENERATING_OUTPUT @@ -369,37 +370,38 @@ constexpr PixelStorage::PixelStorage() noexcept: namespace Implementation { /* Used in *Image::dataProperties() */ - template std::tuple, std::size_t> imageDataProperties(const T& image) { - std::size_t offset; - Math::Vector3 dataSize; + template std::tuple, Math::Vector, std::size_t> imageDataProperties(const T& image) { + Math::Vector3 offset, dataSize; std::size_t pixelSize; std::tie(offset, dataSize, pixelSize) = image.storage().dataProperties(image.format(), image.type(), Vector3i::pad(image.size(), 1)); - return std::make_tuple(offset, Math::Vector::pad(dataSize), pixelSize); + return std::make_tuple(Math::Vector::pad(offset), Math::Vector::pad(dataSize), pixelSize); } #ifndef MAGNUM_TARGET_GLES2 /* Used in Compressed*Image::dataProperties() */ - template std::tuple, std::size_t> compressedImageDataProperties(const T& image) { - std::size_t offset; - Math::Vector3 blockCount; + template std::tuple, Math::Vector, std::size_t> 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(offset, Math::Vector::pad(blockCount), blockSize); + return std::make_tuple(Math::Vector::pad(offset), Math::Vector::pad(blockCount), blockSize); } #endif /* Used in image query functions */ template std::size_t imageDataSizeFor(const T& image, const Math::Vector& size) { - const auto paddedSize = Vector3i::pad(size, 1); - - std::size_t offset; - Math::Vector3 dataSize; + Math::Vector3 offset, dataSize; std::size_t pixelSize; - std::tie(offset, dataSize, pixelSize) = image.storage().dataProperties(image.format(), image.type(), paddedSize); - - /* I would subtract also (dataSize.x() - pixelSize*paddedSize.x()) but NVidia - then complains that the buffer is too small */ - return offset + dataSize.product() - (dataSize.y() - paddedSize.y())*dataSize.x(); + std::tie(offset, dataSize, pixelSize) = image.storage().dataProperties(image.format(), image.type(), Vector3i::pad(size, 1)); + + /* Smallest line/rectangle/cube that covers the area */ + std::size_t dataOffset = 0; + if(offset.z()) + dataOffset += offset.z(); + else if(offset.y()) + dataOffset += offset.y(); + else if(offset.x()) + dataOffset += offset.x(); + return dataOffset + dataSize.product(); } /* Used in data size assertions */ @@ -419,14 +421,13 @@ namespace Implementation { if(!image.storage().compressedBlockSize().product() || !image.storage().compressedBlockDataSize()) return {0, dataSize}; - std::size_t offset; - Math::Vector3 blockCount; + Math::Vector3 offset, blockCount; std::size_t blockDataSize; std::tie(offset, blockCount, blockDataSize) = 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, (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())*blockDataSize}; } /* Used in image query functions */ diff --git a/src/Magnum/Test/PixelStorageTest.cpp b/src/Magnum/Test/PixelStorageTest.cpp index af298516e..ba6e1c006 100644 --- a/src/Magnum/Test/PixelStorageTest.cpp +++ b/src/Magnum/Test/PixelStorageTest.cpp @@ -45,7 +45,9 @@ struct PixelStorageTest: TestSuite::Tester { void dataPropertiesImageHeight(); #endif - void dataSize(); + void dataSize1D(); + void dataSize2D(); + void dataSize3D(); #ifndef MAGNUM_TARGET_GLES void dataPropertiesCompressed(); @@ -70,7 +72,9 @@ PixelStorageTest::PixelStorageTest() { &PixelStorageTest::dataPropertiesImageHeight, #endif - &PixelStorageTest::dataSize, + &PixelStorageTest::dataSize1D, + &PixelStorageTest::dataSize2D, + &PixelStorageTest::dataSize3D, #ifndef MAGNUM_TARGET_GLES &PixelStorageTest::dataPropertiesCompressed, @@ -96,16 +100,16 @@ void PixelStorageTest::dataProperties() { storage.setAlignment(1); CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{0}), - (std::tuple{0, {0, 0, 0}, 4})); + (std::tuple{{}, {0, 0, 0}, 4})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{1}), - (std::tuple{0, {4, 1, 1}, 4})); + (std::tuple{{}, {4, 1, 1}, 4})); #if !defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2) CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {8, 2, 1}), - (std::tuple{0, {8, 2, 1}, 1})); + (std::tuple{{}, {8, 2, 1}, 1})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 1}), - (std::tuple{0, {2, 4, 1}, 1})); + (std::tuple{{}, {2, 4, 1}, 1})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 6}), - (std::tuple{0, {2, 4, 6}, 1})); + (std::tuple{{}, {2, 4, 6}, 1})); #endif } @@ -115,16 +119,16 @@ void PixelStorageTest::dataPropertiesAlignment() { .setSkip({3, 2, 1}); CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{0}), - (std::tuple{3*4, {0, 0, 0}, 4})); + (std::tuple{{3*4, 0, 0}, {0, 0, 0}, 4})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{1}), - (std::tuple{8 + 16 + 3*4, {8, 1, 1}, 4})); + (std::tuple{{12, 16, 8}, {8, 1, 1}, 4})); #if !defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2) CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {8, 2, 1}), - (std::tuple{16 + 16 + 3, {8, 2, 1}, 1})); + (std::tuple{{3, 16, 16}, {8, 2, 1}, 1})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 1}), - (std::tuple{32 + 16 + 3, {8, 4, 1}, 1})); + (std::tuple{{3, 16, 32}, {8, 4, 1}, 1})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 6}), - (std::tuple{32 + 16 + 3, {8, 4, 6}, 1})); + (std::tuple{{3, 16, 32}, {8, 4, 6}, 1})); #endif } @@ -136,15 +140,15 @@ void PixelStorageTest::dataPropertiesRowLength() { .setSkip({3, 7, 0}); CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{0}), - (std::tuple{3*4 + 7*15*4, {0, 0, 0}, 4})); + (std::tuple{{3*4, 7*15*4, 0}, {0, 0, 0}, 4})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{1}), - (std::tuple{3*4 + 7*15*4, {60, 1, 1}, 4})); + (std::tuple{{3*4, 7*15*4, 0}, {60, 1, 1}, 4})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {4, 2, 1}), - (std::tuple{3 + 7*16, {16, 2, 1}, 1})); + (std::tuple{{3, 7*16, 0}, {16, 2, 1}, 1})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 1}), - (std::tuple{3 + 7*16, {16, 4, 1}, 1})); + (std::tuple{{3, 7*16, 0}, {16, 4, 1}, 1})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 6}), - (std::tuple{3 + 7*16, {16, 4, 6}, 1})); + (std::tuple{{3, 7*16, 0}, {16, 4, 6}, 1})); } #endif @@ -156,39 +160,66 @@ void PixelStorageTest::dataPropertiesImageHeight() { .setSkip({3, 7, 2}); CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{0}), - (std::tuple{3*4, {0, 0, 0}, 4})); + (std::tuple{{3*4, 0, 0}, {0, 0, 0}, 4})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{1}), - (std::tuple{3*4 + 7*1*4 + 2*128*1*4, {4, 128, 1}, 4})); + (std::tuple{{3*4, 7*1*4, 2*128*1*4}, {4, 128, 1}, 4})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {4, 2, 1}), - (std::tuple{3 + 7*1*4 + 2*128*4, {4, 128, 1}, 1})); + (std::tuple{{3, 7*1*4, 2*128*4}, {4, 128, 1}, 1})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 1}), - (std::tuple{3 + 7*1*2 + 2*128*2, {2, 128, 1}, 1})); + (std::tuple{{3, 7*1*2, 2*128*2}, {2, 128, 1}, 1})); CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 6}), - (std::tuple{3 + 7*1*2 + 2*128*2, {2, 128, 6}, 1})); + (std::tuple{{3, 7*1*2, 2*128*2}, {2, 128, 6}, 1})); } #endif -void PixelStorageTest::dataSize() { +void PixelStorageTest::dataSize1D() { + const Image1D image{PixelStorage{}.setAlignment(2) + .setSkip({2, 0, 0}), + PixelFormat::RGB, PixelType::UnsignedByte}; + + CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Math::Vector<1, Int>{3}), + 16); +} + +void PixelStorageTest::dataSize2D() { /* The same parameters as in PixelStorageGLTest 3D case */ const Image2D image{PixelStorage{}.setAlignment(2) #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) - .setRowLength(3) + .setRowLength(7) + #endif + .setSkip({2, 3, 0}), + PixelFormat::RGB, PixelType::UnsignedByte}; + + #if defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2) + CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector2i{5, 9}), + (3 + 9)*15); + #else + CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector2i{5, 9}), + (3 + 9)*22); + #endif +} + +void PixelStorageTest::dataSize3D() { + /* The same parameters as in PixelStorageGLTest 3D case */ + const Image3D image{PixelStorage{}.setAlignment(2) + #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) + .setRowLength(7) #endif #ifndef MAGNUM_TARGET_GLES2 - .setImageHeight(5) + .setImageHeight(10) #endif .setSkip({2, 3, 1}), PixelFormat::RGB, PixelType::UnsignedByte}; #if defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2) - CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector2i{2, 3}), - 3*6 + 3*6 + 6 + 3*6); + CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector3i{5, 9, 3}), + (1 + 3)*9*15); #elif defined(MAGNUM_TARGET_GLES2) - CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector2i{2, 3}), - 3*10 + 3*10 + 6 + 3*10); + CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector3i{5, 9, 3}), + (1 + 3)*9*22); #else - CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector2i{2, 3}), - 5*10 + 3*10 + 6 + 3*10); + CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector3i{5, 9, 3}), + (1 + 3)*10*22); #endif } @@ -199,7 +230,7 @@ void PixelStorageTest::dataPropertiesCompressed() { .setCompressedBlockDataSize(16); CORRADE_COMPARE(storage.dataProperties({2, 8, 11}), - (std::tuple{0, {1, 2, 3}, 16})); + (std::tuple{{}, {1, 2, 3}, 16})); } void PixelStorageTest::dataPropertiesCompressedRowLength() { @@ -210,7 +241,7 @@ void PixelStorageTest::dataPropertiesCompressedRowLength() { .setSkip({5, 8, 0}); CORRADE_COMPARE(storage.dataProperties({2, 8, 11}), - (std::tuple{(2 + 8)*9, {4, 2, 3}, 9})); + (std::tuple{{2*9, 8*9, 0}, {4, 2, 3}, 9})); } void PixelStorageTest::dataPropertiesCompressedImageHeight() { @@ -221,7 +252,7 @@ void PixelStorageTest::dataPropertiesCompressedImageHeight() { .setSkip({5, 8, 11}); CORRADE_COMPARE(storage.dataProperties({2, 8, 11}), - (std::tuple{(2 + 2 + 9)*16, {1, 3, 3}, 16})); + (std::tuple{{2*16, 2*16, 9*16}, {1, 3, 3}, 16})); } void PixelStorageTest::dataOffsetSizeCompressed() { diff --git a/src/Magnum/Trade/ImageData.cpp b/src/Magnum/Trade/ImageData.cpp index e4d1f3a87..587685009 100644 --- a/src/Magnum/Trade/ImageData.cpp +++ b/src/Magnum/Trade/ImageData.cpp @@ -63,7 +63,7 @@ template std::size_t ImageData::pixelSize() return PixelStorage::pixelSize(_format, _type); } -template std::tuple, std::size_t> ImageData::dataProperties() const { +template std::tuple, VectorTypeFor, std::size_t> 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 2c6492aa0..28f53005c 100644 --- a/src/Magnum/Trade/ImageData.h +++ b/src/Magnum/Trade/ImageData.h @@ -210,7 +210,7 @@ template class ImageData { * @ref PixelStorage::dataProperties() for more information. * @see @ref isCompressed() */ - std::tuple, std::size_t> dataProperties() const; + std::tuple, VectorTypeFor, std::size_t> 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/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp index af9817c0f..6383105a4 100644 --- a/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp +++ b/src/MagnumPlugins/TgaImageConverter/TgaImageConverter.cpp @@ -98,7 +98,7 @@ Containers::Array TgaImageConverter::doExportToData(const ImageView2D& ima header->height = UnsignedShort(Utility::Endianness::littleEndian(image.size().y())); /* Image data pointer including skip */ - const char* imageData = image.data() + std::get<0>(image.dataProperties()); + const char* imageData = image.data() + std::get<0>(image.dataProperties()).sum(); /* Fill data or copy them row by row if we need to drop the padding */ const std::size_t rowSize = image.size().x()*pixelSize;