Browse Source

Split the OpenGL layer out, pt 10: test the new image APIs.

With the previous commits the original tests passed (which is
desired), but these were using deprecated functionality and not
covering the new stuff. These tests are not using the deprecated
functionality, which means I don't need to build them as part of
the GL library anymore.

The GL::BufferImage test is still using the deprecated
functionality though, in order to check I didn't break anything
by accident.
pull/233/head
Vladimír Vondruš 8 years ago
parent
commit
8fa9b89882
  1. 4
      src/Magnum/CMakeLists.txt
  2. 6
      src/Magnum/GL/BufferImage.cpp
  3. 4
      src/Magnum/GL/CMakeLists.txt
  4. 223
      src/Magnum/GL/Test/BufferImageGLTest.cpp
  5. 8
      src/Magnum/GL/Test/CMakeLists.txt
  6. 2
      src/Magnum/Image.cpp
  7. 4
      src/Magnum/ImageView.cpp
  8. 6
      src/Magnum/Test/CMakeLists.txt
  9. 576
      src/Magnum/Test/ImageTest.cpp
  10. 515
      src/Magnum/Test/ImageViewTest.cpp
  11. 222
      src/Magnum/Test/PixelStorageTest.cpp
  12. 53
      src/Magnum/Trade/CMakeLists.txt
  13. 2
      src/Magnum/Trade/ImageData.cpp
  14. 2
      src/Magnum/Trade/Test/CMakeLists.txt
  15. 476
      src/Magnum/Trade/Test/ImageDataTest.cpp
  16. 2
      src/Magnum/Trade/visibility.h
  17. 2
      src/Magnum/visibility.h

4
src/Magnum/CMakeLists.txt

