Krita Source Code Documentation
Loading...
Searching...
No Matches
KisLazyFillTools Namespace Reference

Classes

struct  FilteringOptions
 
struct  KeyStroke
 

Functions

void cutOneWay (const KoColor &color, KisPaintDeviceSP src, KisPaintDeviceSP colorScribble, KisPaintDeviceSP backgroundScribble, KisPaintDeviceSP resultDevice, KisPaintDeviceSP maskDevice, const QRect &boundingRect)
 
void normalizeAlpha8Device (KisPaintDeviceSP dev, const QRect &rect)
 
void normalizeAndInvertAlpha8Device (KisPaintDeviceSP dev, const QRect &rect)
 
bool operator== (const FilteringOptions &t1, const FilteringOptions &t2)
 
bool operator== (const KeyStroke &t1, const KeyStroke &t2)
 
QVector< QPoint > splitIntoConnectedComponents (KisPaintDeviceSP dev, const QRect &boundingRect)
 

Function Documentation

◆ cutOneWay()

KRITAIMAGE_EXPORT void KisLazyFillTools::cutOneWay ( const KoColor & color,
KisPaintDeviceSP src,
KisPaintDeviceSP colorScribble,
KisPaintDeviceSP backgroundScribble,
KisPaintDeviceSP resultDevice,
KisPaintDeviceSP maskDevice,
const QRect & boundingRect )

Uses Boykov-Kolmogorov Max-Flow/Min-Cut algorithm to split the device src into two parts. The first part is defined by colorScribble and the second part — by backgroundScribble. In the result of the split the area defined by colorScribble in resultDevice is filled with color. Also the same area in maskDevice is filled with a non-null scribble index.

maskDevice is used for limiting the area used for filling the color.

Definition at line 77 of file kis_lazy_fill_tools.cpp.

84{
85 using namespace boost;
86
87 KIS_ASSERT_RECOVER_RETURN(src->pixelSize() == 1);
88 KIS_ASSERT_RECOVER_RETURN(colorScribble->pixelSize() == 1);
89 KIS_ASSERT_RECOVER_RETURN(backgroundScribble->pixelSize() == 1);
90 KIS_ASSERT_RECOVER_RETURN(maskDevice->pixelSize() == 1);
91 KIS_ASSERT_RECOVER_RETURN(*resultDevice->colorSpace() == *color.colorSpace());
92
93 KisLazyFillCapacityMap capacityMap(src, colorScribble, backgroundScribble, maskDevice, boundingRect);
94 KisLazyFillGraph &graph = capacityMap.graph();
95
96 std::vector<default_color_type> groups(num_vertices(graph));
97 std::vector<int> residual_capacity(num_edges(graph), 0);
98
99 std::vector<typename graph_traits<KisLazyFillGraph>::vertices_size_type> distance_vec(num_vertices(graph), 0);
100 std::vector<typename graph_traits<KisLazyFillGraph>::edge_descriptor> predecessor_vec(num_vertices(graph));
101
102 auto vertexIndexMap = get(boost::vertex_index, graph);
103
105
106 Vertex s(Vertex::LABEL_A);
107 Vertex t(Vertex::LABEL_B);
108
109 float maxFlow =
111 capacityMap,
112 make_iterator_property_map(&residual_capacity[0], get(boost::edge_index, graph)),
113 get(boost::edge_reverse, graph),
114 make_iterator_property_map(&predecessor_vec[0], vertexIndexMap),
115 make_iterator_property_map(&groups[0], vertexIndexMap),
116 make_iterator_property_map(&distance_vec[0], vertexIndexMap),
117 vertexIndexMap,
118 s,
119 t);
120 Q_UNUSED(maxFlow);
121
122 KisSequentialIterator dstIt(resultDevice, graph.rect());
123 KisSequentialIterator mskIt(maskDevice, graph.rect());
124
125 const int pixelSize = resultDevice->pixelSize();
126
127 while (dstIt.nextPixel() && mskIt.nextPixel()) {
128 KisLazyFillGraph::vertex_descriptor v(dstIt.x(), dstIt.y());
129 long vertex_idx = get(boost::vertex_index, graph, v);
130 default_color_type label = groups[vertex_idx];
131
132 if (label == black_color) {
133 memcpy(dstIt.rawData(), color.data(), pixelSize);
134 *mskIt.rawData() = 10 + (int(label) << 4);
135 }
136 }
137}
qreal v
VertexDescriptor get(PredecessorMap const &m, VertexDescriptor v)
quint32 pixelSize() const
const KoColorSpace * colorSpace() const
quint8 * data()
Definition KoColor.h:144
const KoColorSpace * colorSpace() const
return the current colorSpace
Definition KoColor.h:82
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
property_traits< CapacityEdgeMap >::value_type boykov_kolmogorov_max_flow(Graph &g, CapacityEdgeMap cap, ResidualCapacityEdgeMap res_cap, ReverseEdgeMap rev_map, PredecessorMap pre_map, ColorMap color, DistanceMap dist, IndexMap idx, typename graph_traits< Graph >::vertex_descriptor src, typename graph_traits< Graph >::vertex_descriptor sink)

