From 268b2f001470a9f30db6229f24bf7213dc1b07af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 30 Jun 2025 17:03:52 +0200 Subject: [PATCH] Improve tests for PixelStorage data size calculation. In case of compressed images the tests were absolutely insufficient, as they were always verifying just a single block, and thus they passed even though the actual calculation was wrong in several ways. And then the occupiedCompressedImageDataSize() wasn't tested at all, even though it should return something completely different from the function it delegates to. Fixes to both in the next commit. --- src/Magnum/GL/Test/CMakeLists.txt | 1 + src/Magnum/GL/Test/PixelStorageGLTest.cpp | 312 +++++++++++++----- src/Magnum/GL/Test/PixelStorageTest.cpp | 102 ++++++ src/Magnum/Test/PixelStorageTest.cpp | 381 +++++++++++++++++++++- 4 files changed, 700 insertions(+), 96 deletions(-) create mode 100644 src/Magnum/GL/Test/PixelStorageTest.cpp diff --git a/src/Magnum/GL/Test/CMakeLists.txt b/src/Magnum/GL/Test/CMakeLists.txt index 538d8fd04..7368c58a7 100644 --- a/src/Magnum/GL/Test/CMakeLists.txt +++ b/src/Magnum/GL/Test/CMakeLists.txt @@ -37,6 +37,7 @@ corrade_add_test(GLDefaultFramebufferTest DefaultFramebufferTest.cpp LIBRARIES M corrade_add_test(GLFramebufferTest FramebufferTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLMeshTest MeshTest.cpp LIBRARIES MagnumGLTestLib) corrade_add_test(GLPixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumGLTestLib) +corrade_add_test(GLPixelStorageTest PixelStorageTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLRendererTest RendererTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLRenderbufferTest RenderbufferTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLSamplerTest SamplerTest.cpp LIBRARIES MagnumGLTestLib) diff --git a/src/Magnum/GL/Test/PixelStorageGLTest.cpp b/src/Magnum/GL/Test/PixelStorageGLTest.cpp index 958f1f589..571bbbc9f 100644 --- a/src/Magnum/GL/Test/PixelStorageGLTest.cpp +++ b/src/Magnum/GL/Test/PixelStorageGLTest.cpp @@ -565,26 +565,44 @@ void PixelStorageGLTest::imageHeightSkipZPackNotSupported() { #endif #ifndef MAGNUM_TARGET_GLES -constexpr const UnsignedByte CompressedData2D[] = { - /* Skip */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 17, 17, 34, 34, 51, 51, 67, - 232, 57, 0, 0, 213, 255, 170, 2 +constexpr const UnsignedByte CompressedData2D[]{ + /* Skip rows (5 blocks) */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /* Image data row (2 blocks skipped, 2 data, 1 more for 5 total) */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /* Image data row (2 blocks skipped, 2 data, 1 more for 5 total) */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /* Image data row (2 blocks skipped, 2 data, 1 more for 5 total) */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -/* Just 4x4 0x00 - 0x3f compressed using RGBA DXT3 by the driver */ -constexpr const UnsignedByte ActualCompressedData[] = { - 0, 17, 17, 34, 34, 51, 51, 67, - 232, 57, 0, 0, 213, 255, 170, 2, +/* Just two different 16-byte RGBA DXT3 blocks mixed to form 6 blocks */ +constexpr UnsignedByte ActualCompressedData2D[]{ + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, }; void PixelStorageGLTest::compressedUnpack2D() { @@ -594,13 +612,13 @@ void PixelStorageGLTest::compressedUnpack2D() { CompressedPixelStorage storage; storage.setCompressedBlockSize({4, 4, 1}) .setCompressedBlockDataSize(16) - .setRowLength(12) - .setSkip({4, 4, 0}); + .setRowLength(20) + .setSkip({8, 4, 0}); - CompressedImageView2D image{storage, CompressedPixelFormat::RGBAS3tcDxt3, {4, 4}, CompressedData2D}; + CompressedImageView2D image{storage, CompressedPixelFormat::RGBAS3tcDxt3, {8, 12}, CompressedData2D}; Texture2D texture; - texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {4, 4}) + texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {8, 12}) .setCompressedSubImage(0, {}, image); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -610,7 +628,7 @@ void PixelStorageGLTest::compressedUnpack2D() { MAGNUM_VERIFY_NO_GL_ERROR(); CORRADE_COMPARE_AS(Containers::arrayCast(actual.data()), - Containers::arrayView(ActualCompressedData), + Containers::arrayView(ActualCompressedData2D), TestSuite::Compare::Container); } @@ -618,10 +636,10 @@ void PixelStorageGLTest::compressedPack2D() { if(!Context::current().isExtensionSupported()) CORRADE_SKIP(Extensions::ARB::compressed_texture_pixel_storage::string() << "is not supported."); - CompressedImageView2D actual{CompressedPixelFormat::RGBAS3tcDxt3, {4, 4}, ActualCompressedData}; + CompressedImageView2D actual{CompressedPixelFormat::RGBAS3tcDxt3, {8, 12}, ActualCompressedData2D}; Texture2D texture; - texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {4, 4}) + texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {8, 12}) .setCompressedSubImage(0, {}, actual); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -630,8 +648,8 @@ void PixelStorageGLTest::compressedPack2D() { CompressedImage2D image{CompressedPixelStorage{} .setCompressedBlockSize({4, 4, 1}) .setCompressedBlockDataSize(16) - .setRowLength(12) - .setSkip({4, 4, 0}), + .setRowLength(20) + .setSkip({8, 4, 0}), CompressedPixelFormat::RGBAS3tcDxt3, {}, Containers::Array{ValueInit, sizeof(CompressedData2D)}}; texture.compressedImage(0, image); @@ -643,54 +661,176 @@ void PixelStorageGLTest::compressedPack2D() { } constexpr const UnsignedByte CompressedData3D[] = { - /* Skip image */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - /* Skip rows and pixels */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 17, 17, 34, 34, 51, 51, 67, - 232, 57, 0, 0, 213, 255, 170, 2 + /* Skip first image (5x6 blocks) */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /* Skip second image (5x6 blocks) */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /* First image data slice (1 row skipped, 3 data, 2 more for 6 total), + each data row then 2 blocks skipped, 2 data, 1 more for 5 total */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /* Data */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /* Two more rows */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /* Second image data slice (1 row skipped, 3 data, 2 more for 6 total), + each data row then 2 blocks skipped, 2 data, 1 more for 5 total */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /* Two more rows */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +/* ActualCompressedData2D but repeated two times */ +constexpr UnsignedByte ActualCompressedData3D[]{ + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + + /* Second slice with the two different blocks swapped */ + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 68, 84, 85, 101, 102, 118, 119, 119, 239, 123, 8, 66, 213, 255, 170, 2, + 0, 17, 17, 34, 34, 51, 51, 67, 232, 57, 0, 0, 213, 255, 170, 2, }; void PixelStorageGLTest::compressedUnpack3D() { @@ -700,14 +840,14 @@ void PixelStorageGLTest::compressedUnpack3D() { CompressedPixelStorage storage; storage.setCompressedBlockSize({4, 4, 1}) .setCompressedBlockDataSize(16) - .setRowLength(8) - .setImageHeight(8) - .setSkip({4, 4, 4}); + .setRowLength(20) + .setImageHeight(24) + .setSkip({8, 4, 2}); - CompressedImageView3D image{storage, CompressedPixelFormat::RGBAS3tcDxt3, {4, 4, 1}, CompressedData3D}; + CompressedImageView3D image{storage, CompressedPixelFormat::RGBAS3tcDxt3, {8, 12, 2}, CompressedData3D}; Texture2DArray texture; - texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {4, 4, 1}) + texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {8, 12, 2}) .setCompressedSubImage(0, {}, image); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -717,7 +857,7 @@ void PixelStorageGLTest::compressedUnpack3D() { MAGNUM_VERIFY_NO_GL_ERROR(); CORRADE_COMPARE_AS(Containers::arrayCast(actual.data()), - Containers::arrayView(ActualCompressedData), + Containers::arrayView(ActualCompressedData3D), TestSuite::Compare::Container); } @@ -725,10 +865,10 @@ void PixelStorageGLTest::compressedPack3D() { if(!Context::current().isExtensionSupported()) CORRADE_SKIP(Extensions::ARB::compressed_texture_pixel_storage::string() << "is not supported."); - CompressedImageView3D actual{CompressedPixelFormat::RGBAS3tcDxt3, {4, 4, 1}, ActualCompressedData}; + CompressedImageView3D actual{CompressedPixelFormat::RGBAS3tcDxt3, {8, 12, 2}, ActualCompressedData3D}; Texture2DArray texture; - texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {4, 4, 1}) + texture.setStorage(1, TextureFormat::CompressedRGBAS3tcDxt3, {8, 12, 2}) .setCompressedSubImage(0, {}, actual); MAGNUM_VERIFY_NO_GL_ERROR(); @@ -737,9 +877,9 @@ void PixelStorageGLTest::compressedPack3D() { CompressedImage3D image{CompressedPixelStorage{} .setCompressedBlockSize({4, 4, 1}) .setCompressedBlockDataSize(16) - .setRowLength(8) - .setImageHeight(8) - .setSkip({4, 4, 4}), + .setRowLength(20) + .setImageHeight(24) + .setSkip({8, 4, 2}), CompressedPixelFormat::RGBAS3tcDxt3, {}, Containers::Array{ValueInit, sizeof(CompressedData3D)}}; texture.compressedImage(0, image); diff --git a/src/Magnum/GL/Test/PixelStorageTest.cpp b/src/Magnum/GL/Test/PixelStorageTest.cpp new file mode 100644 index 000000000..736bf20ad --- /dev/null +++ b/src/Magnum/GL/Test/PixelStorageTest.cpp @@ -0,0 +1,102 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include /** @todo drop once std::pair isn't used (i.e., the whole PixelStorage crap ceases to exist) */ + +#include "Magnum/ImageView.h" +#include "Magnum/PixelFormat.h" +#include "Magnum/GL/Implementation/imageProperties.h" + +namespace Magnum { namespace GL { namespace Test { namespace { + +struct PixelStorageTest: TestSuite::Tester { + explicit PixelStorageTest(); + + void occupiedCompressedImageDataSize(); +}; + +PixelStorageTest::PixelStorageTest() { + addTests({&PixelStorageTest::occupiedCompressedImageDataSize}); +} + +void PixelStorageTest::occupiedCompressedImageDataSize() { + /* Assuming a custom 5x4x2 format with 16-byte blocks, with the whole image + being 55x28x12 */ + const char data[(55/5)*(28/4)*(12/2)*16]{}; + + /* If we have no block properties, the passed data size is taken, assuming + it's the best bet. Image size or row length and image height isn't taken + into account in any way. */ + { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setRowLength(55) + .setImageHeight(28) + .setSkip({10, 8, 4}), + 42069, /* custom format */ + {35, 20, 6}, + data}; + CORRADE_COMPARE(Implementation::occupiedCompressedImageDataSize(image, 1337), 1337); + + /* If we have block properties, the size is calculated from those and the + *image* size, not the supplied row length / image height. This is what + GL wants, it has no relation to anything useful. For comparison see the PixelStorageTest::dataOffsetSizeCompressed() test in the core + library. */ + } { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16) + .setRowLength(55) + .setImageHeight(28) + .setSkip({10, 8, 4}), + 42069, /* custom format */ + {35, 20, 6}, + data}; + CORRADE_COMPARE(Implementation::occupiedCompressedImageDataSize(image, 1337), + (35/5)*(20/4)*(6/2)*16); + + /* Same result if the size isn't whole blocks */ + } { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16) + .setRowLength(55) + .setImageHeight(28) + .setSkip({10, 8, 4}), + 42069, /* custom format */ + {31, 19, 5}, + data}; + CORRADE_COMPARE(Implementation::occupiedCompressedImageDataSize(image, 1337), + (35/5)*(20/4)*(6/2)*16); + } +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::GL::Test::PixelStorageTest) diff --git a/src/Magnum/Test/PixelStorageTest.cpp b/src/Magnum/Test/PixelStorageTest.cpp index dedcb11bc..8a099581f 100644 --- a/src/Magnum/Test/PixelStorageTest.cpp +++ b/src/Magnum/Test/PixelStorageTest.cpp @@ -25,9 +25,11 @@ */ #include +#include #include /** @todo drop once std::pair isn't used (i.e., the whole PixelStorage crap ceases to exist) */ #include "Magnum/Image.h" +#include "Magnum/ImageView.h" #include "Magnum/PixelFormat.h" #include "Magnum/PixelStorage.h" #include "Magnum/Implementation/ImageProperties.h" @@ -48,12 +50,16 @@ struct PixelStorageTest: TestSuite::Tester { void dataSize1D(); void dataSize2D(); void dataSize3D(); + void dataSizeZeroSize(); void dataPropertiesCompressed(); void dataPropertiesCompressedRowLength(); void dataPropertiesCompressedImageHeight(); - void dataOffsetSizeCompressed(); + void dataOffsetSizeCompressed1D(); + void dataOffsetSizeCompressed2D(); + void dataOffsetSizeCompressed3D(); + void dataOffsetSizeCompressedZeroSize(); }; typedef Math::Vector3 Vector3st; @@ -70,12 +76,16 @@ PixelStorageTest::PixelStorageTest() { &PixelStorageTest::dataSize1D, &PixelStorageTest::dataSize2D, &PixelStorageTest::dataSize3D, + &PixelStorageTest::dataSizeZeroSize, &PixelStorageTest::dataPropertiesCompressed, &PixelStorageTest::dataPropertiesCompressedRowLength, &PixelStorageTest::dataPropertiesCompressedImageHeight, - &PixelStorageTest::dataOffsetSizeCompressed}); + &PixelStorageTest::dataOffsetSizeCompressed1D, + &PixelStorageTest::dataOffsetSizeCompressed2D, + &PixelStorageTest::dataOffsetSizeCompressed3D, + &PixelStorageTest::dataOffsetSizeCompressedZeroSize}); } void PixelStorageTest::compare() { @@ -246,6 +256,13 @@ void PixelStorageTest::dataSize3D() { CORRADE_COMPARE(Implementation::imageDataSizeFor(image3, Vector3i{64, 64, 64}), 8388608); } +void PixelStorageTest::dataSizeZeroSize() { + const Image3D image{PixelFormat::RGBA8Unorm}; + CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector3i{0, 64, 64}), 0); + CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector3i{64, 0, 64}), 0); + CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector3i{64, 64, 0}), 0); +} + void PixelStorageTest::dataPropertiesCompressed() { CompressedPixelStorage storage; storage.setCompressedBlockSize({3, 4, 5}) @@ -277,16 +294,360 @@ void PixelStorageTest::dataPropertiesCompressedImageHeight() { (std::pair{{2*16, 2*16, 9*16}, {1, 3, 3}})); } -void PixelStorageTest::dataOffsetSizeCompressed() { - /* The same parameters as in PixelStorageGLTest 3D case */ +void PixelStorageTest::dataOffsetSizeCompressed1D() { + /* Assuming a custom 5-pixel block format with 8-byte blocks, with the + whole image being 45 pixels wide */ + const char data[(45/5)*8]{}; + + /* Image size in whole blocks, no skip */ + { + CompressedImageView1D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 1, 1}) + .setCompressedBlockDataSize(8), + 42069, /* custom format */ + 1, /* this is ignored, the passed size is used instead */ + data}; + CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, (Math::Vector<1, Int>{55})), (std::pair{ + 0, + (55/5)*8})); + + /* Skip */ + } { + CompressedImageView1D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 1, 1}) + .setCompressedBlockDataSize(8) + .setSkip({10, 0, 0}), + 42069, + 1, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Math::Vector<1, Int>{35}); + /* The total size shouldn't overflow the 45 block line */ + CORRADE_COMPARE(out.first + out.second, (45/5)*8); + /* The size should be an exact amount of blocks */ + CORRADE_COMPARE_AS(out.second, 8, TestSuite::Compare::Divisible); + /* Check the exact values */ + CORRADE_COMPARE(out, (std::pair{ + (10/5)*8, + (35/5)*8})); + + /* Row length not whole blocks, should result in the same */ + } { + CompressedImageView1D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 1, 1}) + .setCompressedBlockDataSize(8) + .setSkip({10, 0, 0}), + 42069, + 1, + data}; + CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, (Math::Vector<1, Int>{35})), (std::pair{ + (10/5)*8, + (35/5)*8})); + } +} + +void PixelStorageTest::dataOffsetSizeCompressed2D() { + /* Assuming a custom 5x4 format with 8-byte blocks, with the whole image + being 45x28x12 */ + const char data[(45/5)*(28/4)*8]{}; + + /* Image size in whole blocks, no skip */ + { + CompressedImageView2D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 1}) + .setCompressedBlockDataSize(8), + 42069, /* custom format */ + {1, 1}, /* this is ignored, the passed size is used instead */ + data}; + CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, Vector2i{55, 28}), (std::pair{ + 0, + (55/5)*(28/4)*8})); + + /* Skip just blocks, explicitly supplied row length */ + } { + CompressedImageView2D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 1}) + .setCompressedBlockDataSize(8) + .setRowLength(45) + .setSkip({10, 0, 0}), + 42069, + {1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector2i{35, 20}); + /* The total size shouldn't overflow the 45x20 block rectangle */ + CORRADE_COMPARE(out.first + out.second, (45/5)*(20/4)*8); + /* The size should be an exact amount of row blocks */ + CORRADE_COMPARE_AS(out.second, (45/5)*8, TestSuite::Compare::Divisible); + /* Check the exact values. In this case there's no offset as the + rectangle starts right away. */ + CORRADE_COMPARE(out, (std::pair{ + 0, + (45/5)*(20/4)*8})); + + /* Skip just rows */ + } { + CompressedImageView2D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 1}) + .setCompressedBlockDataSize(8) + .setSkip({0, 8, 0}), + 42069, + {1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector2i{35, 20}); + /* The total size shouldn't overflow the 35x28 block rectangle */ + CORRADE_COMPARE(out.first + out.second, (35/5)*(28/4)*8); + /* The size should be an exact amount of row blocks */ + CORRADE_COMPARE_AS(out.second, (35/5)*8, TestSuite::Compare::Divisible); + /* Check the exact values */ + CORRADE_COMPARE(out, (std::pair{ + (35/5)*(8/4)*8, + (35/5)*(20/4)*8})); + + /* Skip just rows, explicitly supplied row length */ + } { + CompressedImageView2D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 1}) + .setCompressedBlockDataSize(8) + .setRowLength(45) + .setSkip({0, 8, 0}), + 42069, + {1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector2i{35, 20}); + /* The total size shouldn't overflow the 45x28 block rectangle */ + CORRADE_COMPARE(out.first + out.second, (45/5)*(28/4)*8); + /* The size should be an exact amount of row blocks */ + CORRADE_COMPARE_AS(out.second, (45/5)*8, TestSuite::Compare::Divisible); + /* Check the exact values */ + CORRADE_COMPARE(out, (std::pair{ + (45/5)*(8/4)*8, + (45/5)*(20/4)*8})); + + /* Skip blocks and rows, explicitly supplied row length */ + } { + CompressedImageView2D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 1}) + .setCompressedBlockDataSize(8) + .setRowLength(45) + .setSkip({10, 8, 0}), + 42069, + {1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector2i{35, 20}); + /* The total size shouldn't overflow the 45x28 block rectangle */ + CORRADE_COMPARE(out.first + out.second, (45/5)*(28/4)*8); + /* The size should be an exact amount of row blocks */ + CORRADE_COMPARE_AS(out.second, (45/5)*8, TestSuite::Compare::Divisible); + /* Check the exact values */ + CORRADE_COMPARE(out, (std::pair{ + (8/4)*(45/5)*8, + (45/5)*(20/4)*8})); + + /* Row length not whole blocks, should result in the same */ + } { + CompressedImageView2D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 1}) + .setCompressedBlockDataSize(8) + .setRowLength(41) + .setSkip({10, 8, 0}), + 42069, + {1, 1}, + data}; + CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, Vector2i{35, 20}), (std::pair{ + (8/4)*(45/5)*8, + (45/5)*(20/4)*8})); + } +} + +void PixelStorageTest::dataOffsetSizeCompressed3D() { + /* Assuming a custom 5x4x2 format with 16-byte blocks, with the whole image + being 45x28x10 */ + const char data[(45/5)*(28/4)*(10/2)*16]{}; + + /* Image size in whole blocks, no offset */ + { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16), + 42069, /* custom format */ + {1, 1, 1}, /* this is ignored, the passed size is used instead */ + data}; + CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{45, 28, 6}), (std::pair{ + 0, + (45/5)*(28/4)*(6/2)*16})); + + /* Skip just blocks, explicitly supplied row length */ + } { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16) + .setRowLength(45) + .setSkip({10, 0, 0}), + 42069, + {1, 1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{35, 20, 6}); + /* The total size shouldn't overflow the 45x20x6 cube */ + CORRADE_COMPARE(out.first + out.second, (45/5)*(20/4)*(6/2)*16); + /* The size should be an exact amount of slice blocks */ + CORRADE_COMPARE_AS(out.second, (45/5)*(20/4)*16, TestSuite::Compare::Divisible); + /* Check the exact values. In this case there's no offset as the cube + starts right away. */ + CORRADE_COMPARE(out, (std::pair{ + 0, + (45/5)*(20/4)*(6/2)*16})); + + /* Skip just blocks, explicitly supplied row length and image height */ + } { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16) + .setRowLength(45) + .setImageHeight(28) + .setSkip({20, 0, 0}), + 42069, + {1, 1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{35, 20, 6}); + /* The total size shouldn't overflow the 45x28x6 cube */ + CORRADE_COMPARE(out.first + out.second, (45/5)*(28/4)*(6/2)*16); + /* The size should be an exact amount of slice blocks */ + CORRADE_COMPARE_AS(out.second, (45/5)*(28/4)*16, TestSuite::Compare::Divisible); + /* Check the exact values. In this case there's no offset as the cube + starts right away. */ + CORRADE_COMPARE(out, (std::pair{ + 0, + (45/5)*(28/4)*(6/2)*16})); + + /* Skip just rows, explicitly supplied image height */ + } { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16) + .setImageHeight(28) + .setSkip({0, 8, 0}), + 42069, + {1, 1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{35, 20, 6}); + /* The total size shouldn't overflow the 35x28x6 cube */ + CORRADE_COMPARE(out.first + out.second, (35/5)*(28/4)*(6/2)*16); + /* The size should be an exact amount of slice blocks */ + CORRADE_COMPARE_AS(out.second, (35/5)*(28/4)*16, TestSuite::Compare::Divisible); + /* Check the exact values. In this case there's no offset either as the + cube again starts right away. */ + CORRADE_COMPARE(out, (std::pair{ + 0, + (35/5)*(28/4)*(6/2)*16})); + + /* Skip just rows, explicitly supplied row length and image height */ + } { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16) + .setRowLength(45) + .setImageHeight(28) + .setSkip({0, 8, 0}), + 42069, + {1, 1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{35, 20, 6}); + /* The total size shouldn't overflow the 45x28x6 cube */ + CORRADE_COMPARE(out.first + out.second, (45/5)*(28/4)*(6/2)*16); + /* The size should be an exact amount of slice blocks */ + CORRADE_COMPARE_AS(out.second, (45/5)*(28/4)*16, TestSuite::Compare::Divisible); + /* Check the exact values. In this case there's no offset either as the + cube again starts right away. */ + CORRADE_COMPARE(out, (std::pair{ + 0, + (45/5)*(28/4)*(6/2)*16})); + + /* Skip just slices, explicitly supplied row length and image height */ + } { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16) + .setRowLength(45) + .setImageHeight(28) + .setSkip({0, 0, 4}), + 42069, + {1, 1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{35, 20, 6}); + /* The total size shouldn't overflow the 45x28x10 cube */ + CORRADE_COMPARE(out.first + out.second, (45/5)*(28/4)*(10/2)*16); + /* The size should be an exact amount of slice blocks */ + CORRADE_COMPARE_AS(out.second, (45/5)*(28/4)*16, TestSuite::Compare::Divisible); + /* Check the exact values */ + CORRADE_COMPARE(out, (std::pair{ + (45/5)*(28/4)*(4/2)*16, + (45/5)*(28/4)*(6/2)*16})); + + /* Skip all, explicitly supplied row length and image height */ + } { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16) + .setRowLength(45) + .setImageHeight(28) + .setSkip({10, 8, 4}), + 42069, + {1, 1, 1}, + data}; + std::pair out = Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{35, 20, 6}); + /* The total size shouldn't overflow the 45x28x10 cube */ + CORRADE_COMPARE(out.first + out.second, (45/5)*(28/4)*(10/2)*16); + /* The size should be an exact amount of slice blocks */ + CORRADE_COMPARE_AS(out.second, (45/5)*(28/4)*16, TestSuite::Compare::Divisible); + /* Check the exact values */ + CORRADE_COMPARE(out, (std::pair{ + (45/5)*(28/4)*(4/2)*16, + (45/5)*(28/4)*(6/2)*16})); + + /* Row length and image height not whole blocks, should result in the + same */ + } { + CompressedImageView3D image{ + CompressedPixelStorage{} + .setCompressedBlockSize({5, 4, 2}) + .setCompressedBlockDataSize(16) + .setRowLength(41) + .setImageHeight(27) + .setSkip({10, 8, 4}), + 42069, + {1, 1, 1}, + data}; + CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{35, 20, 6}), (std::pair{ + (45/5)*(28/4)*(4/2)*16, + (45/5)*(28/4)*(6/2)*16})); + } +} + +void PixelStorageTest::dataOffsetSizeCompressedZeroSize() { const CompressedImage3D image{CompressedPixelStorage{} .setCompressedBlockSize({4, 4, 1}) - .setCompressedBlockDataSize(16) - .setRowLength(8) - .setImageHeight(8) - .setSkip({4, 4, 4})}; - CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{4, 4, 1}), - (std::pair{16*4*4 + 16*2 + 16, 16})); + .setCompressedBlockDataSize(16)}; + CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{0, 4, 4}), + (std::pair{})); + CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{4, 0, 4}), + (std::pair{})); + CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{4, 4, 0}), + (std::pair{})); } }}}