@ -28,13 +28,13 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake
# Files shared between main library and unit test library
set(Magnum_SRCS
Image.cpp
ImageView.cpp
PixelStorage.cpp
Resource.cpp
Timeline.cpp)
set(Magnum_GracefulAssert_SRCS
Image.cpp
ImageView.cpp
PixelFormat.cpp)
set(Magnum_HEADERS

6
src/Magnum/GL/BufferImage.cpp

@ -37,7 +37,7 @@ template<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(const Pixe
template<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(const PixelStorage storage, const Magnum::PixelFormat format, const VectorTypeFor<dimensions, Int>& size, Containers::ArrayView<const void> const data, const BufferUsage usage): BufferImage{storage, GL::pixelFormat(format), GL::pixelType(format), size, data, usage} {}
template<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(const PixelStorage storage, const PixelFormat format, const PixelType type, const VectorTypeFor<dimensions, Int>& size, Buffer&& buffer, const std::size_t dataSize) noexcept: _storage{storage}, _format{format}, _type{type}, _size{size}, _buffer{std::move(buffer)}, _dataSize{dataSize} {
CORRADE_ASSERT(Magnum::Implementation::imageDataSize(*this) <= dataSize, "GL::BufferImage::BufferImage(): bad image data size, got" << dataSize << "but expected at least" << Magnum::Implementation::imageDataSize(*this), );
CORRADE_ASSERT(Magnum::Implementation::imageDataSize(*this) <= dataSize, "GL::BufferImage::BufferImage(): data too small, got" << dataSize << "but expected at least" << Magnum::Implementation::imageDataSize(*this) << "bytes", );
}
template<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(const PixelStorage storage, const Magnum::PixelFormat format, const VectorTypeFor<dimensions, Int>& size, Buffer&& buffer, const std::size_t dataSize) noexcept: BufferImage{storage, GL::pixelFormat(format), GL::pixelType(format), size, std::move(buffer), dataSize} {}
@ -58,9 +58,9 @@ template<UnsignedInt dimensions> void BufferImage<dimensions>::setData(const Pix
/* Keep the old storage if zero-sized nullptr buffer was passed */
if(data.data() == nullptr && data.size() == 0)
CORRADE_ASSERT(Magnum::Implementation::imageDataSize(*this) <= _dataSize, "GL::BufferImage::setData(): bad current storage size, got" << _dataSize << "but expected at least" << Magnum::Implementation::imageDataSize(*this), );
CORRADE_ASSERT(Magnum::Implementation::imageDataSize(*this) <= _dataSize, "GL::BufferImage::setData(): current storage too small, got" << _dataSize << "but expected at least" << Magnum::Implementation::imageDataSize(*this) << "bytes", );
else {
CORRADE_ASSERT(Magnum::Implementation::imageDataSize(*this) <= data.size(), "GL::BufferImage::setData(): bad image data size, got" << data.size() << "but expected at least" << Magnum::Implementation::imageDataSize(*this), );
CORRADE_ASSERT(Magnum::Implementation::imageDataSize(*this) <= data.size(), "GL::BufferImage::setData(): data too small, got" << data.size() << "but expected at least" << Magnum::Implementation::imageDataSize(*this) << "bytes", );
_buffer.setData(data, usage);
_dataSize = data.size();
}

4
src/Magnum/GL/CMakeLists.txt

@ -109,13 +109,15 @@ endif()
# OpenGL ES 3.0 and WebGL 2.0 stuff
if(NOT TARGET_GLES2)
list(APPEND MagnumGL_SRCS
BufferImage.cpp
PrimitiveQuery.cpp
TextureArray.cpp
TransformFeedback.cpp
Implementation/TransformFeedbackState.cpp)
list(APPEND MagnumGL_GracefulAssert_SRCS
BufferImage.cpp)
list(APPEND MagnumGL_HEADERS
BufferImage.h
PrimitiveQuery.h

223
src/Magnum/GL/Test/BufferImageGLTest.cpp

@ -23,6 +23,7 @@
DEALINGS IN THE SOFTWARE.
*/
#include <sstream>
#include <Corrade/Containers/Array.h>
#include <Corrade/TestSuite/Compare/Container.h>
@ -36,16 +37,26 @@ struct BufferImageGLTest: OpenGLTester {
explicit BufferImageGLTest();
void construct();
void constructGeneric();
void constructCompressed();
void constructCompressedGeneric();
void constructBuffer();
void constructBufferGeneric();
void constructBufferCompressed();
void constructBufferCompressedGeneric();
void constructInvalidSize();
void constructCompressedInvalidSize();
void constructCopy();
void constructCopyCompressed();
void constructMove();
void constructMoveCompressed();
void setData();
void setDataGeneric();
void setDataCompressed();
void setDataCompressedGeneric();
void release();
void releaseCompressed();
@ -53,16 +64,26 @@ struct BufferImageGLTest: OpenGLTester {
BufferImageGLTest::BufferImageGLTest() {
addTests({&BufferImageGLTest::construct,
&BufferImageGLTest::constructGeneric,
&BufferImageGLTest::constructCompressed,
&BufferImageGLTest::constructCompressedGeneric,
&BufferImageGLTest::constructBuffer,
&BufferImageGLTest::constructBufferGeneric,
&BufferImageGLTest::constructBufferCompressed,
&BufferImageGLTest::constructBufferCompressedGeneric,
&BufferImageGLTest::constructInvalidSize,
&BufferImageGLTest::constructCompressedInvalidSize,
&BufferImageGLTest::constructCopy,
&BufferImageGLTest::constructCopyCompressed,
&BufferImageGLTest::constructMove,
&BufferImageGLTest::constructMoveCompressed,
&BufferImageGLTest::setData,
&BufferImageGLTest::setDataGeneric,
&BufferImageGLTest::setDataCompressed,
&BufferImageGLTest::setDataCompressedGeneric,
&BufferImageGLTest::release,
&BufferImageGLTest::releaseCompressed});
@ -91,6 +112,29 @@ void BufferImageGLTest::construct() {
#endif
}
void BufferImageGLTest::constructGeneric() {
const char data[] = { 'a', 'b', 'c' };
BufferImage2D a{PixelStorage{}.setAlignment(1),
Magnum::PixelFormat::R8Unorm, {1, 3}, data, BufferUsage::StaticDraw};
#ifndef MAGNUM_TARGET_GLES
const auto imageData = a.buffer().data();
#endif
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), GL::PixelFormat::Red);
CORRADE_COMPARE(a.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
/** @todo How to verify the contents in ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(imageData, Containers::arrayView(data),
TestSuite::Compare::Container);
#endif
}
void BufferImageGLTest::constructCompressed() {
const char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0 };
CompressedBufferImage2D a{
@ -120,6 +164,35 @@ void BufferImageGLTest::constructCompressed() {
#endif
}
void BufferImageGLTest::constructCompressedGeneric() {
const char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0 };
CompressedBufferImage2D a{
#ifndef MAGNUM_TARGET_GLES
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
Magnum::CompressedPixelFormat::Bc1RGBAUnorm,
{4, 4}, data, BufferUsage::StaticDraw};
#ifndef MAGNUM_TARGET_GLES
const auto imageData = a.buffer().data();
#endif
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_COMPARE(a.format(), GL::CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(a.size(), Vector2i(4, 4));
CORRADE_COMPARE(a.dataSize(), 8);
/** @todo How to verify the contents in ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(imageData, Containers::arrayView(data),
TestSuite::Compare::Container);
#endif
}
void BufferImageGLTest::constructBuffer() {
const char data[] = { 'a', 'b', 'c' };
Buffer buffer;
@ -149,6 +222,35 @@ void BufferImageGLTest::constructBuffer() {
#endif
}
void BufferImageGLTest::constructBufferGeneric() {
const char data[] = { 'a', 'b', 'c' };
Buffer buffer;
buffer.setData(data, BufferUsage::StaticDraw);
const UnsignedInt id = buffer.id();
BufferImage2D a{PixelStorage{}.setAlignment(1),
Magnum::PixelFormat::R8Unorm, {1, 3}, std::move(buffer), sizeof(data)};
#ifndef MAGNUM_TARGET_GLES
const auto imageData = a.buffer().data();
#endif
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(!buffer.id());
CORRADE_COMPARE(a.buffer().id(), id);
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), GL::PixelFormat::Red);
CORRADE_COMPARE(a.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
/** @todo How to verify the contents in ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(imageData, Containers::arrayView(data),
TestSuite::Compare::Container);
#endif
}
void BufferImageGLTest::constructBufferCompressed() {
const char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0 };
Buffer buffer;
@ -184,6 +286,69 @@ void BufferImageGLTest::constructBufferCompressed() {
#endif
}
void BufferImageGLTest::constructBufferCompressedGeneric() {
const char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0 };
Buffer buffer;
buffer.setData(data, BufferUsage::StaticDraw);
const UnsignedInt id = buffer.id();
CompressedBufferImage2D a{
#ifndef MAGNUM_TARGET_GLES
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
Magnum::CompressedPixelFormat::Bc1RGBAUnorm,
{4, 4}, std::move(buffer), sizeof(data)};
#ifndef MAGNUM_TARGET_GLES
const auto imageData = a.buffer().data();
#endif
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_VERIFY(!buffer.id());
CORRADE_COMPARE(a.buffer().id(), id);
CORRADE_COMPARE(a.format(), GL::CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(a.size(), Vector2i(4, 4));
CORRADE_COMPARE(a.dataSize(), 8);
/** @todo How to verify the contents in ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(imageData, Containers::arrayView(data),
TestSuite::Compare::Container);
#endif
}
void BufferImageGLTest::constructInvalidSize() {
std::ostringstream out;
Error redirectError{&out};
/* Doesn't consider alignment */
BufferImage2D{PixelFormat::RGB8Unorm, {1, 3}, Containers::Array<char>{3*3}, BufferUsage::StaticDraw};
CORRADE_COMPARE(out.str(), "GL::BufferImage::BufferImage(): data too small, got 9 but expected at least 12 bytes\n");
}
void BufferImageGLTest::constructCompressedInvalidSize() {
CORRADE_EXPECT_FAIL("Size checking for compressed image data is not implemented yet.");
/* Too small for given format */
{
std::ostringstream out;
Error redirectError{&out};
CompressedBufferImage2D{CompressedPixelFormat::Bc2RGBAUnorm, {4, 4}, Containers::Array<char>{2}, BufferUsage::StaticDraw};
CORRADE_COMPARE(out.str(), "GL::CompressedBufferImage::CompressedBufferImage(): data too small, got 2 but expected at least 4 bytes\n");
/* Size should be rounded up even if the image size is not full block */
} {
std::ostringstream out;
Error redirectError{&out};
CompressedBufferImage2D{CompressedPixelFormat::Bc2RGBAUnorm, {2, 2}, Containers::Array<char>{2}, BufferUsage::StaticDraw};
CORRADE_COMPARE(out.str(), "GL::CompressedBufferImage::CompressedBufferImage(): data too small, got 2 but expected at least 4 bytes\n");
}
}
void BufferImageGLTest::constructCopy() {
CORRADE_VERIFY(!(std::is_constructible<BufferImage2D, const BufferImage2D&>{}));
CORRADE_VERIFY(!(std::is_assignable<BufferImage2D, const BufferImage2D&>{}));
@ -306,6 +471,33 @@ void BufferImageGLTest::setData() {
#endif
}
void BufferImageGLTest::setDataGeneric() {
const char data[4] = { 'a', 'b', 'c', 'd' };
BufferImage2D a{PixelStorage{}.setAlignment(1),
PixelFormat::Red, PixelType::UnsignedByte, {4, 1}, data, BufferUsage::StaticDraw};
const UnsignedShort data2[2*4] = { 1, 2, 3, 4, 5, 6, 7, 8 };
a.setData(Magnum::PixelFormat::RGBA16Unorm, {1, 2}, data2, BufferUsage::StaticDraw);
#ifndef MAGNUM_TARGET_GLES
const auto imageData = a.buffer().data();
#endif
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), GL::PixelFormat::RGBA);
CORRADE_COMPARE(a.type(), PixelType::UnsignedShort);
CORRADE_COMPARE(a.size(), Vector2i(1, 2));
/** @todo How to verify the contents in ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(Containers::arrayCast<UnsignedShort>(imageData),
Containers::arrayView(data2),
TestSuite::Compare::Container);
#endif
}
void BufferImageGLTest::setDataCompressed() {
const char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0 };
CompressedBufferImage2D a{CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, data, BufferUsage::StaticDraw};
@ -337,6 +529,37 @@ void BufferImageGLTest::setDataCompressed() {
#endif
}
void BufferImageGLTest::setDataCompressedGeneric() {
const char data[] = { 'a', 0, 0, 0, 'b', 0, 0, 0 };
CompressedBufferImage2D a{CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, data, BufferUsage::StaticDraw};
const char data2[] = { 'a', 0, 0, 0, 'b', 0, 0, 0, 'c', 0, 0, 0, 'd', 0, 0, 0 };
a.setData(
#ifndef MAGNUM_TARGET_GLES
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
Magnum::CompressedPixelFormat::Bc2RGBAUnorm, {8, 4}, data2, BufferUsage::StaticDraw);
#ifndef MAGNUM_TARGET_GLES
const auto imageData = a.buffer().data();
#endif
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_COMPARE(a.format(), GL::CompressedPixelFormat::RGBAS3tcDxt3);
CORRADE_COMPARE(a.size(), Vector2i(8, 4));
CORRADE_COMPARE(a.dataSize(), 16);
/** @todo How to verify the contents in ES? */
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE_AS(imageData, Containers::arrayView(data2),
TestSuite::Compare::Container);
#endif
}
void BufferImageGLTest::release() {
BufferImage2D a{PixelFormat::RGBA, PixelType::UnsignedByte};
const UnsignedInt id = a.buffer().id();

8
src/Magnum/GL/Test/CMakeLists.txt

@ -30,11 +30,8 @@ corrade_add_test(GLContextTest ContextTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLCubeMapTextureTest CubeMapTextureTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLDefaultFramebufferTest DefaultFramebufferTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLFramebufferTest FramebufferTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLImageTest ../../Test/ImageTest.cpp LIBRARIES MagnumGL) # temporary
corrade_add_test(GLImageViewTest ../../Test/ImageViewTest.cpp LIBRARIES MagnumGL) # temporary
corrade_add_test(GLMeshTest MeshTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLPixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumGLTestLib)
corrade_add_test(GLPixelStorageTest ../../Test/PixelStorageTest.cpp LIBRARIES MagnumGL) # temporary
corrade_add_test(GLRendererTest RendererTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLRenderbufferTest RenderbufferTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLSamplerTest SamplerTest.cpp LIBRARIES MagnumGL)
@ -50,10 +47,7 @@ set_target_properties(
GLCubeMapTextureTest
GLDefaultFramebufferTest
GLFramebufferTest
GLImageTest
GLImageViewTest
GLMeshTest
GLPixelStorageTest
GLPixelFormatTest
GLRendererTest
GLRenderbufferTest
@ -179,7 +173,7 @@ if(BUILD_GL_TESTS)
endif()
if(NOT MAGNUM_TARGET_GLES2)
corrade_add_test(GLBufferImageGLTest BufferImageGLTest.cpp LIBRARIES MagnumOpenGLTester)
corrade_add_test(GLBufferImageGLTest BufferImageGLTest.cpp LIBRARIES MagnumGLTestLib MagnumOpenGLTester)
corrade_add_test(GLBufferTextureGLTest BufferTextureGLTest.cpp LIBRARIES MagnumOpenGLTester)
corrade_add_test(GLCubeMapTextureArrayGLTest CubeMapTextureArrayGLTest.cpp LIBRARIES MagnumOpenGLTester)
corrade_add_test(GLMultisampleTextureGLTest MultisampleTextureGLTest.cpp LIBRARIES MagnumOpenGLTester)

2
src/Magnum/Image.cpp

@ -34,7 +34,7 @@ template<UnsignedInt dimensions> Image<dimensions>::Image(const PixelStorage sto
template<UnsignedInt dimensions> Image<dimensions>::Image(const PixelStorage storage, const UnsignedInt format, const UnsignedInt formatExtra, const UnsignedInt pixelSize, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data) noexcept: Image{storage, pixelFormatWrap(format), formatExtra, pixelSize, size, std::move(data)} {}
template<UnsignedInt dimensions> Image<dimensions>::Image(const PixelStorage storage, const PixelFormat format, const UnsignedInt formatExtra, const UnsignedInt pixelSize, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data) noexcept: _storage{storage}, _format{format}, _formatExtra{formatExtra}, _pixelSize{pixelSize}, _size{size}, _data{std::move(data)} {
CORRADE_ASSERT(Implementation::imageDataSize(*this) <= _data.size(), "Image::Image(): bad image data size, got" << _data.size() << "but expected at least" << Implementation::imageDataSize(*this), );
CORRADE_ASSERT(Implementation::imageDataSize(*this) <= _data.size(), "Image::Image(): data too small, got" << _data.size() << "but expected at least" << Implementation::imageDataSize(*this) << "bytes", );
}
template<UnsignedInt dimensions> Image<dimensions>::Image(const PixelStorage storage, const PixelFormat format) noexcept: Image{storage, format, {}, Magnum::pixelSize(format)} {}

4
src/Magnum/ImageView.cpp

@ -34,7 +34,7 @@ template<UnsignedInt dimensions> ImageView<dimensions>::ImageView(const PixelSto
template<UnsignedInt dimensions> ImageView<dimensions>::ImageView(const PixelStorage storage, const UnsignedInt format, const UnsignedInt formatExtra, const UnsignedInt pixelSize, const VectorTypeFor<dimensions, Int>& size, const Containers::ArrayView<const void> data) noexcept: ImageView{storage, pixelFormatWrap(format), formatExtra, pixelSize, size, data} {}
template<UnsignedInt dimensions> ImageView<dimensions>::ImageView(const PixelStorage storage, const PixelFormat format, const UnsignedInt formatExtra, const UnsignedInt pixelSize, const VectorTypeFor<dimensions, Int>& size, const Containers::ArrayView<const void> data) noexcept: _storage{storage}, _format{format}, _formatExtra{formatExtra}, _pixelSize{pixelSize}, _size{size}, _data{reinterpret_cast<const char*>(data.data()), data.size()} {
CORRADE_ASSERT(!_data || Implementation::imageDataSize(*this) <= _data.size(), "ImageView::ImageView(): bad image data size, got" << _data.size() << "but expected at least" << Implementation::imageDataSize(*this), );
CORRADE_ASSERT(!_data || Implementation::imageDataSize(*this) <= _data.size(), "ImageView::ImageView(): data too small, got" << _data.size() << "but expected at least" << Implementation::imageDataSize(*this) << "bytes", );
}
template<UnsignedInt dimensions> ImageView<dimensions>::ImageView(const PixelStorage storage, const PixelFormat format, const VectorTypeFor<dimensions, Int>& size) noexcept: ImageView{storage, format, {}, Magnum::pixelSize(format), size} {}
@ -44,7 +44,7 @@ template<UnsignedInt dimensions> ImageView<dimensions>::ImageView(const PixelSto
template<UnsignedInt dimensions> ImageView<dimensions>::ImageView(const PixelStorage storage, const PixelFormat format, const UnsignedInt formatExtra, const UnsignedInt pixelSize, const VectorTypeFor<dimensions, Int>& size) noexcept: _storage{storage}, _format{format}, _formatExtra{formatExtra}, _pixelSize{pixelSize}, _size{size}, _data{nullptr} {}
template<UnsignedInt dimensions> void ImageView<dimensions>::setData(const Containers::ArrayView<const void> data) {
CORRADE_ASSERT(Implementation::imageDataSize(*this) <= data.size(), "ImageView::setData(): bad image data size, got" << data.size() << "but expected at least" << Implementation::imageDataSize(*this), );
CORRADE_ASSERT(Implementation::imageDataSize(*this) <= data.size(), "ImageView::setData(): data too small, got" << data.size() << "but expected at least" << Implementation::imageDataSize(*this) << "bytes", );
_data = {reinterpret_cast<const char*>(data.data()), data.size()};
}

6
src/Magnum/Test/CMakeLists.txt

@ -24,8 +24,11 @@
#
corrade_add_test(ArrayTest ArrayTest.cpp LIBRARIES Magnum)
corrade_add_test(ImageTest ImageTest.cpp LIBRARIES MagnumTestLib)
corrade_add_test(ImageViewTest ImageViewTest.cpp LIBRARIES MagnumTestLib)
corrade_add_test(PixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumTestLib)
target_compile_definitions(PixelFormatTest PRIVATE "CORRADE_GRACEFUL_ASSERT")
corrade_add_test(PixelStorageTest PixelStorageTest.cpp LIBRARIES Magnum)
corrade_add_test(ResourceManagerTest ResourceManagerTest.cpp LIBRARIES Magnum)
target_compile_definitions(ResourceManagerTest PRIVATE "CORRADE_GRACEFUL_ASSERT")
@ -40,7 +43,10 @@ corrade_add_test(TagsTest TagsTest.cpp LIBRARIES Magnum)
set_target_properties(
ArrayTest
ImageTest
ImageViewTest
PixelFormatTest
PixelStorageTest
ResourceManagerTest
ResourceManagerLocalInstanceTestLib
ResourceManagerLocalInstanceTest

576
src/Magnum/Test/ImageTest.cpp

@ -23,6 +23,7 @@
DEALINGS IN THE SOFTWARE.
*/
#include <sstream>
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/Image.h"
@ -33,60 +34,366 @@ namespace Magnum { namespace Test {
struct ImageTest: TestSuite::Tester {
explicit ImageTest();
void construct();
void constructCompressed();
void constructGeneric();
void constructGenericPlaceholder();
void constructImplementationSpecific();
void constructImplementationSpecificPlaceholder();
void constructCompressedGeneric();
void constructCompressedGenericPlaceholder();
void constructCompressedImplementationSpecific();
void constructInvalidSize();
void constructCompressedInvalidSize();
void constructCopy();
void constructCopyCompressed();
void constructMove();
void constructMoveCompressed();
void toView();
void toViewCompressed();
void constructMoveGeneric();
void constructMoveImplementationSpecific();
void constructMoveCompressedGeneric();
void constructMoveCompressedImplementationSpecific();
void toViewGeneric();
void toViewImplementationSpecific();
void toViewCompressedGeneric();
void toViewCompressedImplementationSpecific();
void access();
void accessCompressed();
void release();
void releaseCompressed();
};
ImageTest::ImageTest() {
addTests({&ImageTest::construct,
&ImageTest::constructCompressed,
addTests({&ImageTest::constructGeneric,
&ImageTest::constructGenericPlaceholder,
&ImageTest::constructImplementationSpecific,
&ImageTest::constructImplementationSpecificPlaceholder,
&ImageTest::constructCompressedGeneric,
&ImageTest::constructCompressedGenericPlaceholder,
&ImageTest::constructCompressedImplementationSpecific,
&ImageTest::constructInvalidSize,
&ImageTest::constructCompressedInvalidSize,
&ImageTest::constructCopy,
&ImageTest::constructCopyCompressed,
&ImageTest::constructMove,
&ImageTest::constructMoveCompressed,
&ImageTest::toView,
&ImageTest::toViewCompressed,
&ImageTest::constructMoveGeneric,
&ImageTest::constructMoveImplementationSpecific,
&ImageTest::constructMoveCompressedGeneric,
&ImageTest::constructMoveCompressedImplementationSpecific,
&ImageTest::toViewGeneric,
&ImageTest::toViewImplementationSpecific,
&ImageTest::toViewCompressedGeneric,
&ImageTest::toViewCompressedImplementationSpecific,
&ImageTest::access,
&ImageTest::accessCompressed,
&ImageTest::release,
&ImageTest::releaseCompressed});
}
void ImageTest::construct() {
auto data = new char[3*4];
Image2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGBA, PixelType::UnsignedByte, {1, 3}, Containers::Array<char>{data, 3*4}};
namespace {
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::RGBA);
CORRADE_COMPARE(a.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
CORRADE_COMPARE(a.data(), data);
namespace GL {
enum class PixelFormat { RGB = 666 };
enum class PixelType { UnsignedShort = 1337 };
UnsignedInt pixelSize(PixelFormat format, PixelType type) {
CORRADE_INTERNAL_ASSERT(format == PixelFormat::RGB);
CORRADE_INTERNAL_ASSERT(type == PixelType::UnsignedShort);
return 6;
}
enum class CompressedPixelFormat { RGBS3tcDxt1 = 21 };
}
void ImageTest::constructCompressed() {
auto data = new char[8];
CompressedImage2D a{
#ifndef MAGNUM_TARGET_GLES
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_COMPARE(a.format(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(a.size(), Vector2i(4, 4));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
namespace Vk {
enum class PixelFormat { R32G32B32F = 42 };
UnsignedInt pixelSize(PixelFormat format) {
CORRADE_INTERNAL_ASSERT(format == PixelFormat::R32G32B32F);
return 12;
}
enum class CompressedPixelFormat { Bc1SRGBAlpha = 42 };
}
}
void ImageTest::constructGeneric() {
{
auto data = new char[4*4];
Image2D a{PixelFormat::RGBA8Unorm, {1, 3}, Containers::Array<char>{data, 4*4}};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), PixelFormat::RGBA8Unorm);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 4);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 4*4);
} {
auto data = new char[3*2];
Image2D a{PixelStorage{}.setAlignment(1),
PixelFormat::R16UI, {1, 3}, Containers::Array<char>{data, 3*2}};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::R16UI);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 2);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*2);
}
}
void ImageTest::constructGenericPlaceholder() {
{
Image2D a{PixelFormat::RG32F};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), PixelFormat::RG32F);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 8);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(a.data(), nullptr);
} {
Image2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB16F};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::RGB16F);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(a.data(), nullptr);
}
}
void ImageTest::constructImplementationSpecific() {
/* Single format */
{
auto data = new char[3*12];
Image2D a{Vk::PixelFormat::R32G32B32F, {1, 3}, Containers::Array<char>{data, 3*12}};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*12);
} {
auto data = new char[3*12];
Image2D a{PixelStorage{}.setAlignment(1),
Vk::PixelFormat::R32G32B32F, {1, 3}, Containers::Array<char>{data, 3*12}};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*12);
}
/* Format + extra */
{
auto data = new char[3*8];
Image2D a{GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, Containers::Array<char>{data, 3*8}};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*8);
} {
auto data = new char[3*6];
Image2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, Containers::Array<char>{data, 3*6}};
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*6);
}
/* Manual pixel size */
{
auto data = new char[3*6];
Image2D a{PixelStorage{}.setAlignment(1), 666, 1337, 6, {1, 3}, Containers::Array<char>{data, 3*6}};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*6);
}
}
void ImageTest::constructImplementationSpecificPlaceholder() {
/* Single format */
{
Image2D a{Vk::PixelFormat::R32G32B32F};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(a.data(), nullptr);
} {
Image2D a{PixelStorage{}.setAlignment(1),
Vk::PixelFormat::R32G32B32F};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(a.data(), nullptr);
}
/* Format + extra */
{
Image2D a{GL::PixelFormat::RGB, GL::PixelType::UnsignedShort};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(a.data(), nullptr);
} {
Image2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort};
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(a.data(), nullptr);
}
/* Manual pixel size */
{
Image2D a{PixelStorage{}.setAlignment(1), 666, 1337, 6};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(a.data(), nullptr);
}
}
void ImageTest::constructCompressedGeneric() {
{
auto data = new char[8];
CompressedImage2D a{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4},
Containers::Array<char>{data, 8}};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{0});
CORRADE_COMPARE(a.format(), CompressedPixelFormat::Bc1RGBAUnorm);
CORRADE_COMPARE(a.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
} {
auto data = new char[8];
CompressedImage2D a{CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
CompressedPixelFormat::Bc1RGBAUnorm, {4, 4},
Containers::Array<char>{data, 8}};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(a.format(), CompressedPixelFormat::Bc1RGBAUnorm);
CORRADE_COMPARE(a.size(), Vector2i(4, 4));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
}
}
void ImageTest::constructCompressedGenericPlaceholder() {
{
CompressedImage2D a;
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{0});
CORRADE_COMPARE(a.format(), CompressedPixelFormat{});
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(a.data(), nullptr);
} {
CompressedImage2D a{CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4})};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(a.format(), CompressedPixelFormat{});
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(a.data(), nullptr);
}
}
void ImageTest::constructCompressedImplementationSpecific() {
/* Format with autodetection */
{
auto data = new char[8];
CompressedImage2D a{GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4},
Containers::Array<char>{data, 8}};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{0});
CORRADE_COMPARE(a.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(a.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
} {
auto data = new char[8];
CompressedImage2D a{CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4},
Containers::Array<char>{data, 8}};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(a.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(a.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
}
/* Manual properties not implemented yet */
}
void ImageTest::constructInvalidSize() {
std::ostringstream out;
Error redirectError{&out};
/* Doesn't consider alignment */
Image2D{PixelFormat::RGB8Unorm, {1, 3}, Containers::Array<char>{3*3}};
CORRADE_COMPARE(out.str(), "Image::Image(): data too small, got 9 but expected at least 12 bytes\n");
}
void ImageTest::constructCompressedInvalidSize() {
CORRADE_EXPECT_FAIL("Size checking for compressed image data is not implemented yet.");
/* Too small for given format */
{
std::ostringstream out;
Error redirectError{&out};
CompressedImage2D{CompressedPixelFormat::Bc2RGBAUnorm, {4, 4}, Containers::Array<char>{2}};
CORRADE_COMPARE(out.str(), "CompressedImage::CompressedImage(): data too small, got 2 but expected at least 4 bytes\n");
/* Size should be rounded up even if the image size is not full block */
} {
std::ostringstream out;
Error redirectError{&out};
CompressedImage2D{CompressedPixelFormat::Bc2RGBAUnorm, {2, 2}, Containers::Array<char>{2}};
CORRADE_COMPARE(out.str(), "CompressedImage::CompressedImage(): data too small, got 2 but expected at least 4 bytes\n");
}
}
void ImageTest::constructCopy() {
@ -99,106 +406,209 @@ void ImageTest::constructCopyCompressed() {
CORRADE_VERIFY(!(std::is_assignable<CompressedImage2D, const CompressedImage2D&>{}));
}
void ImageTest::constructMove() {
auto data = new char[3*3];
void ImageTest::constructMoveGeneric() {
auto data = new char[3*16];
Image2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB, PixelType::UnsignedByte, {1, 3}, Containers::Array<char>{data, 3*3}};
PixelFormat::RGBA32F, {1, 3}, Containers::Array<char>{data, 3*16}};
Image2D b(std::move(a));
CORRADE_COMPARE(a.data(), nullptr);
CORRADE_COMPARE(a.size(), Vector2i());
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(b.storage().alignment(), 1);
CORRADE_COMPARE(b.format(), PixelFormat::RGBA32F);
CORRADE_COMPARE(b.formatExtra(), 0);
CORRADE_COMPARE(b.pixelSize(), 16);
CORRADE_COMPARE(b.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(b.data(), data);
CORRADE_COMPARE(b.data().size(), 3*16);
auto data2 = new char[24];
Image2D c{PixelFormat::R8I, {2, 6}, Containers::Array<char>{data2, 24}};
c = std::move(b);
CORRADE_COMPARE(b.data(), data2);
CORRADE_COMPARE(b.size(), (Vector2i{2, 6}));
CORRADE_COMPARE(c.storage().alignment(), 1);
CORRADE_COMPARE(c.format(), PixelFormat::RGBA32F);
CORRADE_COMPARE(c.formatExtra(), 0);
CORRADE_COMPARE(c.pixelSize(), 16);
CORRADE_COMPARE(c.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(c.data(), data);
CORRADE_COMPARE(c.data().size(), 3*16);
}
void ImageTest::constructMoveImplementationSpecific() {
auto data = new char[3*6];
Image2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, Containers::Array<char>{data, 3*6}};
Image2D b(std::move(a));
CORRADE_COMPARE(a.data(), nullptr);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(b.storage().alignment(), 1);
CORRADE_COMPARE(b.format(), PixelFormat::RGB);
CORRADE_COMPARE(b.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(b.size(), Vector2i(1, 3));
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);
auto data2 = new char[12*4*2];
Image2D c{PixelFormat::RGBA, PixelType::UnsignedShort, {2, 6}, Containers::Array<char>{data2, 12*4*2}};
Image2D c{PixelStorage{},
1, 2, 8, {2, 6}, Containers::Array<char>{data2, 12*4*2}};
c = std::move(b);
CORRADE_COMPARE(b.data(), data2);
CORRADE_COMPARE(b.size(), Vector2i(2, 6));
CORRADE_COMPARE(c.storage().alignment(), 1);
CORRADE_COMPARE(c.format(), PixelFormat::RGB);
CORRADE_COMPARE(c.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(c.size(), Vector2i(1, 3));
CORRADE_COMPARE(c.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(c.formatExtra(), 1337);
CORRADE_COMPARE(c.pixelSize(), 6);
CORRADE_COMPARE(c.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(c.data(), data);
CORRADE_COMPARE(c.data().size(), 3*6);
}
void ImageTest::constructMoveCompressed() {
void ImageTest::constructMoveCompressedGeneric() {
auto data = new char[8];
CompressedImage2D a{CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
CompressedImage2D a{
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
CompressedPixelFormat::Bc3RGBAUnorm, {4, 4}, Containers::Array<char>{data, 8}};
CompressedImage2D b{std::move(a)};
CORRADE_COMPARE(a.data(), nullptr);
CORRADE_COMPARE(a.size(), Vector2i());
CORRADE_COMPARE(a.size(), Vector2i{});
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(b.storage().compressedBlockSize(), Vector3i{0});
#endif
CORRADE_COMPARE(b.format(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(b.size(), Vector2i(4, 4));
CORRADE_COMPARE(b.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(b.format(), CompressedPixelFormat::Bc3RGBAUnorm);
CORRADE_COMPARE(b.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(b.data(), data);
CORRADE_COMPARE(b.data().size(), 8);
auto data2 = new char[16];
CompressedImage2D c{
#ifndef MAGNUM_TARGET_GLES
CompressedImage2D c{CompressedPixelFormat::Bc1RGBAUnorm, {8, 4}, Containers::Array<char>{data2, 16}};
c = std::move(b);
CORRADE_COMPARE(b.data(), data2);
CORRADE_COMPARE(b.size(), (Vector2i{8, 4}));
CORRADE_COMPARE(c.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(c.format(), CompressedPixelFormat::Bc3RGBAUnorm);
CORRADE_COMPARE(c.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(c.data(), data);
CORRADE_COMPARE(c.data().size(), 8);
}
void ImageTest::constructMoveCompressedImplementationSpecific() {
auto data = new char[8];
CompressedImage2D a{
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
CompressedPixelFormat::RGBAS3tcDxt3, {8, 4}, Containers::Array<char>{data2, 16}};
GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
CompressedImage2D b{std::move(a)};
CORRADE_COMPARE(a.data(), nullptr);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_COMPARE(b.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(b.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(b.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(b.data(), data);
CORRADE_COMPARE(b.data().size(), 8);
auto data2 = new char[16];
CompressedImage2D c{CompressedPixelFormat::Bc2RGBAUnorm, {8, 4}, Containers::Array<char>{data2, 16}};
c = std::move(b);
CORRADE_COMPARE_AS(b.data(), data2, char*);
CORRADE_COMPARE(b.data().size(), 16);
CORRADE_COMPARE(b.size(), Vector2i(8, 4));
CORRADE_COMPARE(b.data(), data2);
CORRADE_COMPARE(b.size(), (Vector2i{8, 4}));
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(c.storage().compressedBlockSize(), Vector3i{0});
#endif
CORRADE_COMPARE(c.format(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(c.size(), Vector2i(4, 4));
CORRADE_COMPARE(c.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(c.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(c.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(c.data(), data);
CORRADE_COMPARE(c.data().size(), 8);
}
void ImageTest::toView() {
auto data = new char[3*3];
void ImageTest::toViewGeneric() {
auto data = new char[3*4];
const Image2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB, PixelType::UnsignedByte, {1, 3}, Containers::Array<char>{data, 3*3}};
PixelFormat::RG16I, {1, 3}, Containers::Array<char>{data, 3*4}};
ImageView2D b = a;
CORRADE_COMPARE(b.storage().alignment(), 1);
CORRADE_COMPARE(b.format(), PixelFormat::RGB);
CORRADE_COMPARE(b.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(b.size(), Vector2i(1, 3));
CORRADE_COMPARE(b.format(), PixelFormat::RG16I);
CORRADE_COMPARE(b.formatExtra(), 0);
CORRADE_COMPARE(b.pixelSize(), 4);
CORRADE_COMPARE(b.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(b.data(), data);
}
void ImageTest::toViewImplementationSpecific() {
auto data = new char[3*6];
const Image2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, Containers::Array<char>{data, 3*6}};
ImageView2D b = a;
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);
}
void ImageTest::toViewCompressedGeneric() {
auto data = new char[8];
const CompressedImage2D a{
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
CompressedPixelFormat::Bc1RGBUnorm, {4, 4}, Containers::Array<char>{data, 8}};
CompressedImageView2D b = a;
CORRADE_COMPARE(b.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(b.format(), CompressedPixelFormat::Bc1RGBUnorm);
CORRADE_COMPARE(b.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(b.data(), data);
CORRADE_COMPARE(b.data().size(), 8);
}
void ImageTest::toViewCompressed() {
void ImageTest::toViewCompressedImplementationSpecific() {
auto data = new char[8];
const CompressedImage2D a{
#ifndef MAGNUM_TARGET_GLES
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
CompressedImageView2D b = a;
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(b.storage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_COMPARE(b.format(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(b.size(), Vector2i(4, 4));
CORRADE_COMPARE(b.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(b.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(b.data(), data);
CORRADE_COMPARE(b.data().size(), 8);
}
void ImageTest::access() {
auto data = new char[4*4];
Image2D a{PixelFormat::RGBA8Unorm, {1, 3}, Containers::Array<char>{data, 4*4}};
const Image2D& ca = a;
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(ca.data(), data);
}
void ImageTest::accessCompressed() {
auto data = new char[8];
CompressedImage2D a{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4},
Containers::Array<char>{data, 8}};
const CompressedImage2D& ca = a;
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(ca.data(), data);
}
void ImageTest::release() {
char data[] = {'c', 'a', 'f', 'e'};
Image2D a(PixelFormat::RGBA, PixelType::UnsignedByte, {1, 1}, Containers::Array<char>{data, 4});
Image2D a(PixelFormat::RGBA8Unorm, {1, 1}, Containers::Array<char>{data, 4});
const char* const pointer = a.release().release();
CORRADE_COMPARE(pointer, data);
@ -208,7 +618,7 @@ void ImageTest::release() {
void ImageTest::releaseCompressed() {
char data[8];
CompressedImage2D a{CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
CompressedImage2D a{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4}, Containers::Array<char>{data, 8}};
const char* const pointer = a.release().release();
CORRADE_COMPARE(pointer, data);

515
src/Magnum/Test/ImageViewTest.cpp

@ -23,6 +23,7 @@
DEALINGS IN THE SOFTWARE.
*/
#include <sstream>
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/ImageView.h"
@ -33,68 +34,467 @@ namespace Magnum { namespace Test {
struct ImageViewTest: TestSuite::Tester {
explicit ImageViewTest();
void construct();
void constructNullptr();
void constructCompressed();
void constructGeneric();
void constructGenericEmpty();
void constructGenericEmptyNullptr();
void constructImplementationSpecific();
void constructImplementationSpecificEmpty();
void constructImplementationSpecificEmptyNullptr();
void constructCompressedGeneric();
void constructCompressedGenericEmpty();
void constructCompressedImplementationSpecific();
void constructCompressedImplementationSpecificEmpty();
void constructInvalidSize();
void constructCompressedInvalidSize();
void setData();
void setDataCompressed();
void setDataInvalidSize();
void setDataCompressedInvalidSize();
};
ImageViewTest::ImageViewTest() {
addTests({&ImageViewTest::construct,
&ImageViewTest::constructNullptr,
&ImageViewTest::constructCompressed,
addTests({&ImageViewTest::constructGeneric,
&ImageViewTest::constructGenericEmpty,
&ImageViewTest::constructGenericEmptyNullptr,
&ImageViewTest::constructImplementationSpecific,
&ImageViewTest::constructImplementationSpecificEmpty,
&ImageViewTest::constructImplementationSpecificEmptyNullptr,
&ImageViewTest::constructCompressedGeneric,
&ImageViewTest::constructCompressedGenericEmpty,
&ImageViewTest::constructCompressedImplementationSpecific,
&ImageViewTest::constructCompressedImplementationSpecificEmpty,
&ImageViewTest::constructInvalidSize,
&ImageViewTest::constructCompressedInvalidSize,
&ImageViewTest::setData,
&ImageViewTest::setDataCompressed});
&ImageViewTest::setDataCompressed,
&ImageViewTest::setDataInvalidSize,
&ImageViewTest::setDataCompressedInvalidSize});
}
void ImageViewTest::construct() {
const char data[3*3]{};
ImageView2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB, PixelType::UnsignedByte, {1, 3}, data};
namespace {
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::RGB);
CORRADE_COMPARE(a.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
CORRADE_COMPARE(a.data(), data);
namespace GL {
enum class PixelFormat { RGB = 666 };
enum class PixelType { UnsignedShort = 1337 };
UnsignedInt pixelSize(PixelFormat format, PixelType type) {
CORRADE_INTERNAL_ASSERT(format == PixelFormat::RGB);
CORRADE_INTERNAL_ASSERT(type == PixelType::UnsignedShort);
return 6;
}
enum class CompressedPixelFormat { RGBS3tcDxt1 = 21 };
}
void ImageViewTest::constructNullptr() {
/* Just verify that it won't assert when passing nullptr array -- useful
e.g. for old-style texture allocation using setImage() */
ImageView2D a{PixelFormat::RGBA, PixelType::UnsignedByte, {256, 128}, nullptr};
CORRADE_COMPARE(a.size(), (Vector2i{256, 128}));
namespace Vk {
enum class PixelFormat { R32G32B32F = 42 };
UnsignedInt pixelSize(PixelFormat format) {
CORRADE_INTERNAL_ASSERT(format == PixelFormat::R32G32B32F);
return 12;
}
enum class CompressedPixelFormat { Bc1SRGBAlpha = 42 };
}
void ImageViewTest::constructCompressed() {
const char data[8]{};
CompressedImageView2D a{
#ifndef MAGNUM_TARGET_GLES
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, data};
}
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_COMPARE(a.format(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(a.size(), Vector2i(4, 4));
CORRADE_COMPARE(a.data(), data);
void ImageViewTest::constructGeneric() {
{
const char data[4*4]{};
ImageView2D a{PixelFormat::RGBA8Unorm, {1, 3}, data};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), PixelFormat::RGBA8Unorm);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 4);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 4*4);
} {
const char data[3*2]{};
ImageView2D a{PixelStorage{}.setAlignment(1),
PixelFormat::R16UI, {1, 3}, data};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::R16UI);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 2);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*2);
}
}
void ImageViewTest::constructGenericEmpty() {
{
ImageView2D a{PixelFormat::RG32F, {2, 6}};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), PixelFormat::RG32F);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 8);
CORRADE_COMPARE(a.size(), (Vector2i{2, 6}));
CORRADE_COMPARE(a.data(), nullptr);
} {
ImageView2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB16F, {8, 3}};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::RGB16F);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{8, 3}));
CORRADE_COMPARE(a.data(), nullptr);
}
}
void ImageViewTest::constructGenericEmptyNullptr() {
/* This should be deprecated/removed, as it doesn't provide anything over
the above and can lead to silent errors */
{
ImageView2D a{PixelFormat::RG32F, {2, 6}, nullptr};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), PixelFormat::RG32F);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 8);
CORRADE_COMPARE(a.size(), (Vector2i{2, 6}));
CORRADE_COMPARE(a.data(), nullptr);
} {
ImageView2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB16F, {8, 3}, nullptr};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::RGB16F);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{8, 3}));
CORRADE_COMPARE(a.data(), nullptr);
}
}
void ImageViewTest::constructImplementationSpecific() {
/* Single format */
{
const char data[3*12]{};
ImageView2D a{Vk::PixelFormat::R32G32B32F, {1, 3}, data};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*12);
} {
const char data[3*12]{};
ImageView2D a{PixelStorage{}.setAlignment(1),
Vk::PixelFormat::R32G32B32F, {1, 3}, data};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*12);
}
/* Format + extra */
{
const char data[3*8]{};
ImageView2D a{GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, data};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*8);
} {
const char data[3*6]{};
ImageView2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, data};
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*6);
}
/* Manual pixel size */
{
const char data[3*6]{};
ImageView2D a{PixelStorage{}.setAlignment(1), 666, 1337, 6, {1, 3}, data};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*6);
}
}
void ImageViewTest::constructImplementationSpecificEmpty() {
/* Single format */
{
ImageView2D a{Vk::PixelFormat::R32G32B32F, {2, 16}};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), (Vector2i{2, 16}));
CORRADE_COMPARE(a.data(), nullptr);
} {
ImageView2D a{PixelStorage{}.setAlignment(1),
Vk::PixelFormat::R32G32B32F, {1, 2}};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), (Vector2i{1, 2}));
CORRADE_COMPARE(a.data(), nullptr);
}
/* Format + extra */
{
ImageView2D a{GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), nullptr);
} {
ImageView2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {8, 2}};
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{8, 2}));
CORRADE_COMPARE(a.data(), nullptr);
}
/* Manual pixel size */
{
ImageView2D a{PixelStorage{}.setAlignment(1), 666, 1337, 6, {3, 3}};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{3, 3}));
CORRADE_COMPARE(a.data(), nullptr);
}
}
void ImageViewTest::constructImplementationSpecificEmptyNullptr() {
/* This should be deprecated/removed, as it doesn't provide anything over
the above and can lead to silent errors */
/* Single format */
{
ImageView2D a{Vk::PixelFormat::R32G32B32F, {2, 16}, nullptr};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), (Vector2i{2, 16}));
CORRADE_COMPARE(a.data(), nullptr);
} {
ImageView2D a{PixelStorage{}.setAlignment(1),
Vk::PixelFormat::R32G32B32F, {1, 2}, nullptr};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), (Vector2i{1, 2}));
CORRADE_COMPARE(a.data(), nullptr);
}
/* Format + extra */
{
ImageView2D a{GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, nullptr};
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), nullptr);
} {
ImageView2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {8, 2}, nullptr};
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{8, 2}));
CORRADE_COMPARE(a.data(), nullptr);
}
/* Manual pixel size */
{
ImageView2D a{PixelStorage{}.setAlignment(1), 666, 1337, 6, {3, 3}, nullptr};
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{3, 3}));
CORRADE_COMPARE(a.data(), nullptr);
}
}
void ImageViewTest::constructCompressedGeneric() {
{
const char data[8]{};
CompressedImageView2D a{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4}, data};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{0});
CORRADE_COMPARE(a.format(), CompressedPixelFormat::Bc1RGBAUnorm);
CORRADE_COMPARE(a.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
} {
const char data[8]{};
CompressedImageView2D a{CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
CompressedPixelFormat::Bc1RGBAUnorm, {4, 4},
data};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(a.format(), CompressedPixelFormat::Bc1RGBAUnorm);
CORRADE_COMPARE(a.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
}
}
void ImageViewTest::constructCompressedGenericEmpty() {
{
CompressedImageView2D a{CompressedPixelFormat::Bc1RGBAUnorm, {8, 16}};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{0});
CORRADE_COMPARE(a.format(), CompressedPixelFormat::Bc1RGBAUnorm);
CORRADE_COMPARE(a.size(), (Vector2i{8, 16}));
CORRADE_COMPARE(a.data(), nullptr);
} {
CompressedImageView2D a{CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
CompressedPixelFormat::Bc1RGBAUnorm, {8, 16}};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(a.format(), CompressedPixelFormat::Bc1RGBAUnorm);
CORRADE_COMPARE(a.size(), (Vector2i{8, 16}));
CORRADE_COMPARE(a.data(), nullptr);
}
}
void ImageViewTest::constructCompressedImplementationSpecific() {
/* Format with autodetection */
{
const char data[8]{};
CompressedImageView2D a{GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4},
data};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{0});
CORRADE_COMPARE(a.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(a.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
} {
const char data[8]{};
CompressedImageView2D a{CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4}, data};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(a.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(a.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
}
/* Manual properties not implemented yet */
}
void ImageViewTest::constructCompressedImplementationSpecificEmpty() {
/* Format with autodetection */
{
CompressedImageView2D a{GL::CompressedPixelFormat::RGBS3tcDxt1, {8, 16}};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{0});
CORRADE_COMPARE(a.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(a.size(), (Vector2i{8, 16}));
CORRADE_COMPARE(a.data(), nullptr);
} {
CompressedImageView2D a{CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 8}};
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(a.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(a.size(), (Vector2i{4, 8}));
CORRADE_COMPARE(a.data(), nullptr);
}
/* Manual properties not implemented yet */
}
void ImageViewTest::constructInvalidSize() {
std::ostringstream out;
Error redirectError{&out};
/* Doesn't consider alignment */
const char data[3*3]{};
ImageView2D{PixelFormat::RGB8Unorm, {1, 3}, data};
CORRADE_COMPARE(out.str(), "ImageView::ImageView(): data too small, got 9 but expected at least 12 bytes\n");
}
void ImageViewTest::constructCompressedInvalidSize() {
CORRADE_EXPECT_FAIL("Size checking for compressed image data is not implemented yet.");
const char data[2]{};
/* Too small for given format */
{
std::ostringstream out;
Error redirectError{&out};
CompressedImageView2D{CompressedPixelFormat::Bc2RGBAUnorm, {4, 4}, data};
CORRADE_COMPARE(out.str(), "CompressedImageView::CompressedImageView(): data too small, got 2 but expected at least 4 bytes\n");
/* Size should be rounded up even if the image size is not full block */
} {
std::ostringstream out;
Error redirectError{&out};
CompressedImageView2D{CompressedPixelFormat::Bc2RGBAUnorm, {2, 2}, data};
CORRADE_COMPARE(out.str(), "CompressedImageView::CompressedImageView(): data too small, got 2 but expected at least 4 bytes\n");
}
}
void ImageViewTest::setData() {
const char data[3*3]{};
ImageView2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB, PixelType::UnsignedByte, {1, 3}, data};
PixelFormat::RGB8Snorm, {1, 3}, data};
const char data2[3*3]{};
a.setData(data2);
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::RGB);
CORRADE_COMPARE(a.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(a.format(), PixelFormat::RGB8Snorm);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
CORRADE_COMPARE(a.data(), data2);
}
@ -102,21 +502,50 @@ void ImageViewTest::setData() {
void ImageViewTest::setDataCompressed() {
const char data[8]{};
CompressedImageView2D a{
#ifndef MAGNUM_TARGET_GLES
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, data};
CompressedPixelFormat::Bc1RGBAUnorm, {4, 4}, data};
const char data2[16]{};
a.setData(data2);
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(a.storage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_COMPARE(a.format(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(a.format(), CompressedPixelFormat::Bc1RGBAUnorm);
CORRADE_COMPARE(a.size(), Vector2i(4, 4));
CORRADE_COMPARE(a.data(), data2);
}
void ImageViewTest::setDataInvalidSize() {
std::ostringstream out;
Error redirectError{&out};
ImageView2D image{PixelFormat::RGB8Unorm, {1, 3}};
const char data[3*3]{};
/* Doesn't consider alignment */
image.setData(data);
CORRADE_COMPARE(out.str(), "ImageView::setData(): data too small, got 9 but expected at least 12 bytes\n");
}
void ImageViewTest::setDataCompressedInvalidSize() {
CORRADE_EXPECT_FAIL("Size checking for compressed image data is not implemented yet.");
const char data[2]{};
/* Too small for given format */
{
std::ostringstream out;
Error redirectError{&out};
CompressedImageView2D{CompressedPixelFormat::Bc2RGBAUnorm, {4, 4}, data};
CORRADE_COMPARE(out.str(), "CompressedImageView::setData(): data too small, got 2 but expected at least 4 bytes\n");
/* Size should be rounded up even if the image size is not that big */
} {
std::ostringstream out;
Error redirectError{&out};
CompressedImageView2D{CompressedPixelFormat::Bc2RGBAUnorm, {2, 2}, data};
CORRADE_COMPARE(out.str(), "CompressedImageView::setData(): data too small, got 2 but expected at least 4 bytes\n");
}
}
}}
CORRADE_TEST_MAIN(Magnum::Test::ImageViewTest)

222
src/Magnum/Test/PixelStorageTest.cpp

@ -34,103 +34,63 @@ namespace Magnum { namespace Test {
struct PixelStorageTest: TestSuite::Tester {
explicit PixelStorageTest();
void pixelSize();
void compare();
#ifndef MAGNUM_TARGET_GLES
void compareCompressed();
#endif
void dataProperties();
void dataPropertiesAlignment();
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void dataPropertiesRowLength();
#endif
#ifndef MAGNUM_TARGET_GLES2
void dataPropertiesImageHeight();
#endif
void dataSize1D();
void dataSize2D();
void dataSize3D();
#ifndef MAGNUM_TARGET_GLES
void dataPropertiesCompressed();
void dataPropertiesCompressedRowLength();
void dataPropertiesCompressedImageHeight();
void dataOffsetSizeCompressed();
#endif
};
typedef Math::Vector3<std::size_t> Vector3st;
PixelStorageTest::PixelStorageTest() {
addTests({&PixelStorageTest::pixelSize,
&PixelStorageTest::compare,
#ifndef MAGNUM_TARGET_GLES
addTests({&PixelStorageTest::compare,
&PixelStorageTest::compareCompressed,
#endif
&PixelStorageTest::dataProperties,
&PixelStorageTest::dataPropertiesAlignment,
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
&PixelStorageTest::dataPropertiesRowLength,
#endif
#ifndef MAGNUM_TARGET_GLES2
&PixelStorageTest::dataPropertiesImageHeight,
#endif
&PixelStorageTest::dataSize1D,
&PixelStorageTest::dataSize2D,
&PixelStorageTest::dataSize3D,
#ifndef MAGNUM_TARGET_GLES
&PixelStorageTest::dataPropertiesCompressed,
&PixelStorageTest::dataPropertiesCompressedRowLength,
&PixelStorageTest::dataPropertiesCompressedImageHeight,
&PixelStorageTest::dataOffsetSizeCompressed
#endif
});
}
void PixelStorageTest::pixelSize() {
CORRADE_COMPARE(PixelStorage::pixelSize(PixelFormat::RGBA, PixelType::UnsignedInt), 4*4);
CORRADE_COMPARE(PixelStorage::pixelSize(PixelFormat::DepthComponent, PixelType::UnsignedShort), 2);
#ifndef MAGNUM_TARGET_WEBGL
CORRADE_COMPARE(PixelStorage::pixelSize(PixelFormat::StencilIndex, PixelType::UnsignedByte), 1);
#endif
CORRADE_COMPARE(PixelStorage::pixelSize(PixelFormat::DepthStencil, PixelType::UnsignedInt248), 4);
&PixelStorageTest::dataOffsetSizeCompressed});
}
void PixelStorageTest::compare() {
PixelStorage a;
a
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
.setRowLength(1)
#endif
#ifndef MAGNUM_TARGET_GLES2
a.setRowLength(1)
.setImageHeight(15)
#endif
.setSkip({1, 3, 4})
.setAlignment(3);
CORRADE_VERIFY(a == a);
CORRADE_VERIFY(a != PixelStorage{});
CORRADE_VERIFY(PixelStorage{} == PixelStorage{});
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
CORRADE_VERIFY(PixelStorage{}.setRowLength(15) != PixelStorage{}.setRowLength(17));
#endif
#ifndef MAGNUM_TARGET_GLES2
CORRADE_VERIFY(PixelStorage{}.setImageHeight(32) != PixelStorage{}.setImageHeight(31));
#endif
CORRADE_VERIFY(PixelStorage{}.setSkip({1, 5, 7}) != PixelStorage{}.setSkip({7, 1, 5}));
CORRADE_VERIFY(PixelStorage{}.setAlignment(3) != PixelStorage{}.setAlignment(5));
}
#ifndef MAGNUM_TARGET_GLES
void PixelStorageTest::compareCompressed() {
CompressedPixelStorage a;
a.setSkip({16, 2, 1})
@ -144,24 +104,21 @@ void PixelStorageTest::compareCompressed() {
CORRADE_VERIFY(CompressedPixelStorage{}.setCompressedBlockSize({2, 7, 19}) != CompressedPixelStorage{}.setCompressedBlockSize({2, 7, 16}));
CORRADE_VERIFY(CompressedPixelStorage{}.setCompressedBlockDataSize(32) != CompressedPixelStorage{}.setCompressedBlockDataSize(30));
}
#endif
void PixelStorageTest::dataProperties() {
PixelStorage storage;
storage.setAlignment(1);
CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{0}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{}, {0, 0, 0}, 4}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{1}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{}, {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<Vector3st, Vector3st, std::size_t>{{}, {8, 2, 1}, 1}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 1}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{}, {2, 4, 1}, 1}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 6}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{}, {2, 4, 6}, 1}));
#endif
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::RGBA8Unorm), Vector3i{0}),
(std::pair<Vector3st, Vector3st>{{}, {0, 0, 0}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::RGBA8Unorm), Vector3i{1}),
(std::pair<Vector3st, Vector3st>{{}, {4, 1, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {8, 2, 1}),
(std::pair<Vector3st, Vector3st>{{}, {8, 2, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {2, 4, 1}),
(std::pair<Vector3st, Vector3st>{{}, {2, 4, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {2, 4, 6}),
(std::pair<Vector3st, Vector3st>{{}, {2, 4, 6}}));
}
void PixelStorageTest::dataPropertiesAlignment() {
@ -169,144 +126,120 @@ void PixelStorageTest::dataPropertiesAlignment() {
storage.setAlignment(8)
.setSkip({3, 2, 1});
CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{0}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3*4, 0, 0}, {0, 0, 0}, 4}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{1}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{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<Vector3st, Vector3st, std::size_t>{{3, 16, 16}, {8, 2, 1}, 1}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 1}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3, 16, 32}, {8, 4, 1}, 1}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 6}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3, 16, 32}, {8, 4, 6}, 1}));
#endif
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::RGBA8Unorm), Vector3i{0}),
(std::pair<Vector3st, Vector3st>{{3*4, 0, 0}, {0, 0, 0}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::RGBA8Unorm), Vector3i{1}),
(std::pair<Vector3st, Vector3st>{{12, 16, 8}, {8, 1, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {8, 2, 1}),
(std::pair<Vector3st, Vector3st>{{3, 16, 16}, {8, 2, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {2, 4, 1}),
(std::pair<Vector3st, Vector3st>{{3, 16, 32}, {8, 4, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {2, 4, 6}),
(std::pair<Vector3st, Vector3st>{{3, 16, 32}, {8, 4, 6}}));
}
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void PixelStorageTest::dataPropertiesRowLength() {
PixelStorage storage;
storage.setAlignment(4)
.setRowLength(15)
.setSkip({3, 7, 0});
CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{0}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3*4, 7*15*4, 0}, {0, 0, 0}, 4}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{1}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3*4, 7*15*4, 0}, {60, 1, 1}, 4}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {4, 2, 1}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3, 7*16, 0}, {16, 2, 1}, 1}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 1}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3, 7*16, 0}, {16, 4, 1}, 1}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 6}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3, 7*16, 0}, {16, 4, 6}, 1}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::RGBA8Unorm), Vector3i{0}),
(std::pair<Vector3st, Vector3st>{{3*4, 7*15*4, 0}, {0, 0, 0}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::RGBA8Unorm), Vector3i{1}),
(std::pair<Vector3st, Vector3st>{{3*4, 7*15*4, 0}, {60, 1, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {4, 2, 1}),
(std::pair<Vector3st, Vector3st>{{3, 7*16, 0}, {16, 2, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {2, 4, 1}),
(std::pair<Vector3st, Vector3st>{{3, 7*16, 0}, {16, 4, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {2, 4, 6}),
(std::pair<Vector3st, Vector3st>{{3, 7*16, 0}, {16, 4, 6}}));
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void PixelStorageTest::dataPropertiesImageHeight() {
PixelStorage storage;
storage.setAlignment(1)
.setImageHeight(128)
.setSkip({3, 7, 2});
CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{0}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3*4, 0, 0}, {0, 0, 0}, 4}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::RGBA, PixelType::UnsignedByte, Vector3i{1}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{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<Vector3st, Vector3st, std::size_t>{{3, 7*1*4, 2*128*4}, {4, 128, 1}, 1}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 1}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3, 7*1*2, 2*128*2}, {2, 128, 1}, 1}));
CORRADE_COMPARE(storage.dataProperties(PixelFormat::Red, PixelType::UnsignedByte, {2, 4, 6}),
(std::tuple<Vector3st, Vector3st, std::size_t>{{3, 7*1*2, 2*128*2}, {2, 128, 6}, 1}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::RGBA8Unorm), Vector3i{0}),
(std::pair<Vector3st, Vector3st>{{3*4, 0, 0}, {0, 0, 0}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::RGBA8Unorm), Vector3i{1}),
(std::pair<Vector3st, Vector3st>{{3*4, 7*1*4, 2*128*1*4}, {4, 128, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {4, 2, 1}),
(std::pair<Vector3st, Vector3st>{{3, 7*1*4, 2*128*4}, {4, 128, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {2, 4, 1}),
(std::pair<Vector3st, Vector3st>{{3, 7*1*2, 2*128*2}, {2, 128, 1}}));
CORRADE_COMPARE(storage.dataProperties(pixelSize(PixelFormat::R8Unorm), {2, 4, 6}),
(std::pair<Vector3st, Vector3st>{{3, 7*1*2, 2*128*2}, {2, 128, 6}}));
}
#endif
void PixelStorageTest::dataSize1D() {
const Image1D image{PixelStorage{}.setAlignment(2)
.setSkip({2, 0, 0}),
PixelFormat::RGB, PixelType::UnsignedByte};
const Image1D image{
PixelStorage{}.setAlignment(2).setSkip({2, 0, 0}),
PixelFormat::RGB8Unorm};
CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Math::Vector<1, Int>{3}),
16);
}
void PixelStorageTest::dataSize2D() {
const Image2D image{PixelStorage{}.setAlignment(2)
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
.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)*16);
#else
const Image2D image{
PixelStorage{}.setAlignment(2)
.setRowLength(7)
.setSkip({2, 3, 0}),
PixelFormat::RGB8Unorm};
CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector2i{5, 9}),
(3 + 9)*22);
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
/* This shouldn't overflow the 128x128 rectangle */
const Image2D image2{PixelStorage{}.setSkip({64, 0, 0})
.setRowLength(128),
PixelFormat::RGBA, PixelType::UnsignedByte};
const Image2D image2{
PixelStorage{}.setSkip({64, 0, 0})
.setRowLength(128),
PixelFormat::RGBA8Unorm};
CORRADE_COMPARE(Implementation::imageDataSizeFor(image2, Vector2i{64, 128}), 65536);
/* This shouldn't overflow the 128x128 rectangle */
const Image2D image3{PixelStorage{}.setSkip({64, 64, 0})
.setRowLength(128),
PixelFormat::RGBA, PixelType::UnsignedByte};
const Image2D image3{
PixelStorage{}.setSkip({64, 64, 0})
.setRowLength(128),
PixelFormat::RGBA8Unorm};
CORRADE_COMPARE(Implementation::imageDataSizeFor(image3, Vector2i{64, 64}), 65536);
#endif
}
void PixelStorageTest::dataSize3D() {
const Image3D image{PixelStorage{}.setAlignment(2)
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
.setRowLength(7)
#endif
#ifndef MAGNUM_TARGET_GLES2
.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, Vector3i{5, 9, 3}),
(1 + 3)*9*16);
#elif defined(MAGNUM_TARGET_GLES2)
CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector3i{5, 9, 3}),
(1 + 3)*9*22);
#else
const Image3D image{
PixelStorage{}.setAlignment(2)
.setRowLength(7)
.setImageHeight(10)
.setSkip({2, 3, 1}),
PixelFormat::RGB8Unorm};
CORRADE_COMPARE(Implementation::imageDataSizeFor(image, Vector3i{5, 9, 3}),
(1 + 3)*10*22);
#endif
#ifndef MAGNUM_TARGET_GLES2
/* This shouldn't overflow the 128x128x128 cube */
const Image3D image2{PixelStorage{}.setSkip({64, 64, 0})
.setRowLength(128)
.setImageHeight(128),
PixelFormat::RGBA, PixelType::UnsignedByte};
const Image3D image2{
PixelStorage{}.setSkip({64, 64, 0})
.setRowLength(128)
.setImageHeight(128),
PixelFormat::RGBA8Unorm};
CORRADE_COMPARE(Implementation::imageDataSizeFor(image2, Vector3i{64, 64, 128}), 8388608);
/* This shouldn't overflow the 128x128x128 cube */
const Image3D image3{PixelStorage{}.setSkip({64, 64, 64})
.setRowLength(128)
.setImageHeight(128),
PixelFormat::RGBA, PixelType::UnsignedByte};
const Image3D image3{
PixelStorage{}.setSkip({64, 64, 64})
.setRowLength(128)
.setImageHeight(128),
PixelFormat::RGBA8Unorm};
CORRADE_COMPARE(Implementation::imageDataSizeFor(image3, Vector3i{64, 64, 64}), 8388608);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void PixelStorageTest::dataPropertiesCompressed() {
CompressedPixelStorage storage;
storage.setCompressedBlockSize({3, 4, 5})
@ -349,7 +282,6 @@ void PixelStorageTest::dataOffsetSizeCompressed() {
CORRADE_COMPARE(Implementation::compressedImageDataOffsetSizeFor(image, Vector3i{4, 4, 1}),
(std::pair<std::size_t, std::size_t>{16*4*4 + 16*2 + 16, 16}));
}
#endif
}}