References boost::boykov_kolmogorov_max_flow(), KisPaintDevice::colorSpace(), KoColor::colorSpace(), KoColor::data(), get(), KisLazyFillCapacityMap::graph(), KIS_ASSERT_RECOVER_RETURN, KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KisPaintDevice::pixelSize(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), KisLazyFillGraph::rect(), v, KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::x(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::y().

◆ normalizeAlpha8Device()

KRITAIMAGE_EXPORT void KisLazyFillTools::normalizeAlpha8Device ( KisPaintDeviceSP dev,
const QRect & rect )

Definition at line 56 of file kis_lazy_fill_tools.cpp.

57{
58 quint8 maxPixel = std::numeric_limits<quint8>::min();
59 quint8 minPixel = std::numeric_limits<quint8>::max();
61 [&minPixel, &maxPixel](quint8 pixel) {
62 if (pixel > maxPixel) {
63 maxPixel = pixel;
64 }
65 if (pixel < minPixel) {
66 minPixel = pixel;
67 }
68 });
69
70 const qreal scale = 255.0 / (maxPixel - minPixel);
72 [minPixel, scale](quint8 pixel) {
73 return (quint8((pixel - minPixel) * scale));
74 });
75}
void filterAlpha8Device(KisPaintDeviceSP dev, const QRect &rc, std::function< quint8(quint8)> func)
void applyToAlpha8Device(KisPaintDeviceSP dev, const QRect &rc, std::function< void(quint8)> func)

References KritaUtils::applyToAlpha8Device(), and KritaUtils::filterAlpha8Device().

◆ normalizeAndInvertAlpha8Device()

KRITAIMAGE_EXPORT void KisLazyFillTools::normalizeAndInvertAlpha8Device ( KisPaintDeviceSP dev,
const QRect & rect )

Definition at line 35 of file kis_lazy_fill_tools.cpp.

36{
37 quint8 maxPixel = std::numeric_limits<quint8>::min();
38 quint8 minPixel = std::numeric_limits<quint8>::max();
40 [&minPixel, &maxPixel](quint8 pixel) {
41 if (pixel > maxPixel) {
42 maxPixel = pixel;
43 }
44 if (pixel < minPixel) {
45 minPixel = pixel;
46 }
47 });
48
49 const qreal scale = 255.0 / (maxPixel - minPixel);
51 [minPixel, scale](quint8 pixel) {
52 return pow2(255 - quint8((pixel - minPixel) * scale)) / 255;
53 });
54}
T pow2(const T &x)
Definition kis_global.h:166

References KritaUtils::applyToAlpha8Device(), KritaUtils::filterAlpha8Device(), and pow2().

◆ operator==() [1/2]

bool KisLazyFillTools::operator== ( const FilteringOptions & t1,
const FilteringOptions & t2 )

◆ operator==() [2/2]

bool KisLazyFillTools::operator== ( const KeyStroke & t1,
const KeyStroke & t2 )

Definition at line 180 of file kis_lazy_fill_tools.cpp.

181{
182 return
183 t1.dev == t2.dev &&
184 t1.color == t2.color &&
186}

◆ splitIntoConnectedComponents()

KRITAIMAGE_EXPORT QVector< QPoint > KisLazyFillTools::splitIntoConnectedComponents ( KisPaintDeviceSP src,
const QRect & boundingRect )

Returns one pixel from each connected component of src.

WARNING: src is used as a temporary device, so it will be cleared(!) after the execution of the algorithm

Please note that since we modify the device inside clearNonZeroComponent() call, we must use a writable iterator, for not ending up with a lazy copied old version of a device.

Definition at line 139 of file kis_lazy_fill_tools.cpp.

141{
142 QVector<QPoint> points;
143 const KoColorSpace *cs = dev->colorSpace();
144
145 const QRect rect = dev->exactBounds() & boundingRect;
146 if (rect.isEmpty()) return points;
147
154 KisSequentialIterator dstIt(dev, rect);
155
156 while (dstIt.nextPixel()) {
157 if (cs->opacityU8(dstIt.rawData()) > 0) {
158 const QPoint pt(dstIt.x(), dstIt.y());
159 points << pt;
160
161 KisScanlineFill fill(dev, pt, rect);
162 fill.clearNonZeroComponent();
163 }
164 }
165
166 return points;
167}
virtual quint8 opacityU8(const quint8 *pixel) const =0

References KisScanlineFill::clearNonZeroComponent(), KisPaintDevice::colorSpace(), KisPaintDevice::exactBounds(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), KoColorSpace::opacityU8(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::x(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::y().