Skip to content

Commit

Permalink
Introduce ImageFlags to annotate cube map and array images.
Browse files Browse the repository at this point in the history
With the intention that those will eventually contain also things like
YUp / YDown, PremultipliedAlpha and such.

This commit is mostly just busywork, wiring this into [Compressed]Image,
[Compressed]ImageView and Trade::ImageData and ensuring the flags get
correctly propagated during moves and conversions. Unfortunately in case
of Trade::ImageData it meant deprecating the current set of constructor
in order to insert an ImageFlags parameter before the importer state
pointer.

The only non-trivial piece of logic is when a 2D
[Compressed]ImageView gets converted to a 3D one, then the Array bit is
implicitly dropped, as 2D arrays of 1D images are not really a thing.
Instead, it's now possible to add new flags when doing the conversion --
for example to turn a 2D image to a (single-layer) 2D array image.
  • Loading branch information
mosra committed Jun 27, 2022
1 parent e422a8a commit f14e15c
Show file tree
Hide file tree
Showing 18 changed files with 1,332 additions and 269 deletions.
8 changes: 8 additions & 0 deletions doc/changelog.dox
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,9 @@ See also:
@ref CompressedImageView::size() as well as @ref Trade::ImageData::size()
now return a @cpp const& @ce instead of a value to allow creating a
@relativeref{Corrade,Containers::StridedArrayView} slice onto this member.
- @ref Image, @ref CompressedImage, @ref ImageView, @ref CompressedImageView
as well as @ref Trade::ImageData are now able to annotate array, cube map
and cube map array images using @ref ImageFlags

@subsubsection changelog-latest-changes-debugtools DebugTools library

Expand Down Expand Up @@ -916,6 +919,11 @@ See also:
changed to have input first and output second, for consistency with other
interfaces, together with a switch to @ref Containers::StringView. The
original signature is marked as deprecated.
- Due to introduction of @ref ImageFlags, @ref Trade::ImageData constructors
that were taking @cpp const void* importerState @ce as the last parameter
are now deprecated in favor of constructors that take @ref ImageFlags *and*
`importerState`. Code that wasn't passing the `importerState` parameter
isn't affected by this change.
- @cpp Trade::TextureData::Type @ce was deprecated in favor of
@ref Trade::TextureType that is much less annoying to type, in addition
@cpp Trade::TextureData::Type::Cube @ce was deprecated in favor of
Expand Down
2 changes: 2 additions & 0 deletions src/Magnum/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake
# Files shared between main library and unit test library
set(Magnum_SRCS
FileCallback.cpp
ImageFlags.cpp
PixelStorage.cpp
Resource.cpp
Sampler.cpp
Expand All @@ -95,6 +96,7 @@ set(Magnum_HEADERS
DimensionTraits.h
FileCallback.h
Image.h
ImageFlags.h
ImageView.h
Magnum.h
Mesh.h
Expand Down
31 changes: 20 additions & 11 deletions src/Magnum/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@

namespace Magnum {

template<UnsignedInt dimensions> Image<dimensions>::Image(const PixelStorage storage, const PixelFormat format, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data) noexcept: Image{storage, format, {}, pixelFormatSize(format), size, std::move(data)} {}
template<UnsignedInt dimensions> Image<dimensions>::Image(const PixelStorage storage, const PixelFormat format, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data, const ImageFlags<dimensions> flags) noexcept: Image{storage, format, {}, pixelFormatSize(format), size, std::move(data), flags} {}

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 UnsignedInt format, const UnsignedInt formatExtra, const UnsignedInt pixelSize, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data, const ImageFlags<dimensions> flags) noexcept: Image{storage, pixelFormatWrap(format), formatExtra, pixelSize, size, std::move(data), flags} {}

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)} {
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, const ImageFlags<dimensions> flags) noexcept: _storage{storage}, _format{format}, _formatExtra{formatExtra}, _pixelSize{pixelSize}, _flags{flags}, _size{size}, _data{std::move(data)} {
CORRADE_ASSERT(Implementation::imageDataSize(*this) <= _data.size(), "Image: data too small, got" << _data.size() << "but expected at least" << Implementation::imageDataSize(*this) << "bytes", );
#ifndef CORRADE_NO_ASSERT
Implementation::checkImageFlagsForSize("Image:", flags, size);
#endif
}