53
src/Magnum/Trade/CMakeLists.txt

@ -29,7 +29,6 @@ set(MagnumTrade_SRCS
AbstractImageConverter.cpp
AbstractImporter.cpp
AbstractMaterialData.cpp
ImageData.cpp
LightData.cpp
MeshData2D.cpp
MeshData3D.cpp
@ -40,6 +39,10 @@ set(MagnumTrade_SRCS
PhongMaterialData.cpp
SceneData.cpp
TextureData.cpp)
set(MagnumTrade_GracefulAssert_SRCS
ImageData.cpp)
set(MagnumTrade_HEADERS
AbstractImporter.h
AbstractImageConverter.h
@ -65,9 +68,26 @@ if(NOT CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT)
${CMAKE_CURRENT_BINARY_DIR}/configure.h)
endif()
# Objects shared between main and test library
add_library(MagnumTradeObjects OBJECT
${MagnumTrade_SRCS}
${MagnumTrade_HEADERS})
target_include_directories(MagnumTradeObjects PUBLIC
$<TARGET_PROPERTY:Magnum,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:MagnumGL,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:Corrade::PluginManager,INTERFACE_INCLUDE_DIRECTORIES>)
if(NOT BUILD_STATIC)
target_compile_definitions(MagnumTradeObjects PRIVATE "MagnumTradeObjects_EXPORTS")
endif()
if(NOT BUILD_STATIC OR BUILD_STATIC_PIC)
set_target_properties(MagnumTradeObjects PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
set_target_properties(MagnumTradeObjects PROPERTIES FOLDER "Magnum/Trade")
# Trade library
add_library(MagnumTrade ${SHARED_OR_STATIC}
${MagnumTrade_SRCS})
$<TARGET_OBJECTS:MagnumTradeObjects>
${MagnumTrade_GracefulAssert_SRCS})
set_target_properties(MagnumTrade PROPERTIES
DEBUG_POSTFIX "-d"
FOLDER "Magnum/Trade")
@ -101,6 +121,35 @@ if(WITH_IMAGECONVERTER)
endif()
if(BUILD_TESTS)
# Library with graceful assert for testing
add_library(MagnumTradeTestLib ${SHARED_OR_STATIC}
$<TARGET_OBJECTS:MagnumTradeObjects>
${MagnumTrade_GracefulAssert_SRCS})
target_include_directories(MagnumTradeTestLib PUBLIC
${PROJECT_SOURCE_DIR}/src
${PROJECT_BINARY_DIR}/src)
target_compile_definitions(MagnumTradeTestLib PRIVATE
"CORRADE_GRACEFUL_ASSERT" "MagnumTrade_EXPORTS")
set_target_properties(MagnumTradeTestLib PROPERTIES
DEBUG_POSTFIX "-d"
FOLDER "Magnum")
if(BUILD_STATIC_PIC)
set_target_properties(MagnumTradeTestLib PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
target_link_libraries(MagnumTradeTestLib
Magnum
MagnumGL
Corrade::PluginManager)
# On Windows we need to install first and then run the tests to avoid "DLL
# not found" hell, thus we need to install this too
if(CORRADE_TARGET_WINDOWS AND NOT CMAKE_CROSSCOMPILING AND NOT BUILD_STATIC)
install(TARGETS MagnumTradeTestLib
RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR}
LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}
ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
endif()
add_subdirectory(Test)
endif()

2
src/Magnum/Trade/ImageData.cpp

@ -34,7 +34,7 @@ template<UnsignedInt dimensions> ImageData<dimensions>::ImageData(const PixelSto
template<UnsignedInt dimensions> ImageData<dimensions>::ImageData(const PixelStorage storage, const UnsignedInt format, const UnsignedInt formatExtra, const UnsignedInt pixelSize, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data, const void* const importerState) noexcept: ImageData{storage, pixelFormatWrap(format), formatExtra, pixelSize, size, std::move(data), importerState} {}
template<UnsignedInt dimensions> ImageData<dimensions>::ImageData(const PixelStorage storage, const PixelFormat format, const UnsignedInt formatExtra, const UnsignedInt pixelSize, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data, const void* const importerState) noexcept: _compressed{false}, _storage{storage}, _format{format}, _formatExtra{formatExtra}, _pixelSize{pixelSize}, _size{size}, _data{std::move(data)}, _importerState{importerState} {
CORRADE_ASSERT(Implementation::imageDataSize(*this) <= _data.size(), "Trade::ImageData::ImageData(): bad image data size, got" << _data.size() << "but expected at least" << Implementation::imageDataSize(*this), );
CORRADE_ASSERT(Implementation::imageDataSize(*this) <= _data.size(), "Trade::ImageData::ImageData(): data too small, got" << _data.size() << "but expected at least" << Implementation::imageDataSize(*this) << "bytes", );
}
template<UnsignedInt dimensions> ImageData<dimensions>::ImageData(const CompressedPixelStorage storage, const CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data, const void* const importerState) noexcept: _compressed{true}, _compressedStorage{storage}, _compressedFormat{format}, _size{size}, _data{std::move(data)}, _importerState{importerState} {}

2
src/Magnum/Trade/Test/CMakeLists.txt

@ -41,7 +41,7 @@ corrade_add_test(TradeAbstractImporterTest AbstractImporterTest.cpp
FILES file.bin)
target_include_directories(TradeAbstractImporterTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
corrade_add_test(TradeCameraDataTest CameraDataTest.cpp LIBRARIES MagnumTrade)
corrade_add_test(TradeImageDataTest ImageDataTest.cpp LIBRARIES MagnumTrade)
corrade_add_test(TradeImageDataTest ImageDataTest.cpp LIBRARIES MagnumTradeTestLib)
corrade_add_test(TradeLightDataTest LightDataTest.cpp LIBRARIES MagnumTrade)
corrade_add_test(TradeMaterialDataTest MaterialDataTest.cpp LIBRARIES MagnumTrade)
corrade_add_test(TradeMeshData2DTest MeshData2DTest.cpp LIBRARIES MagnumTrade)

476
src/Magnum/Trade/Test/ImageDataTest.cpp

@ -23,6 +23,7 @@
DEALINGS IN THE SOFTWARE.
*/
#include <sstream>
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/PixelFormat.h"
@ -33,60 +34,250 @@ namespace Magnum { namespace Trade { namespace Test {
struct ImageDataTest: TestSuite::Tester {
explicit ImageDataTest();
void construct();
void constructCompressed();
void constructGeneric();
void constructImplementationSpecific();
void constructCompressedGeneric();
void constructCompressedImplementationSpecific();
void constructInvalidSize();
void constructCompressedInvalidSize();
void constructCopy();
void constructMove();
void constructMoveCompressed();
void toView();
void toViewCompressed();
void constructMoveGeneric();
void constructMoveImplementationSpecific();
void constructMoveCompressedGeneric();
void constructMoveCompressedImplementationSpecific();
void toViewGeneric();
void toViewImplementationSpecific();
void toViewCompressedGeneric();
void toViewCompressedImplementationSpecific();
void access();
void release();
void releaseCompressed();
};
ImageDataTest::ImageDataTest() {
addTests({&ImageDataTest::construct,
&ImageDataTest::constructCompressed,
addTests({&ImageDataTest::constructGeneric,
&ImageDataTest::constructImplementationSpecific,
&ImageDataTest::constructCompressedGeneric,
&ImageDataTest::constructCompressedImplementationSpecific,
&ImageDataTest::constructInvalidSize,
&ImageDataTest::constructCompressedInvalidSize,
&ImageDataTest::constructCopy,
&ImageDataTest::constructMove,
&ImageDataTest::constructMoveCompressed,
&ImageDataTest::toView,
&ImageDataTest::toViewCompressed,
&ImageDataTest::constructMoveGeneric,
&ImageDataTest::constructMoveImplementationSpecific,
&ImageDataTest::constructMoveCompressedGeneric,
&ImageDataTest::constructMoveCompressedImplementationSpecific,
&ImageDataTest::toViewGeneric,
&ImageDataTest::toViewImplementationSpecific,
&ImageDataTest::toViewCompressedGeneric,
&ImageDataTest::toViewCompressedImplementationSpecific,
&ImageDataTest::access,
&ImageDataTest::release,
&ImageDataTest::releaseCompressed});
}
void ImageDataTest::construct() {
auto data = new char[3*3];
Trade::ImageData2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB, PixelType::UnsignedByte, {1, 3}, Containers::Array<char>{data, 3*3}};
namespace {
CORRADE_VERIFY(!a.isCompressed());
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::RGB);
CORRADE_COMPARE(a.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(a.size(), Vector2i(1, 3));
CORRADE_COMPARE(a.data(), data);
namespace GL {
enum class PixelFormat { RGB = 666 };
enum class PixelType { UnsignedShort = 1337 };
UnsignedInt pixelSize(PixelFormat format, PixelType type) {
CORRADE_INTERNAL_ASSERT(format == PixelFormat::RGB);
CORRADE_INTERNAL_ASSERT(type == PixelType::UnsignedShort);
return 6;
}
enum class CompressedPixelFormat { RGBS3tcDxt1 = 21 };
}
namespace Vk {
enum class PixelFormat { R32G32B32F = 42 };
UnsignedInt pixelSize(PixelFormat format) {
CORRADE_INTERNAL_ASSERT(format == PixelFormat::R32G32B32F);
return 12;
}
enum class CompressedPixelFormat { Bc1SRGBAlpha = 42 };
}
void ImageDataTest::constructCompressed() {
auto data = new char[8];
Trade::ImageData2D a{
#ifndef MAGNUM_TARGET_GLES
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
CORRADE_VERIFY(a.isCompressed());
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(a.compressedStorage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_COMPARE(a.compressedFormat(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(a.size(), Vector2i(4, 4));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
}
void ImageDataTest::constructGeneric() {
{
auto data = new char[4*4];
int state;
ImageData2D a{PixelFormat::RGBA8Unorm, {1, 3}, Containers::Array<char>{data, 4*4}, &state};
CORRADE_VERIFY(!a.isCompressed());
CORRADE_COMPARE(a.storage().alignment(), 4);
CORRADE_COMPARE(a.format(), PixelFormat::RGBA8Unorm);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 4);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 4*4);
CORRADE_COMPARE(a.importerState(), &state);
} {
auto data = new char[3*2];
int state;
ImageData2D a{PixelStorage{}.setAlignment(1),
PixelFormat::R16UI, {1, 3}, Containers::Array<char>{data, 3*2}, &state};
CORRADE_VERIFY(!a.isCompressed());
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), PixelFormat::R16UI);
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 2);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*2);
CORRADE_COMPARE(a.importerState(), &state);
}
}
void ImageDataTest::constructImplementationSpecific() {
/* Single format */
{
auto data = new char[3*12];
int state;
ImageData2D a{PixelStorage{}.setAlignment(1),
Vk::PixelFormat::R32G32B32F, {1, 3}, Containers::Array<char>{data, 3*12}, &state};
CORRADE_VERIFY(!a.isCompressed());
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(Vk::PixelFormat::R32G32B32F));
CORRADE_COMPARE(a.formatExtra(), 0);
CORRADE_COMPARE(a.pixelSize(), 12);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*12);
CORRADE_COMPARE(a.importerState(), &state);
}
/* Format + extra */
{
auto data = new char[3*6];
int state;
ImageData2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, Containers::Array<char>{data, 3*6}, &state};
CORRADE_VERIFY(!a.isCompressed());
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*6);
CORRADE_COMPARE(a.importerState(), &state);
}
/* Manual pixel size */
{
auto data = new char[3*6];
int state;
ImageData2D a{PixelStorage{}.setAlignment(1), 666, 1337, 6, {1, 3}, Containers::Array<char>{data, 3*6}, &state};
CORRADE_VERIFY(!a.isCompressed());
CORRADE_COMPARE(a.storage().alignment(), 1);
CORRADE_COMPARE(a.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(a.formatExtra(), UnsignedInt(GL::PixelType::UnsignedShort));
CORRADE_COMPARE(a.pixelSize(), 6);
CORRADE_COMPARE(a.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 3*6);
CORRADE_COMPARE(a.importerState(), &state);
}
}
void ImageDataTest::constructCompressedGeneric() {
{
auto data = new char[8];
int state;
ImageData2D a{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4},
Containers::Array<char>{data, 8}, &state};
CORRADE_VERIFY(a.isCompressed());
CORRADE_COMPARE(a.compressedStorage().compressedBlockSize(), Vector3i{0});
CORRADE_COMPARE(a.compressedFormat(), CompressedPixelFormat::Bc1RGBAUnorm);
CORRADE_COMPARE(a.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
CORRADE_COMPARE(a.importerState(), &state);
} {
auto data = new char[8];
int state;
ImageData2D a{CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
CompressedPixelFormat::Bc1RGBAUnorm, {4, 4},
Containers::Array<char>{data, 8}, &state};
CORRADE_VERIFY(a.isCompressed());
CORRADE_COMPARE(a.compressedStorage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(a.compressedFormat(), CompressedPixelFormat::Bc1RGBAUnorm);
CORRADE_COMPARE(a.size(), Vector2i(4, 4));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
CORRADE_COMPARE(a.importerState(), &state);
}
}
void ImageDataTest::constructCompressedImplementationSpecific() {
/* Format with autodetection */
{
auto data = new char[8];
int state;
ImageData2D a{CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4},
Containers::Array<char>{data, 8}, &state};
CORRADE_VERIFY(a.isCompressed());
CORRADE_COMPARE(a.compressedStorage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(a.compressedFormat(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(a.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(a.data().size(), 8);
CORRADE_COMPARE(a.importerState(), &state);
}
/* Manual properties not implemented yet */
}
void ImageDataTest::constructInvalidSize() {
std::ostringstream out;
Error redirectError{&out};
/* Doesn't consider alignment */
ImageData2D{PixelFormat::RGB8Unorm, {1, 3}, Containers::Array<char>{3*3}};
CORRADE_COMPARE(out.str(), "Trade::ImageData::ImageData(): data too small, got 9 but expected at least 12 bytes\n");
}
void ImageDataTest::constructCompressedInvalidSize() {
CORRADE_EXPECT_FAIL("Size checking for compressed image data is not implemented yet.");
/* Too small for given format */
{
std::ostringstream out;
Error redirectError{&out};
ImageData2D{CompressedPixelFormat::Bc2RGBAUnorm, {4, 4}, Containers::Array<char>{2}};
CORRADE_COMPARE(out.str(), "Trade::ImageData::ImageData(): data too small, got 2 but expected at least 4 bytes\n");
/* Size should be rounded up even if the image size is not full block */
} {
std::ostringstream out;
Error redirectError{&out};
ImageData2D{CompressedPixelFormat::Bc2RGBAUnorm, {2, 2}, Containers::Array<char>{2}};
CORRADE_COMPARE(out.str(), "Trade::ImageData::ImageData(): data too small, got 2 but expected at least 4 bytes\n");
}
}
void ImageDataTest::constructCopy() {
@ -94,24 +285,67 @@ void ImageDataTest::constructCopy() {
CORRADE_VERIFY(!(std::is_assignable<Trade::ImageData2D, const Trade::ImageData2D&>{}));
}
void ImageDataTest::constructMove() {
auto data = new char[3*3];
Trade::ImageData2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB, PixelType::UnsignedByte, {1, 3}, Containers::Array<char>{data, 3*3}};
Trade::ImageData2D b(std::move(a));
void ImageDataTest::constructMoveGeneric() {
auto data = new char[3*16];
int state;
ImageData2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGBA32F, {1, 3}, Containers::Array<char>{data, 3*16}, &state};
ImageData2D b(std::move(a));
CORRADE_COMPARE(a.data(), nullptr);
CORRADE_COMPARE(a.size(), Vector2i());
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_VERIFY(!b.isCompressed());
CORRADE_COMPARE(b.storage().alignment(), 1);
CORRADE_COMPARE(b.format(), PixelFormat::RGB);
CORRADE_COMPARE(b.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(b.size(), Vector2i(1, 3));
CORRADE_COMPARE(b.format(), PixelFormat::RGBA32F);
CORRADE_COMPARE(b.formatExtra(), 0);
CORRADE_COMPARE(b.pixelSize(), 16);
CORRADE_COMPARE(b.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(b.data(), data);
CORRADE_COMPARE(b.data().size(), 3*16);
CORRADE_COMPARE(b.importerState(), &state);
auto data2 = new char[2*2*6*4];
Trade::ImageData2D c{PixelFormat::RGBA, PixelType::UnsignedShort, {2, 6}, Containers::Array<char>{data2, 2*2*6*4}};
auto data2 = new char[24];
ImageData2D c{PixelFormat::R8I, {2, 6}, Containers::Array<char>{data2, 24}};
c = std::move(b);
CORRADE_COMPARE(b.data(), data2);
CORRADE_COMPARE(b.size(), (Vector2i{2, 6}));
CORRADE_VERIFY(!c.isCompressed());
CORRADE_COMPARE(c.storage().alignment(), 1);
CORRADE_COMPARE(c.format(), PixelFormat::RGBA32F);
CORRADE_COMPARE(c.formatExtra(), 0);
CORRADE_COMPARE(c.pixelSize(), 16);
CORRADE_COMPARE(c.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(c.data(), data);
CORRADE_COMPARE(c.data().size(), 3*16);
CORRADE_COMPARE(c.importerState(), &state);
}
void ImageDataTest::constructMoveImplementationSpecific() {
auto data = new char[3*6];
int state;
ImageData2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, Containers::Array<char>{data, 3*6}, &state};
ImageData2D b(std::move(a));
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(), &state);
auto data2 = new char[12*4*2];
ImageData2D c{PixelStorage{},
1, 2, 8, {2, 6}, Containers::Array<char>{data2, 12*4*2}};
c = std::move(b);
CORRADE_COMPARE(b.data(), data2);
@ -119,78 +353,152 @@ void ImageDataTest::constructMove() {
CORRADE_VERIFY(!c.isCompressed());
CORRADE_COMPARE(c.storage().alignment(), 1);
CORRADE_COMPARE(c.format(), PixelFormat::RGB);
CORRADE_COMPARE(c.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(c.size(), Vector2i(1, 3));
CORRADE_COMPARE(c.format(), pixelFormatWrap(GL::PixelFormat::RGB));
CORRADE_COMPARE(c.formatExtra(), 1337);
CORRADE_COMPARE(c.pixelSize(), 6);
CORRADE_COMPARE(c.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(c.data(), data);
CORRADE_COMPARE(c.data().size(), 3*6);
CORRADE_COMPARE(c.importerState(), &state);
}
void ImageDataTest::constructMoveCompressed() {
void ImageDataTest::constructMoveCompressedGeneric() {
auto data = new char[8];
Trade::ImageData2D a{
#ifndef MAGNUM_TARGET_GLES
int state;
ImageData2D a{
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
#endif
CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
Trade::ImageData2D b{std::move(a)};
CompressedPixelFormat::Bc3RGBAUnorm, {4, 4}, Containers::Array<char>{data, 8}, &state};
ImageData2D b{std::move(a)};
CORRADE_COMPARE(a.data(), nullptr);
CORRADE_COMPARE(a.size(), Vector2i());
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_VERIFY(b.isCompressed());
CORRADE_COMPARE(b.compressedStorage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(b.compressedFormat(), CompressedPixelFormat::Bc3RGBAUnorm);
CORRADE_COMPARE(b.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(b.data(), data);
CORRADE_COMPARE(b.data().size(), 8);
CORRADE_COMPARE(b.importerState(), &state);
auto data2 = new char[16];
ImageData2D c{CompressedPixelFormat::Bc1RGBAUnorm, {8, 4}, Containers::Array<char>{data2, 16}};
c = std::move(b);
CORRADE_COMPARE(b.data(), data2);
CORRADE_COMPARE(b.size(), (Vector2i{8, 4}));
CORRADE_VERIFY(c.isCompressed());
CORRADE_COMPARE(c.compressedStorage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(c.compressedFormat(), CompressedPixelFormat::Bc3RGBAUnorm);
CORRADE_COMPARE(c.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(c.data(), data);
CORRADE_COMPARE(c.data().size(), 8);
CORRADE_COMPARE(c.importerState(), &state);
}
void ImageDataTest::constructMoveCompressedImplementationSpecific() {
auto data = new char[8];
int state;
ImageData2D a{
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}, &state};
ImageData2D b{std::move(a)};
CORRADE_COMPARE(a.data(), nullptr);
CORRADE_COMPARE(a.size(), Vector2i{});
CORRADE_VERIFY(b.isCompressed());
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(b.compressedStorage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_COMPARE(b.compressedFormat(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(b.size(), Vector2i(4, 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(), &state);
auto data2 = new char[16];
Trade::ImageData2D c{CompressedPixelFormat::RGBAS3tcDxt3, {8, 4}, Containers::Array<char>{data2, 16}};
ImageData2D c{CompressedPixelFormat::Bc2RGBAUnorm, {8, 4}, Containers::Array<char>{data2, 16}};
c = std::move(b);
CORRADE_COMPARE_AS(b.data(), data2, char*);
CORRADE_COMPARE(b.data().size(), 16);
CORRADE_COMPARE(b.size(), Vector2i(8, 4));
CORRADE_COMPARE(b.data(), data2);
CORRADE_COMPARE(b.size(), (Vector2i{8, 4}));
CORRADE_VERIFY(c.isCompressed());
#ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(c.compressedStorage().compressedBlockSize(), Vector3i{4});
#endif
CORRADE_COMPARE(c.compressedFormat(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(c.size(), Vector2i(4, 4));
CORRADE_COMPARE(c.compressedFormat(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(c.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(c.data(), data);
CORRADE_COMPARE(c.data().size(), 8);
CORRADE_COMPARE(c.importerState(), &state);
}
void ImageDataTest::toView() {
auto data = new char[3*3];
const Trade::ImageData2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RGB, PixelType::UnsignedByte, {1, 3}, Containers::Array<char>{data, 3*3}};
void ImageDataTest::toViewGeneric() {
auto data = new char[3*4];
const ImageData2D a{PixelStorage{}.setAlignment(1),
PixelFormat::RG16I, {1, 3}, Containers::Array<char>{data, 3*4}};
ImageView2D b = a;
CORRADE_COMPARE(b.storage().alignment(), 1);
CORRADE_COMPARE(b.format(), PixelFormat::RGB);
CORRADE_COMPARE(b.type(), PixelType::UnsignedByte);
CORRADE_COMPARE(b.size(), Vector2i(1, 3));
CORRADE_COMPARE(b.format(), PixelFormat::RG16I);
CORRADE_COMPARE(b.formatExtra(), 0);
CORRADE_COMPARE(b.pixelSize(), 4);
CORRADE_COMPARE(b.size(), (Vector2i{1, 3}));
CORRADE_COMPARE(b.data(), data);
}
void ImageDataTest::toViewImplementationSpecific() {
auto data = new char[3*6];
const ImageData2D a{PixelStorage{}.setAlignment(1),
GL::PixelFormat::RGB, GL::PixelType::UnsignedShort, {1, 3}, Containers::Array<char>{data, 3*6}};
ImageView2D b = a;
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);
}
void ImageDataTest::toViewCompressedGeneric() {
auto data = new char[8];
const ImageData2D a{
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
CompressedPixelFormat::Bc1RGBUnorm, {4, 4}, Containers::Array<char>{data, 8}};
CompressedImageView2D b = a;
CORRADE_COMPARE(b.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(b.format(), CompressedPixelFormat::Bc1RGBUnorm);
CORRADE_COMPARE(b.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(b.data(), data);
CORRADE_COMPARE(b.data().size(), 8);
}
void ImageDataTest::toViewCompressed() {
void ImageDataTest::toViewCompressedImplementationSpecific() {
auto data = new char[8];
const Trade::ImageData2D a{CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
const ImageData2D a{
CompressedPixelStorage{}.setCompressedBlockSize(Vector3i{4}),
GL::CompressedPixelFormat::RGBS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
CompressedImageView2D b = a;
CORRADE_COMPARE(b.format(), CompressedPixelFormat::RGBAS3tcDxt1);
CORRADE_COMPARE(b.size(), Vector2i(4, 4));
CORRADE_COMPARE(b.storage().compressedBlockSize(), Vector3i{4});
CORRADE_COMPARE(b.format(), compressedPixelFormatWrap(GL::CompressedPixelFormat::RGBS3tcDxt1));
CORRADE_COMPARE(b.size(), (Vector2i{4, 4}));
CORRADE_COMPARE(b.data(), data);
CORRADE_COMPARE(b.data().size(), 8);
}
void ImageDataTest::access() {
auto data = new char[4*4];
ImageData2D a{PixelFormat::RGBA8Unorm, {1, 3}, Containers::Array<char>{data, 4*4}};
const ImageData2D& ca = a;
CORRADE_COMPARE(a.data(), data);
CORRADE_COMPARE(ca.data(), data);
}
void ImageDataTest::release() {
char data[] = {'b', 'e', 'e', 'r'};
Trade::ImageData2D a{PixelFormat::RGBA, PixelType::UnsignedByte, {1, 1}, Containers::Array<char>{data, 4}};
Trade::ImageData2D a{PixelFormat::RGBA8Unorm, {1, 1}, Containers::Array<char>{data, 4}};
const char* const pointer = a.release().release();
CORRADE_COMPARE(pointer, data);
@ -200,7 +508,7 @@ void ImageDataTest::release() {
void ImageDataTest::releaseCompressed() {
char data[8];
Trade::ImageData2D a{CompressedPixelFormat::RGBAS3tcDxt1, {4, 4}, Containers::Array<char>{data, 8}};
Trade::ImageData2D a{CompressedPixelFormat::Bc1RGBAUnorm, {4, 4}, Containers::Array<char>{data, 8}};
const char* const pointer = a.release().release();
CORRADE_COMPARE(pointer, data);

2
src/Magnum/Trade/visibility.h

@ -31,7 +31,7 @@
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_BUILD_STATIC
#ifdef MagnumTrade_EXPORTS
#if defined(MagnumTrade_EXPORTS) || defined(MagnumTradeObjects_EXPORTS)
#define MAGNUM_TRADE_EXPORT CORRADE_VISIBILITY_EXPORT
#else
#define MAGNUM_TRADE_EXPORT CORRADE_VISIBILITY_IMPORT

2
src/Magnum/visibility.h

@ -31,7 +31,7 @@
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_BUILD_STATIC
#if defined(Magnum_EXPORTS) || defined(MagnumMathObjects_EXPORTS)
#if defined(Magnum_EXPORTS) || defined(MagnumObjects_EXPORTS) || defined(MagnumMathObjects_EXPORTS)
#define MAGNUM_EXPORT CORRADE_VISIBILITY_EXPORT
#else
#define MAGNUM_EXPORT CORRADE_VISIBILITY_IMPORT

Loading…
Cancel
Save