AUI Framework  develop
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
AImageView.h
    1/*
    2 * AUI Framework - Declarative UI toolkit for modern C++20
    3 * Copyright (C) 2020-2025 Alex2772 and Contributors
    4 *
    5 * SPDX-License-Identifier: MPL-2.0
    6 *
    7 * This Source Code Form is subject to the terms of the Mozilla Public
    8 * License, v. 2.0. If a copy of the MPL was not distributed with this
    9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   10 */
   11
   12#pragma once
   13
   14#include <cstdint>
   15#include <glm/glm.hpp>
   16#include <AUI/Common/AVector.h>
   17#include <AUI/Common/AByteBuffer.h>
   18#include <AUI/Util/Cache.h>
   19#include <AUI/Url/AUrl.h>
   20#include <AUI/IO/APath.h>
   21#include "AUI/Common/AColor.h"
   22#include "AUI/Traits/memory.h"
   23#include "APixelFormat.h"
   24#include "glm/vector_relational.hpp"
   25
   26class API_AUI_IMAGE AImage;
   27class API_AUI_IMAGE AImageView;
   28
   29template <auto imageFormat = APixelFormat::DEFAULT>
   30class AFormattedImageView;
   31
   32template <auto imageFormat = APixelFormat::DEFAULT>
   33class AFormattedImage;
   34
   35template <typename T>
   36concept AImageViewVisitor = requires(T t) {
   37    t(std::declval<const AFormattedImageView<APixelFormat::RGB | APixelFormat::BYTE>&>());
   38    t(std::declval<const AFormattedImageView<APixelFormat::RGBA | APixelFormat::BYTE>&>());
   39    t(std::declval<const AFormattedImageView<APixelFormat::RGB | APixelFormat::FLOAT>&>());
   40    t(std::declval<const AFormattedImageView<APixelFormat::RGBA | APixelFormat::FLOAT>&>());
   41    // etc...
   42};
   43
   44template <typename T>
   45concept AImageVisitor = requires(T t) {
   50    // etc...
   51};
   52
   58class API_AUI_IMAGE AImageView {
   59public:
   60    using Color = AColor;
   61
   62    AImageView() : mSize(0, 0) {}
   63    AImageView(AByteBufferView data, glm::uvec2 size, APixelFormat format)
   64      : mData(data), mSize(size), mFormat(format) {}
   65    AImageView(const AImage& v);
   66
   70    [[nodiscard]]
   71    AByteBufferView buffer() const noexcept {
   72        return mData;
   73    }
   74
   78    [[nodiscard]]
   79    glm::uvec2 size() const noexcept {
   80        return mSize;
   81    }
   82
   86    [[nodiscard]]
   87    unsigned width() const noexcept {
   88        return mSize.x;
   89    }
   90
   94    [[nodiscard]]
   95    unsigned height() const noexcept {
   96        return mSize.y;
   97    }
   98
  102    [[nodiscard]]
  103    APixelFormat format() const noexcept {
  104        return mFormat;
  105    }
  106
  110    [[nodiscard]]
  111    std::uint8_t bytesPerPixel() const noexcept {
  112        return mFormat.bytesPerPixel();
  113    }
  114
  126    [[nodiscard]]
  127    Color get(glm::uvec2 position) const noexcept;
  128
  129    template <AImageViewVisitor Visitor>
  130    auto visit(Visitor&& visitor) const;
  131
  137    [[nodiscard]]
  138    AImage cropped(glm::uvec2 position, glm::uvec2 size) const;
  139
  140    [[nodiscard]]
  141    Color averageColor() const noexcept;
  142
  150    [[nodiscard]]
  151    const char& rawDataAt(glm::uvec2 position) const noexcept {
  152        AUI_ASSERT(width() != 0);
  153        AUI_ASSERT(height() != 0);
  154        AUI_ASSERT(position.x < width());
  155        AUI_ASSERT(position.y < height());
  156        return mData.at<char>((position.y * width() + position.x) * bytesPerPixel());
  157    }
  158
  159    [[nodiscard]]
  160    AImage mirroredVertically() const;
  161
  162    [[nodiscard]]
  163    AImage resizedLinearDownscale(glm::uvec2 newSize) const;
  164
  165    [[nodiscard]]
  166    AImage convert(APixelFormat format) const;
  167
  171    [[nodiscard]]
  172    const char* data() const noexcept {
  173        return buffer().data();
  174    }
  175
  176protected:
  177    AByteBufferView mData;
  178    glm::uvec2 mSize;
  179    APixelFormat mFormat = APixelFormat::UNKNOWN;
  180};
  181
  186template <auto f>
  187class AFormattedImageView : public AImageView {
  188public:
  189    using Color = AFormattedColor<f>;
  190    static constexpr int FORMAT = f;
  191
  192    constexpr int format() const noexcept { return f; }
  193
  194    AFormattedImageView() { mFormat = f; }
  195
  196    AFormattedImageView(AByteBufferView data, glm::uvec2 size) : AImageView(data, size, f) {}
  197
  198    [[nodiscard]]
  199    const Color& get(glm::uvec2 position) const noexcept {
  200        return reinterpret_cast<const Color&>(rawDataAt(position));
  201    }
  202
  203    [[nodiscard]]
  204    const Color* begin() const noexcept {
  205        return reinterpret_cast<const Color*>(AImageView::data());
  206    }
  207
  208    [[nodiscard]]
  209    const Color* end() const noexcept {
  210        return reinterpret_cast<const Color*>(AImageView::data()) + (width() * height());
  211    }
  212
  213    [[nodiscard]]
  214    AColor averageColor() const noexcept {
  215        AColor accumulator;
  216        aui::zero(accumulator);
  217
  218        for (auto i = begin(); i != end(); ++i) {
  219            accumulator += AColor(*i);
  220        }
  221
  222        return accumulator / float(width() * height());
  223    }
  224};
  225
  226template <AImageViewVisitor Visitor>
  227auto AImageView::visit(Visitor&& visitor) const {
  228#define AUI_CASE(v)                                                                                           \
  229    case v: {                                                                                                 \
  230        switch (format() & APixelFormat::TYPE_BITS) {                                                         \
  231            case APixelFormat::BYTE:                                                                          \
  232                return visitor(reinterpret_cast<const AFormattedImageView<v | APixelFormat::BYTE>&>(*this));  \
  233            case APixelFormat::FLOAT:                                                                         \
  234                return visitor(reinterpret_cast<const AFormattedImageView<v | APixelFormat::FLOAT>&>(*this)); \
  235        }                                                                                                     \
  236    }
  237
  238    switch (format() & APixelFormat::COMPONENT_BITS) {
  239        AUI_CASE(APixelFormat::R)
  240        AUI_CASE(APixelFormat::RG)
  241        AUI_CASE(APixelFormat::RGB)
  242        AUI_CASE(APixelFormat::RGBA)
  243        AUI_CASE(APixelFormat::ARGB)
  244        AUI_CASE(APixelFormat::BGRA)
  245
  246        default:
  247            throw AException("unknown color format");
  248    }
  249#undef AUI_CASE
  250}
