Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_lazy_fill_capacity_map.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#ifndef __KIS_LAZY_FILL_CAPACITY_MAP_H
8#define __KIS_LAZY_FILL_CAPACITY_MAP_H
9
10#include <KoColorSpace.h>
11
12#include "kis_lazy_fill_graph.h"
13#include "kis_paint_device.h"
14#include "kis_types.h"
15#include "kis_painter.h"
17#include "kis_global.h"
18#include <KisRegion.h>
19
20
22{
24 typedef typename boost::graph_traits<KisLazyFillGraph>::vertex_descriptor VertexDescriptor;
25 typedef typename boost::graph_traits<KisLazyFillGraph>::edge_descriptor EdgeDescriptor;
26
27public:
29 typedef int value_type;
30 typedef const int& reference;
31 typedef boost::readable_property_map_tag category;
32
34 KisPaintDeviceSP aLabelImage,
35 KisPaintDeviceSP bLabelImage,
36 KisPaintDeviceSP maskImage,
37 const QRect &boundingRect)
38 : m_mainImage(mainImage),
39 m_aLabelImage(aLabelImage),
40 m_bLabelImage(bLabelImage),
41 m_maskImage(maskImage),
42 m_mainRect(boundingRect),
43 m_aLabelRect(m_aLabelImage->exactBounds() & boundingRect),
44 m_bLabelRect(m_bLabelImage->exactBounds() & boundingRect),
45 m_colorSpace(mainImage->colorSpace()),
46 m_pixelSize(m_colorSpace->pixelSize()),
48 m_aLabelImage->regionExact() & boundingRect,
49 m_bLabelImage->regionExact() & boundingRect)
50 {
54
60 }
61
62 int maxCapacity() const {
63 const int k = 2 * (m_mainRect.width() + m_mainRect.height());
64 return k + 1;
65 }
66
67 friend value_type get(type &map,
68 const key_type &key)
69 {
70 VertexDescriptor src = source(key, map.m_graph);
71 VertexDescriptor dst = target(key, map.m_graph);
72
73 if (src.type == VertexDescriptor::NORMAL) {
74 map.m_maskAccessor->moveTo(src.x, src.y);
75 if (*map.m_maskAccessor->rawDataConst()) {
76 return 0;
77 }
78 }
79
80 if (dst.type == VertexDescriptor::NORMAL) {
81 map.m_maskAccessor->moveTo(dst.x, dst.y);
82 if (*map.m_maskAccessor->rawDataConst()) {
83 return 0;
84 }
85 }
86
87 bool srcLabelA = src.type == VertexDescriptor::LABEL_A;
88 bool srcLabelB = src.type == VertexDescriptor::LABEL_B;
89 bool dstLabelA = dst.type == VertexDescriptor::LABEL_A;
90 bool dstLabelB = dst.type == VertexDescriptor::LABEL_B;
91
92 if (srcLabelA || srcLabelB) {
93 std::swap(src, dst);
94 std::swap(srcLabelA, dstLabelA);
95 std::swap(srcLabelB, dstLabelB);
96 }
97
98 Q_ASSERT(!srcLabelA && !srcLabelB);
99
100
101 // TODO: precalculate!
102 const int k = 2 * (map.m_mainRect.width() + map.m_mainRect.height());
103
104 static const int unitValue = 256;
105
106 qreal value = 0.0;
107
108 if (dstLabelA) {
109 map.m_aAccessor->moveTo(src.x, src.y);
110 const int i0 = *((quint8*)map.m_aAccessor->rawDataConst());
111 value = i0 / 255.0 * k;
112
113 } else if (dstLabelB) {
114 map.m_bAccessor->moveTo(src.x, src.y);
115 const int i0 = *((quint8*)map.m_bAccessor->rawDataConst());
116 value = i0 / 255.0 * k;
117
118 } else {
119 map.m_mainAccessor->moveTo(src.x, src.y);
120 memcpy(map.m_srcPixelBuf.data(), map.m_mainAccessor->rawDataConst(), map.m_pixelSize);
121 map.m_mainAccessor->moveTo(dst.x, dst.y);
122
123 //const quint8 diff = map.m_colorSpace->differenceA((quint8*)map.m_srcPixelBuf.data(), map.m_mainAccessor->rawDataConst());
124 //const quint8 i0 = map.m_colorSpace->intensity8((quint8*)map.m_srcPixelBuf.data());
125 //const quint8 i1 = map.m_colorSpace->intensity8(map.m_mainAccessor->rawDataConst());
126
127 const quint8 i0 = *((quint8*)map.m_srcPixelBuf.data());
128 const quint8 i1 = *map.m_mainAccessor->rawDataConst();
129
130 const quint8 diff = qAbs(i1 - i0);
131
132 const qreal diffPenalty = qBound(0.0, qreal(diff) / 10.0, 1.0);
133 const qreal intensityPenalty = 1.0 - i1 / 255.0;
134
135 const qreal totalPenalty = qMax(0.0 * diffPenalty, intensityPenalty);
136
137 value = 1.0 + k * (1.0 - pow2(totalPenalty));
138 }
139
140 return value * unitValue;
141 }
142
144 return m_graph;
145 }
146
147private:
152
156
163 QByteArray m_srcPixelBuf;
164
166};
167
168#endif /* __KIS_LAZY_FILL_CAPACITY_MAP_H */
float value(const T *src, size_t ch)
KisMagneticGraph::vertex_descriptor target(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
virtual const quint8 * rawDataConst() const =0
KisLazyFillCapacityMap(KisPaintDeviceSP mainImage, KisPaintDeviceSP aLabelImage, KisPaintDeviceSP bLabelImage, KisPaintDeviceSP maskImage, const QRect &boundingRect)
KisRandomConstAccessorSP m_mainAccessor
boost::readable_property_map_tag category
KisRandomConstAccessorSP m_maskAccessor
KisRandomConstAccessorSP m_bAccessor
friend value_type get(type &map, const key_type &key)
KisRandomConstAccessorSP m_aAccessor
boost::graph_traits< KisLazyFillGraph >::vertex_descriptor VertexDescriptor
boost::graph_traits< KisLazyFillGraph >::edge_descriptor EdgeDescriptor
KisRandomConstAccessorSP createRandomConstAccessorNG() const
const KoColorSpace * colorSpace() const
virtual void moveTo(qint32 x, qint32 y)=0
virtual quint32 pixelSize() const =0
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
T pow2(const T &x)
Definition kis_global.h:166