template<UnsignedInt dimensions> Image<dimensions>::Image(const PixelStorage storage, const PixelFormat format) noexcept: Image{storage, format, {}, pixelFormatSize(format)} {}
Expand All @@ -45,7 +48,7 @@ template<UnsignedInt dimensions> Image<dimensions>::Image(const PixelStorage sto

template<UnsignedInt dimensions> Image<dimensions>::Image(const PixelStorage storage, const PixelFormat format, const UnsignedInt formatExtra, const UnsignedInt pixelSize) noexcept: _storage{storage}, _format{format}, _formatExtra{formatExtra}, _pixelSize{pixelSize}, _data{} {}

template<UnsignedInt dimensions> Image<dimensions>::Image(Image<dimensions>&& other) noexcept: _storage{std::move(other._storage)}, _format{std::move(other._format)}, _formatExtra{std::move(other._formatExtra)}, _pixelSize{std::move(other._pixelSize)}, _size{std::move(other._size)}, _data{std::move(other._data)} {
template<UnsignedInt dimensions> Image<dimensions>::Image(Image<dimensions>&& other) noexcept: _storage{std::move(other._storage)}, _format{std::move(other._format)}, _formatExtra{std::move(other._formatExtra)}, _pixelSize{std::move(other._pixelSize)}, _flags{std::move(other._flags)}, _size{std::move(other._size)}, _data{std::move(other._data)} {
other._size = {};
}

Expand All @@ -55,17 +58,18 @@ template<UnsignedInt dimensions> Image<dimensions>& Image<dimensions>::operator=
swap(_format, other._format);
swap(_formatExtra, other._formatExtra);
swap(_pixelSize, other._pixelSize);
swap(_flags, other._flags);
swap(_size, other._size);
swap(_data, other._data);
return *this;
}

template<UnsignedInt dimensions> Image<dimensions>::operator BasicMutableImageView<dimensions>() {
return BasicMutableImageView<dimensions>{_storage, _format, _formatExtra, _pixelSize, _size, _data};
return BasicMutableImageView<dimensions>{_storage, _format, _formatExtra, _pixelSize, _size, _data, _flags};
}

template<UnsignedInt dimensions> Image<dimensions>::operator BasicImageView<dimensions>() const {
return BasicImageView<dimensions>{_storage, _format, _formatExtra, _pixelSize, _size, _data};
return BasicImageView<dimensions>{_storage, _format, _formatExtra, _pixelSize, _size, _data, _flags};
}

template<UnsignedInt dimensions> std::pair<VectorTypeFor<dimensions, std::size_t>, VectorTypeFor<dimensions, std::size_t>> Image<dimensions>::dataProperties() const {
Expand All @@ -86,13 +90,17 @@ template<UnsignedInt dimensions> Containers::Array<char> Image<dimensions>::rele
return data;
}

template<UnsignedInt dimensions> CompressedImage<dimensions>::CompressedImage(const CompressedPixelStorage storage, const CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data) noexcept: _storage{storage}, _format{format}, _size{size}, _data{std::move(data)} {}
template<UnsignedInt dimensions> CompressedImage<dimensions>::CompressedImage(const CompressedPixelStorage storage, const CompressedPixelFormat format, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data, const ImageFlags<dimensions> flags) noexcept: _storage{storage}, _format{format}, _flags{flags}, _size{size}, _data{std::move(data)} {
#ifndef CORRADE_NO_ASSERT
Implementation::checkImageFlagsForSize("CompressedImage:", flags, size);
#endif
}

template<UnsignedInt dimensions> CompressedImage<dimensions>::CompressedImage(const CompressedPixelStorage storage, const UnsignedInt format, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data) noexcept: CompressedImage{storage, compressedPixelFormatWrap(format), size, std::move(data)} {}
template<UnsignedInt dimensions> CompressedImage<dimensions>::CompressedImage(const CompressedPixelStorage storage, const UnsignedInt format, const VectorTypeFor<dimensions, Int>& size, Containers::Array<char>&& data, const ImageFlags<dimensions> flags) noexcept: CompressedImage{storage, compressedPixelFormatWrap(format), size, std::move(data), flags} {}

template<UnsignedInt dimensions> CompressedImage<dimensions>::CompressedImage(const CompressedPixelStorage storage) noexcept: _storage{storage}, _format{} {}

template<UnsignedInt dimensions> CompressedImage<dimensions>::CompressedImage(CompressedImage<dimensions>&& other) noexcept: _storage{std::move(other._storage)}, _format{std::move(other._format)}, _size{std::move(other._size)}, _data{std::move(other._data)}
template<UnsignedInt dimensions> CompressedImage<dimensions>::CompressedImage(CompressedImage<dimensions>&& other) noexcept: _storage{std::move(other._storage)}, _format{std::move(other._format)}, _flags{other._flags}, _size{std::move(other._size)}, _data{std::move(other._data)}
{
other._size = {};
}
Expand All @@ -101,17 +109,18 @@ template<UnsignedInt dimensions> CompressedImage<dimensions>& CompressedImage<di
using std::swap;
swap(_storage, other._storage);
swap(_format, other._format);
swap(_flags, other._flags);
swap(_size, other._size);
swap(_data, other._data);
return *this;
}

template<UnsignedInt dimensions> CompressedImage<dimensions>::operator BasicMutableCompressedImageView<dimensions>() {
return BasicMutableCompressedImageView<dimensions>{_storage, _format, _size, _data};
return BasicMutableCompressedImageView<dimensions>{_storage, _format, _size, _data, _flags};
}

template<UnsignedInt dimensions> CompressedImage<dimensions>::operator BasicCompressedImageView<dimensions>() const {
return BasicCompressedImageView<dimensions>{_storage, _format, _size, _data};
return BasicCompressedImageView<dimensions>{_storage, _format, _size, _data, _flags};
}

template<UnsignedInt dimensions> std::pair<VectorTypeFor<dimensions, std::size_t>, VectorTypeFor<dimensions, std::size_t>> CompressedImage<dimensions>::dataProperties() const {
Expand Down
Loading

0 comments on commit f14e15c

Please sign in to comment.