Acts like std::string_view but for AByteBuffer.
Definition AByteBufferView.h:24
Represents a 4-component floating point color (RGBA).
Definition AColor.h:26
Abstract AUI exception.
Definition AException.h:28
Same as AImageView but all universal AColor methods replaced with concrete specific AFormattedColor t...
Definition AImageView.h:187
Same as AImage but all universal AColor methods replaced with concrete specific AFormattedColor type ...
Definition AImage.h:90
Non-owning read-only image representation of some format.
Definition AImageView.h:58
unsigned width() const noexcept
Definition AImageView.h:87
Color get(glm::uvec2 position) const noexcept
Retrieves pixel color data.
AImage cropped(glm::uvec2 position, glm::uvec2 size) const
Crops the image, creating new image with the same format.
unsigned height() const noexcept
Definition AImageView.h:95
std::uint8_t bytesPerPixel() const noexcept
Definition AImageView.h:111
const char & rawDataAt(glm::uvec2 position) const noexcept
Retrieves reference to raw data at specified position.
Definition AImageView.h:151
AByteBufferView buffer() const noexcept
Definition AImageView.h:71
glm::uvec2 size() const noexcept
Definition AImageView.h:79
const char * data() const noexcept
Shortcut to buffer().data().
Definition AImageView.h:172
APixelFormat format() const noexcept
Definition AImageView.h:103
Owning image representation.
Definition AImage.h:25
Pixel in-memory format descriptor (type, count and order of subpixel components).
Definition APixelFormat.h:27
Definition AImageView.h:36
Definition AImageView.h:45
#define AUI_ASSERT(condition)
Asserts that the passed condition evaluates to true.
Definition Assert.h:55