CaptureMoment 0.1.0
Free and open-source non-destructive photo editor
Loading...
Searching...
No Matches
rhi_image_item.cpp
Go to the documentation of this file.
1
10#include <spdlog/spdlog.h>
11#include <QMutexLocker>
12
14
15RHIImageItem::RHIImageItem(QQuickItem* parent)
16 : QQuickRhiItem(parent)
17{
18 spdlog::debug("[RHIImageItem::RHIImageItem]: Created");
19}
20
22{
23 spdlog::debug("[RHIImageItem::~RHIImageItem]: Destroyed");
24}
25
26void RHIImageItem::setImage(std::unique_ptr<Core::Common::ImageRegion> image)
27{
28 if (!image || !image->isValid()) {
29 spdlog::warn("[RHIImageItem::setImage]: Invalid image");
30 return;
31 }
32
33 spdlog::info("[RHIImageItem::setImage]: {}x{}", image->width(), image->height());
34
35 {
36 QMutexLocker lock(&m_image_mutex);
37 m_full_image = std::move(image);
38 m_texture_needs_update = true;
39 }
40
42}
43
44void RHIImageItem::updateTile(std::unique_ptr<Core::Common::ImageRegion> tile)
45{
46 if (!tile || !tile->isValid()) {
47 spdlog::warn("[RHIImageItem::updateTile]: Invalid tile");
48 return;
49 }
50
51 {
52 QMutexLocker lock(&m_image_mutex);
53
54 if (!m_full_image) {
55 spdlog::warn("[RHIImageItem::updateTile]: No base image");
56 return;
57 }
58
59 // Full replacement if same dimensions
60 if (tile->width() == m_full_image->width() &&
61 tile->height() == m_full_image->height()) {
62 m_full_image = std::move(tile);
63 spdlog::debug("[RHIImageItem::updateTile]: Full replacement");
64 } else
65 {
66 // Security: Validate tile bounds and channel count before partial copy
67 if (tile->x() < 0 || tile->y() < 0 ||
68 tile->x() + tile->width() > m_full_image->width() ||
69 tile->y() + tile->height() > m_full_image->height() ||
70 tile->channels() != m_full_image->channels()) {
71 spdlog::warn("[RHIImageItem::updateTile]: Tile out of bounds or channel mismatch");
72 return;
73 }
74
75 // Partial copy by row (optimized)
76 const size_t row_size { tile->width() * tile->channels() };
77 for (int y = 0; y < tile->height(); ++y)
78 {
79 const float* src { tile->getBuffer().data() + y * row_size };
80 float* dst { m_full_image->getBuffer().data() +
81 ((tile->y() + y) * m_full_image->width() + tile->x()) * m_full_image->channels() };
82 std::copy(src, src + row_size, dst);
83 }
84 spdlog::debug("[RHIImageItem::updateTile]: Partial at ({}, {})", tile->x(), tile->y());
85 }
86
87 m_texture_needs_update = true;
88 }
89
90 update();
91}
92
94{
95 QMutexLocker lock(&m_image_mutex);
96 return m_texture_needs_update;
97}
98
100{
101 QMutexLocker lock(&m_image_mutex);
102 m_texture_needs_update = needs_update;
103}
104
105void RHIImageItem::onZoomChanged(float new_zoom)
106{
107 emit zoomChanged(new_zoom);
108 update();
109}
110
111void RHIImageItem::onPanChanged(const QPointF& new_pan)
112{
113 emit panChanged(new_pan);
114 update();
115}
116
118{
119 emit imageSizeChanged();
120 update();
121}
122
123QQuickRhiItemRenderer* RHIImageItem::createRenderer()
124{
125 return new RHIImageItemRenderer(this);
126}
127
128} // namespace CaptureMoment::UI::Rendering
std::unique_ptr< Core::Common::ImageRegion > m_full_image
Unique pointer to the full image data displayed by this item.
QMutex m_image_mutex
Mutex protecting access to m_full_image and related state. Ensures thread-safe updates to the image d...
~RHIImageItem() override
Destroys the RHIImageItem and releases associated resources.
QQuickRhiItemRenderer * createRenderer() override
Creates the renderer instance responsible for RHI rendering.
void onImageChanged() override
Handler called when image data changes.
void zoomChanged(float zoom)
Signal emitted when the zoom value changes.
bool textureNeedsUpdate() const
Gets the state of the texture update flag.
void onPanChanged(const QPointF &new_pan) override
Handler called when pan changes.
void setTextureNeedsUpdate(bool needs_update)
Sets the state of the texture update flag.
void setImage(std::unique_ptr< Core::Common::ImageRegion > image) override
Sets the full image to be displayed.
void imageSizeChanged()
Signal emitted when the image dimensions change (width or height).
void onZoomChanged(float new_zoom) override
Handler called when zoom changes.
void updateTile(std::unique_ptr< Core::Common::ImageRegion > tile) override
Updates a specific tile of the displayed image.
RHIImageItem(QQuickItem *parent=nullptr)
Constructs a new RHIImageItem.
void panChanged(const QPointF &pan)
Signal emitted when the pan offset changes.
Namespace containing Qt-specific UI components for CaptureMoment.
Modern RHI-based image display (Qt6 - Vulkan/Metal/DX12 compatible) using QQuickRhiItem.
RHI renderer implementation for hardware-accelerated image display.
CaptureMoment — footer