Browse Source

Improve docs of image classes.

It looked like it was last touched in 2012. Not great. Also, with this I
can finally stop explaining the four-byte-aligned-row defaults to people
and can just point them to docs.
pull/620/head
Vladimír Vondruš 3 years ago
parent
commit
fe0a46abad
  1. 75
      doc/snippets/Magnum.cpp
  2. 65
      doc/snippets/MagnumTrade.cpp
  3. 60
      src/Magnum/Image.h
  4. 57
      src/Magnum/ImageView.h
  5. 82
      src/Magnum/Trade/ImageData.h

75
doc/snippets/Magnum.cpp

@ -113,7 +113,7 @@ std::nullptr_t data = nullptr;
Image2D image{PixelFormat::RGB8Unorm, {128, 128}, data};
Containers::StridedArrayView2D<Color3ub> pixels = image.pixels<Color3ub>();
for(auto row: pixels.slice({48, 48}, {80, 80})) {
for(auto row: pixels.sliceSize({48, 48}, {32, 32})) {
for(Color3ub& pixel: row) pixel *= 1.1f;
}
/* [Image-pixels] */
@ -122,10 +122,23 @@ for(auto row: pixels.slice({48, 48}, {80, 80})) {
{
char data[3];
/* [ImageView-usage] */
ImageView2D image{PixelFormat::RGBA8Unorm, {512, 256}, data};
ImageView2D view{PixelFormat::RGBA8Unorm, {512, 256}, data};
/* [ImageView-usage] */
}
{
char tightlyPackedData[3];
/* [ImageView-usage-alignment] */
PixelFormat format = DOXYGEN_ELLIPSIS({});
Vector2i size = DOXYGEN_ELLIPSIS({});
std::size_t rowLength = size.x()*pixelFormatSize(format);
ImageView2D view{
PixelStorage{}.setAlignment(rowLength % 4 == 0 ? 4 : 1),
format, size, tightlyPackedData};
/* [ImageView-usage-alignment] */
}
{
char evenFrameData[3], oddFrameData[3];
/* [ImageView-usage-streaming] */
@ -142,10 +155,10 @@ frame.setData(oddFrameData);
{
char data[3];
/* [ImageView-usage-storage] */
ImageView2D image{
ImageView2D view{
PixelStorage{}
.setAlignment(1)
.setRowLength(75)
.setAlignment(4)
.setSkip({25, 25, 0}),
PixelFormat::RGBA8Unorm, {25, 25}, data};
/* [ImageView-usage-storage] */
@ -155,13 +168,13 @@ ImageView2D image{
{
char data[3];
/* [ImageView-usage-gl] */
ImageView2D image{GL::PixelFormat::DepthComponent,
GL::PixelType::UnsignedInt, {512, 256}, data};
ImageView2D view{GL::PixelFormat::DepthComponent,
GL::PixelType::UnsignedInt, {512, 256}, data};
/* [ImageView-usage-gl] */
/* [ImageView-usage-gl-extract] */
auto format = pixelFormatUnwrap<GLenum>(image.format());
auto type = GLenum(image.formatExtra());
auto format = pixelFormatUnwrap<GLenum>(view.format());
auto type = GLenum(view.formatExtra());
/* [ImageView-usage-gl-extract] */
static_cast<void>(format);
static_cast<void>(type);
@ -180,7 +193,7 @@ ImageView2D view{{}, MTLPixelFormatRGBA8Unorm_sRGB, {}, 4, {256, 256}, data};
{
char data[3];
/* [CompressedImageView-usage] */
CompressedImageView2D image{CompressedPixelFormat::Bc1RGBUnorm,
CompressedImageView2D view{CompressedPixelFormat::Bc1RGBUnorm,
{512, 256}, data};
/* [CompressedImageView-usage] */
}
@ -201,7 +214,7 @@ frame.setData(oddFrameData);
{
char data[3];
/* [CompressedImageView-usage-storage] */
CompressedImageView2D image{
CompressedImageView2D view{
CompressedPixelStorage{}
.setRowLength(64)
.setCompressedBlockSize({4, 4, 1})
@ -215,12 +228,12 @@ CompressedImageView2D image{
{
char data[3];
/* [CompressedImageView-usage-gl] */
CompressedImageView2D image{GL::CompressedPixelFormat::SignedRGRgtc2,
CompressedImageView2D view{GL::CompressedPixelFormat::SignedRGRgtc2,
{512, 256}, data};
/* [CompressedImageView-usage-gl] */
/* [CompressedImageView-usage-gl-extract] */
auto format = compressedPixelFormatUnwrap<GLenum>(image.format());
auto format = compressedPixelFormatUnwrap<GLenum>(view.format());
/* [CompressedImageView-usage-gl-extract] */
static_cast<void>(format);
}
@ -228,26 +241,50 @@ static_cast<void>(format);
{
/* [Image-usage] */
Containers::Array<char> data;
Image2D image{PixelFormat::RGBA8Unorm, {512, 256}, std::move(data)};
Vector2i size{512, 256};
PixelFormat format = PixelFormat::RGBA8Unorm;
Image2D image{format, size, Containers::Array<char>{ValueInit,
std::size_t(size.product()*pixelFormatSize(format))}};
/* [Image-usage] */
}
{
/* [Image-usage-padding] */
PixelFormat format = PixelFormat::RGB8Unorm;
Vector2i size{173, 232};
std::size_t rowStride = 4*((size.x()*pixelFormatSize(format) + 3)/4);
Image2D image{format, size,
Containers::Array<char>{ValueInit, std::size_t(size.y()*rowStride)}};
/* [Image-usage-padding] */
}
{
/* [Image-usage-alignment] */
Vector2i size{173, 232};
PixelFormat format = PixelFormat::RGB8Unorm;
std::size_t rowLength = size.x()*pixelFormatSize(format);
Image2D image{
PixelStorage{}.setAlignment(rowLength % 4 == 0 ? 4 : 1), format, size,
Containers::Array<char>{ValueInit, std::size_t(size.y()*rowLength)}};
/* [Image-usage-alignment] */
}
#if defined(MAGNUM_TARGET_GL) && !defined(MAGNUM_TARGET_GLES)
{
/* [Image-usage-query] */
GL::Texture2D texture;
Image2D image = texture.image(0, {GL::PixelFormat::DepthComponent,
GL::PixelType::UnsignedInt});
Image2D image = texture.image(0, Image2D{PixelFormat::Depth32F});
/* [Image-usage-query] */
}
#endif
{
/* [CompressedImage-usage] */
Containers::Array<char> data;
CompressedImage2D image{CompressedPixelFormat::Bc1RGBUnorm,
{512, 256}, std::move(data)};
{512, 256}, Containers::Array<char>{ValueInit, DOXYGEN_ELLIPSIS(0)}};
/* [CompressedImage-usage] */
}
@ -255,7 +292,7 @@ CompressedImage2D image{CompressedPixelFormat::Bc1RGBUnorm,
{
/* [CompressedImage-usage-query] */
GL::Texture2D texture;
CompressedImage2D image = texture.compressedImage(0, {});
CompressedImage2D image = texture.compressedImage(0, CompressedImage2D{});
/* [CompressedImage-usage-query] */
}
#endif

65
doc/snippets/MagnumTrade.cpp

@ -415,34 +415,67 @@ for(UnsignedInt i = 0; i != data.trackCount(); ++i) {
}
{
/* [ImageData-construction] */
Containers::Array<char> data;
Trade::ImageData2D image{PixelFormat::RGB8Unorm, {32, 32}, std::move(data)};
/* [ImageData-construction] */
/* [ImageData-populating] */
Containers::Array<char> uncompressedData = DOXYGEN_ELLIPSIS({});
Trade::ImageData2D uncompressed{PixelFormat::RGB8Unorm,
{32, 32}, std::move(uncompressedData)};
Containers::Array<char> compressedData = DOXYGEN_ELLIPSIS({});
Trade::ImageData2D compressed{CompressedPixelFormat::Bc1RGBUnorm,
{32, 32}, std::move(compressedData)};
/* [ImageData-populating] */
}
{
/* [ImageData-populating-non-owned] */
Color3ub uncompressedData[]{DOXYGEN_ELLIPSIS({})};
Trade::ImageData2D uncompressed{PixelFormat::RGB8Unorm,
{32, 32}, Trade::DataFlag::Mutable, uncompressedData};
Containers::ArrayView<const char> compressedData = DOXYGEN_ELLIPSIS({});
Trade::ImageData2D compressed{CompressedPixelFormat::Bc1RGBUnorm,
{32, 32}, Trade::DataFlags{}, compressedData};
/* [ImageData-populating-non-owned] */
}
{
/* [ImageData-populating-padding] */
PixelFormat format = DOXYGEN_ELLIPSIS({});
Vector2i size = DOXYGEN_ELLIPSIS({});
std::size_t rowStride = 4*((size.x()*pixelFormatSize(format) + 3)/4);
Containers::Array<char> data{ValueInit, std::size_t(size.y()*rowStride)};
DOXYGEN_ELLIPSIS()
Trade::ImageData2D image{format, size, std::move(data)};
/* [ImageData-populating-padding] */
}
{
/* [ImageData-construction-compressed] */
Containers::Array<char> data;
Trade::ImageData2D image{CompressedPixelFormat::Bc1RGBUnorm,
{32, 32}, std::move(data)};
/* [ImageData-construction-compressed] */
/* [ImageData-populating-alignment] */
PixelFormat format = DOXYGEN_ELLIPSIS({});
Vector2i size = DOXYGEN_ELLIPSIS({});
std::size_t rowLength = size.x()*pixelFormatSize(format);
Containers::Array<char> data{ValueInit, std::size_t(size.y()*rowLength)};
DOXYGEN_ELLIPSIS()
Trade::ImageData2D image{
PixelStorage{}.setAlignment(rowLength % 4 == 0 ? 4 : 1),
format, size, std::move(data)};
/* [ImageData-populating-alignment] */
}
#ifdef MAGNUM_TARGET_GL
{
/* [ImageData-usage] */
Containers::Pointer<Trade::AbstractImporter> importer;
Containers::Optional<Trade::ImageData2D> image = importer->image2D(0);
if(!image) Fatal{} << "Oopsie!";
Trade::ImageData2D image = DOXYGEN_ELLIPSIS(Trade::ImageData2D{PixelFormat{}, {}, nullptr});
GL::Texture2D texture;
DOXYGEN_ELLIPSIS()
texture.setStorage(1, GL::textureFormat(image->format()), image->size());
if(!image->isCompressed())
texture.setSubImage(0, {}, *image);
texture.setStorage(1, GL::textureFormat(image.format()), image.size());
if(!image.isCompressed())
texture.setSubImage(0, {}, image);
else
texture.setCompressedSubImage(0, {}, *image);
texture.setCompressedSubImage(0, {}, image);
/* [ImageData-usage] */
}
#endif

60
src/Magnum/Image.h

@ -62,19 +62,27 @@ functionality targeted on compressed image formats.
@section Image-usage Basic usage
The image takes ownership of a passed @ref Corrade::Containers::Array, together
with storing image size and one of the generic @ref PixelFormat values:
The image takes ownership of a passed @relativeref{Corrade,Containers::Array},
together with a @ref PixelFormat and size in pixels:
@snippet Magnum.cpp Image-usage
On construction, the image internally calculates pixel size corresponding to
given pixel format using @ref pixelFormatSize(). This value is needed to check
that the passed data array is large enough and is also required by most image
manipulation operations.
The constructor internally checks that the passed array is large enough. For
performance reasons it by default expects rows aligned to four bytes, which you
need to account for if using odd image sizes in combination with one-, two- or
three-component formats. The recommended way is to pad the row data to satisfy
the alignment:
@snippet Magnum.cpp Image-usage-padding
Alternatively, if padding is not possible or desirable, you can pass a
@ref PixelStorage instance with the alignment overriden to @cpp 1 @ce:
@snippet Magnum.cpp Image-usage-alignment
It's also possible to create just an image placeholder, storing only the image
properties without data or size. That is useful for example to specify desired
format of image queries in graphics APIs:
format of image queries in graphics APIs such as @ref GL::Texture::image():
@snippet Magnum.cpp Image-usage-query
@ -82,7 +90,7 @@ As with @ref ImageView, this class supports extra storage parameters and
implementation-specific pixel format specification. See the @ref ImageView
documentation for more information.
@section Image-pixel-views Obtaining a view on pixel data
@section Image-pixel-access Pixel data access
While the raw image data are available through @ref data(), for correct pixel
addressing it's required to incorporate all @ref storage() parameters such as
@ -90,30 +98,29 @@ row alignment, row length, skip offset and such. This is very error-prone to
do by hand even with the help of @ref dataProperties().
The @ref pixels() accessor returns a multi-dimensional
@ref Corrade::Containers::StridedArrayView describing layout of the data and
providing easy access to particular rows, pixels and pixel channels. The
non-templated version returns a view that has one dimension more than the
@relativeref{Corrade,Containers::StridedArrayView} describing layout of the
data and providing easy access to particular rows, pixels and pixel contents.
The non-templated version returns a view that has one dimension more than the
actual image, with the last dimension being bytes in a particular pixels. The
second-to-last dimension is always pixels in a row, the one before (if the
image is at least 2D) is rows in an image, and for 3D images the very first
dimension describes image slices. Desired usage is casting to a concrete type
based on @ref format() first, either using the templated @ref pixels<T>() or
using @ref Corrade::Containers::arrayCast() and then operating on the
using @relativeref{Corrade,Containers::arrayCast()} and then operating on the
concretely typed array. The following example brightens the center 32x32 area
of an image:
@snippet Magnum.cpp Image-pixels
@attention Note that the correctness of the cast is can't be generally checked
apart from expecting that the last dimension size is equal to the new type
size. It's the user responsibility to ensure the type matches given
@ref format().
This operation is available also on @ref ImageView and non-compressed
@ref Trade::ImageData. See @ref Corrade::Containers::StridedArrayView docs for
more information about transforming, slicing and converting the view further.
@attention Note that the correctness of the cast can't be generally checked
apart from comparing that the last dimension size to the type size. It's
the user responsibility to ensure the type matches given @ref format().
@see @ref Image1D, @ref Image2D, @ref Image3D, @ref CompressedImage
This operation is available also on a @ref ImageView, and non-compressed
@ref Trade::ImageData. See @relativeref{Corrade,Containers::StridedArrayView}
docs for more information about transforming, slicing and casting the view
further.
@see @ref Image1D, @ref Image2D, @ref Image3D
*/
template<UnsignedInt dimensions> class Image {
public:
@ -460,7 +467,7 @@ template<UnsignedInt dimensions> class Image {
* @m_since{2019,10}
*
* Provides direct and easy-to-use access to image pixels. See
* @ref Image-pixel-views for more information.
* @ref Image-pixel-access for more information.
*/
Containers::StridedArrayView<dimensions + 1, char> pixels();
Containers::StridedArrayView<dimensions + 1, const char> pixels() const; /**< @overload */
@ -472,7 +479,8 @@ template<UnsignedInt dimensions> class Image {
* Compared to non-templated @ref pixels() in addition casts the pixel
* data to a specified type. The user is responsible for choosing
* correct type for given @ref format() --- checking it on the library
* side is not possible for the general case.
* side is not possible for the general case. See also
* @ref Image-pixel-access for more information.
*/
template<class T> Containers::StridedArrayView<dimensions, T> pixels() {
/* Deliberately not adding a StridedArrayView include, it should
@ -535,9 +543,8 @@ for equivalent functionality targeted on non-compressed image formats.
@section CompressedImage-usage Basic usage
The image takes ownership of a passed @ref Corrade::Containers::Array, together
with storing image size and one of the generic @ref CompressedPixelFormat
values:
The image takes ownership of a passed @relativeref{Corrade,Containers::Array},
together with a @ref CompressedPixelFormat and size in pixels:
@snippet Magnum.cpp CompressedImage-usage
@ -550,7 +557,6 @@ format of image queries in graphics APIs:
As with @ref CompressedImageView, this class supports extra storage parameters
and implementation-specific compressed pixel format specification. See its
documentation for more information.
@see @ref CompressedImage1D, @ref CompressedImage2D, @ref CompressedImage3D
*/
template<UnsignedInt dimensions> class CompressedImage {

57
src/Magnum/ImageView.h

@ -66,16 +66,20 @@ functionality targeted on compressed image formats.
@section ImageView-usage Basic usage
Usually, the view is created on some pre-existing data array in order to
describe its layout, with pixel format being one of the values from the generic
@link PixelFormat @endlink:
The view is created from a @ref PixelFormat, size in pixels and a data view:
@snippet Magnum.cpp ImageView-usage
On construction, the image view internally calculates pixel size corresponding
to given pixel format using @ref pixelFormatSize(). This value is needed to
check that the passed data array is large enough and is also required by most
image manipulation operations.
The constructor internally checks that the passed array is large enough. For
performance reasons it by default expects rows aligned to four bytes, which you
need to account for if using odd image sizes in combination with one-, two- or
three-component formats. While the recommended way is to pad the row data to
satisfy the alignment similarly as shown in @ref Image-usage "Image usage docs",
but with views it's more likely that you have to adapt to a layout of an
existing data array by passing a @ref PixelStorage instance with the alignment
value overriden if needed:
@snippet Magnum.cpp ImageView-usage-alignment
It's also possible to create an empty view and assign the memory later. That is
useful for example in case of multi-buffered video streaming, where each frame
@ -83,25 +87,27 @@ has the same properties but a different memory location:
@snippet Magnum.cpp ImageView-usage-streaming
It's possible to have views on image sub-rectangles, 3D texture slices or
images with over-aligned rows by passing a particular @ref PixelStorage as
first parameter. In the following snippet, the view is the center 25x25
sub-rectangle of a 75x75 8-bit RGB image , with rows aligned to four bytes:
The @ref PixelStorage also allows for specifying arbitrary image slices by
passing appropriate row length, image height and skip parameters. In the
following snippet, the view is the center 25x25 sub-rectangle of a 75x75 8-bit
RGB image (with tightly packed rows again):
@snippet Magnum.cpp ImageView-usage-storage
Image views provides pixel data access via @ref pixels() in the same way as the
@ref Image class. See @ref Image-pixel-access "its documentation for more information".
@section ImageView-mutable Data mutability
When using types derived from @ref BasicImageView (e.g. @ref ImageView2D), the
viewed data are immutable. This is the most common use case. In order to be
able to mutate the underlying data (for example in order to read into a
pre-allocated memory), use @ref BasicMutableImageView
(e.g. @ref MutableImageView2D) instead. @ref Image and @ref Trade::ImageData
are convertible to either of these. Similarly to
@ref Corrade::Containers::ArrayView etc., a mutable view is also implicitly
convertible to a const one.
The @ref ImageView2D type and related one- and three-dimensional variants only
provide immutable access to the referenced data, as that's the most common use
case. In order to be able to modify the data (for example in order to read into
a pre-allocated memory), use @ref MutableImageView2D and friends instead.
@ref Image and @ref Trade::ImageData are convertible to either of these.
Similarly to @ref Corrade::Containers::ArrayView etc., a mutable view is also
implicitly convertible to a const one.
@subsection ImageView-usage-implementation-specific Implementation-specific formats
@section ImageView-usage-implementation-specific Implementation-specific formats
For known graphics APIs, there's a set of utility functions converting from
@ref PixelFormat to implementation-specific format identifiers and such
@ -138,7 +144,7 @@ image view using Metal-specific format identifier:
@see @ref BasicImageView, @ref ImageView1D, @ref ImageView2D, @ref ImageView3D,
@ref BasicMutableImageView, @ref MutableImageView1D,
@ref MutableImageView2D, @ref MutableImageView3D, @ref Image-pixel-views
@ref MutableImageView2D, @ref MutableImageView3D
*/
template<UnsignedInt dimensions, class T> class ImageView {
public:
@ -486,7 +492,7 @@ template<UnsignedInt dimensions, class T> class ImageView {
* @m_since{2019,10}
*
* Provides direct and easy-to-use access to image pixels. See
* @ref Image-pixel-views for more information. If the view is empty
* @ref Image-pixel-access for more information. If the view is empty
* (with @ref data() being @cpp nullptr @ce), returns @cpp nullptr @ce
* as well.
*/
@ -501,7 +507,7 @@ template<UnsignedInt dimensions, class T> class ImageView {
* correct type for given @ref format() --- checking it on the library
* side is not possible for the general case. If the view is empty
* (with @ref data() being @cpp nullptr @ce), returns @cpp nullptr @ce
* as well.
* as well. See also @ref Image-pixel-access for more information.
*/
template<class U> Containers::StridedArrayView<dimensions, typename std::conditional<std::is_const<Type>::value, typename std::add_const<U>::type, U>::type> pixels() const {
if(!_data && !_data.size()) return {};
@ -608,9 +614,8 @@ functionality targeted on non-compressed image formats.
@section CompressedImageView-usage Basic usage
Usually, the view is created on some pre-existing data array in order to
describe its layout, with pixel format being one of the values from the generic
@link CompressedPixelFormat @endlink:
The view is created from a @ref CompressedPixelFormat, size in pixels and a
data view:
@snippet Magnum.cpp CompressedImageView-usage

82
src/Magnum/Trade/ImageData.h

@ -54,6 +54,13 @@ namespace Magnum { namespace Trade {
/**
@brief Image data
Provides access to both uncompressed and compressed image data together with
information about data layout, image size and pixel format. Populated instances
of this class are returned from @ref AbstractImporter::image1D(),
@relativeref{AbstractImporter,image2D()},
@relativeref{AbstractImporter,image3D()},
@ref AbstractImageConverter::convert() and other APIs.
Used mainly by @ref AbstractImporter classes to store either compressed or
non-compressed multi-dimensional image data together with layout and pixel
format description.
@ -66,29 +73,20 @@ Particular graphics API wrappers provide additional image classes, for example
@section Trade-ImageData-usage Basic usage
The image usually comes out of @ref AbstractImporter::image1D(),
@ref AbstractImporter::image2D() "image2D()" or
@ref AbstractImporter::image3D() "image3D()" and, based on what format the
particular imported data is in, it stores either compressed or uncompressed
data.
@snippet MagnumTrade.cpp ImageData-construction
@snippet MagnumTrade.cpp ImageData-construction-compressed
As with @ref Image / @ref ImageView, this class supports extra storage
parameters and implementation-specific format specification, if the importer
has a need for that. See the @ref ImageView documentation for more information.
When using the image, its compression status can be distinguished using
@ref isCompressed(). Uncompressed image properties are available through
@ref storage(), @ref format(), @ref formatExtra() and @ref pixelSize();
Based on whether the @ref ImageData has an uncompressed or compressed pixel
format, it behaves either like an @ref Image / @ref ImageView or like a
@ref CompressedImage / @ref CompressedImageView. It can be distinguished using
@ref isCompressed(); uncompressed image properties are then available through
@ref storage(), @ref format(), @ref formatExtra() and @ref pixelSize(),
compressed properties through @ref compressedStorage() and
@ref compressedFormat(). Example of uploading the image to
@ref compressedFormat(). Example of uploading the image to a
@link GL::Texture @endlink:
@snippet MagnumTrade.cpp ImageData-usage
Uncompressed image data instances provide pixel data access via @ref pixels()
in the same way as the @ref Image class. See @ref Image-pixel-access "its documentation for more information".
@section Trade-ImageData-usage-mutable Mutable data access
The interfaces implicitly provide @cpp const @ce views on the contained
@ -101,8 +99,44 @@ first. The following snippet flips the R and B channels of the imported image:
@snippet MagnumTrade.cpp ImageData-usage-mutable
@see @ref ImageData1D, @ref ImageData2D, @ref ImageData3D,
@ref Image-pixel-views
@section Trade-ImageData-populating Populating an instance
An @ref ImageData instance by default takes over the ownership of an
@relativeref{Corrade,Containers::Array} containing the pixel data together
with size and either @ref PixelFormat or @ref CompressedPixelFormat, similarly
to the @ref Image and @ref CompressedImage classes:
@snippet MagnumTrade.cpp ImageData-populating
The constructor internally checks that the passed array is large enough and as
with other image classes, care must be taken in presence of
non-four-byte-aligned rows. This often closely depends on behavior of the code
or library that operates with the image data and the recommended way is to pad
the row data to satisfy the alignment:
@snippet MagnumTrade.cpp ImageData-populating-padding
Alternatively, if padding is not possible or desirable, you can pass a
@ref PixelStorage instance with the alignment overriden to @cpp 1 @ce:
@snippet MagnumTrade.cpp ImageData-populating-alignment
As with @ref Image / @ref ImageView, this class supports extra storage
parameters and implementation-specific format specification, if the importer
has a need for that. See the @ref ImageView documentation for more information.
@subsection Trade-ImageData-populating-non-owned Non-owned instances
In some cases you may want the @ref ImageData instance to only refer to
external data without taking ownership, for example with a memory-mapped file,
global data etc. For that, instead of moving in an
@relativeref{Corrade,Containers::Array}, pass @ref DataFlags describing data
mutability and ownership together with an
@relativeref{Corrade,Containers::ArrayView}:
@snippet MagnumTrade.cpp ImageData-populating-non-owned
@see @ref ImageData1D, @ref ImageData2D, @ref ImageData3D
*/
template<UnsignedInt dimensions> class ImageData {
public:
@ -802,7 +836,7 @@ template<UnsignedInt dimensions> class ImageData {
* the image is not compressed. The last dimension represents the
* actual data type (its size is equal to type size) and is guaranteed
* to be contiguous. Use the templated overload below to get pixels in
* a concrete type. See @ref Image-pixel-views for more information.
* a concrete type. See @ref Image-pixel-access for more information.
* @see @ref isCompressed(),
* @ref Corrade::Containers::StridedArrayView::isContiguous()
*/
@ -813,7 +847,8 @@ template<UnsignedInt dimensions> class ImageData {
* @m_since{2020,06}
*
* Like @ref pixels() const, but returns a non-const view. Expects that
* the image is mutable.
* the image is mutable. See also @ref Image-pixel-access for more
* information.
* @see @ref dataFlags()
*/
Containers::StridedArrayView<dimensions + 1, char> mutablePixels();
@ -825,7 +860,8 @@ template<UnsignedInt dimensions> class ImageData {
* Compared to non-templated @ref pixels() in addition casts the pixel
* data to a specified type. The user is responsible for choosing
* correct type for given @ref format() --- checking it on the library
* side is not possible for the general case.
* side is not possible for the general case. See also
* @ref Image-pixel-access for more information.
*/
template<class T> Containers::StridedArrayView<dimensions, const T> pixels() const {
/* Deliberately not adding a StridedArrayView include, it should

Loading…
Cancel
Save