Krita Source Code Documentation
Loading...
Searching...
No Matches
KisFilterWeightsApplicator Class Reference

#include <kis_filter_weights_applicator.h>

Classes

struct  BlendSpan
 
class  LinePos
 

Public Member Functions

BlendSpan calculateBlendSpan (int dst_l, int line, KisFilterWeightsBuffer *buffer) const
 
 KisFilterWeightsApplicator (KisPaintDeviceSP src, KisPaintDeviceSP dst, qreal realScale, qreal shear, qreal dx, bool clampToEdge)
 
template<class T >
LinePos processLine (LinePos srcLine, int line, KisFilterWeightsBuffer *buffer, qreal filterSupport)
 

Private Member Functions

KisFixedPoint c_to_l (KisFixedPoint pixel_c) const
 
qreal dstToSrc (qreal dst, int line) const
 
int findAntialiasedDstEnd (int src_l, qreal support, int line)
 
int findAntialiasedDstStart (int src_l, qreal support, int line)
 
int getLeftSrcNeedBorder (int dst_l, int line, KisFilterWeightsBuffer *buffer)
 
int getRightSrcNeedBorder (int dst_l, int line, KisFilterWeightsBuffer *buffer)
 
KisFixedPoint l_to_c (KisFixedPoint pixel_l) const
 
qreal srcToDst (qreal src, int line) const
 

Private Attributes

bool m_clampToEdge
 
KisPaintDeviceSP m_dst
 
qreal m_dx
 
qreal m_realScale
 
qreal m_shear
 
KisPaintDeviceSP m_src
 

Detailed Description

This is a main class for transforming a line of pixel data. It transforms lines from src into dst using scale, shear and offset (dx) parameters.

Notation: <pixel_name>_l – leftmost border of the pixel <pixel_name>_c – center of the pixel

Example calculation of an offset (see calculateBlendSpan()): scale = 0.5; offset = <very small value>

               +------ dst_l
               |
               |   +-- dst_c
               |   |

dst: | * | * | * |

src: | * | * | * | * | * | * | * | * |

                  |||
                  ||+--- next_c_in_src
                  |||
                  |+---- dst_c_in_src
                  |||
                  |++--- offset (near zero, measured in dst coordinates)
                  |
                  +-- _l position of the pixel, which is considered
                      central in the weights buffer

Another example calculation of an offset (see calculateBlendSpan()): scale = 0.5; offset = <high value near 0.5>

                 +------ dst_l
                 |
                 |   +-- dst_c
                 |   |

dst: | * | * | * |

src: | * | * | * | * | * | * | * | * |

                     || |
                     || +--- next_c_in_src
                     || |
                     +------ dst_c_in_src
                     || |
                     +|-+--- offset (near 0.5, measured in dst coordinates)
                      |
                      +-- _l position of the pixel, which is considered
                          central in the weights buffer

Definition at line 94 of file kis_filter_weights_applicator.h.

Constructor & Destructor Documentation

◆ KisFilterWeightsApplicator()

KisFilterWeightsApplicator::KisFilterWeightsApplicator ( KisPaintDeviceSP src,
KisPaintDeviceSP dst,
qreal realScale,
qreal shear,
qreal dx,
bool clampToEdge )
inline

Member Function Documentation

◆ c_to_l()

KisFixedPoint KisFilterWeightsApplicator::c_to_l ( KisFixedPoint pixel_c) const
inlineprivate

Definition at line 317 of file kis_filter_weights_applicator.h.

317 {
318 return pixel_c - KisFixedPoint(qreal(0.5));
319 }

◆ calculateBlendSpan()

BlendSpan KisFilterWeightsApplicator::calculateBlendSpan ( int dst_l,
int line,
KisFilterWeightsBuffer * buffer ) const
inline

Definition at line 118 of file kis_filter_weights_applicator.h.

118 {
119 KisFixedPoint dst_c = l_to_c(dst_l);
120 KisFixedPoint dst_c_in_src = dstToSrc(dst_c.toFloat(), line);
121
122 // gives the nearest center of the pixel in src ( x e (0, 1> => f(x) = 0.5, x e (1, 2> => f(x) = 1.5 etc. )
123 KisFixedPoint next_c_in_src = (dst_c_in_src - qreal(0.5)).toIntCeil() + qreal(0.5);
124
125 BlendSpan span;
126 span.offset = (next_c_in_src - dst_c_in_src) * buffer->weightsPositionScale();
127 span.offsetInc = buffer->weightsPositionScale();
128
129 Q_ASSERT(span.offset <= span.offsetInc);
130
131 span.weights = buffer->weights(span.offset);
132 span.firstBlendPixel = next_c_in_src.toIntFloor() - span.weights->centerIndex;
133
134 return span;
135 }
KisFixedPoint l_to_c(KisFixedPoint pixel_l) const
qreal dstToSrc(qreal dst, int line) const
FilterWeights * weights(KisFixedPoint pos) const
KisFixedPoint weightsPositionScale() const
qint32 toIntFloor() const
qreal toFloat() const

References KisFilterWeightsBuffer::FilterWeights::centerIndex, dstToSrc(), KisFilterWeightsApplicator::BlendSpan::firstBlendPixel, l_to_c(), KisFilterWeightsApplicator::BlendSpan::offset, KisFilterWeightsApplicator::BlendSpan::offsetInc, KisFixedPoint::toFloat(), KisFixedPoint::toIntFloor(), KisFilterWeightsApplicator::BlendSpan::weights, KisFilterWeightsBuffer::weights(), and KisFilterWeightsBuffer::weightsPositionScale().

◆ dstToSrc()

qreal KisFilterWeightsApplicator::dstToSrc ( qreal dst,
int line ) const
inlineprivate

Definition at line 325 of file kis_filter_weights_applicator.h.

325 {
326 return (dst - m_dx - line * m_shear) / m_realScale;
327 }

References m_dx, m_realScale, and m_shear.

◆ findAntialiasedDstEnd()

int KisFilterWeightsApplicator::findAntialiasedDstEnd ( int src_l,
qreal support,
int line )
inlineprivate

Definition at line 298 of file kis_filter_weights_applicator.h.

298 {
299 qreal dst = srcToDst(src_l, line);
300 return !m_clampToEdge ? qRound(dst + support) : qRound(dst);
301 }
qreal srcToDst(qreal src, int line) const

References m_clampToEdge, and srcToDst().

◆ findAntialiasedDstStart()

int KisFilterWeightsApplicator::findAntialiasedDstStart ( int src_l,
qreal support,
int line )
inlineprivate

Definition at line 293 of file kis_filter_weights_applicator.h.

293 {
294 qreal dst = srcToDst(src_l, line);
295 return !m_clampToEdge ? qRound(dst - support) : qRound(dst);
296 }

References m_clampToEdge, and srcToDst().

◆ getLeftSrcNeedBorder()

int KisFilterWeightsApplicator::getLeftSrcNeedBorder ( int dst_l,
int line,
KisFilterWeightsBuffer * buffer )
inlineprivate

Definition at line 303 of file kis_filter_weights_applicator.h.

303 {
304 BlendSpan span = calculateBlendSpan(dst_l, line, buffer);
305 return span.firstBlendPixel;
306 }
BlendSpan calculateBlendSpan(int dst_l, int line, KisFilterWeightsBuffer *buffer) const

References calculateBlendSpan(), and KisFilterWeightsApplicator::BlendSpan::firstBlendPixel.

◆ getRightSrcNeedBorder()

int KisFilterWeightsApplicator::getRightSrcNeedBorder ( int dst_l,
int line,
KisFilterWeightsBuffer * buffer )
inlineprivate

Definition at line 308 of file kis_filter_weights_applicator.h.

308 {
309 BlendSpan span = calculateBlendSpan(dst_l, line, buffer);
310 return span.firstBlendPixel + span.weights->span;
311 }

References calculateBlendSpan(), KisFilterWeightsApplicator::BlendSpan::firstBlendPixel, KisFilterWeightsBuffer::FilterWeights::span, and KisFilterWeightsApplicator::BlendSpan::weights.

◆ l_to_c()

KisFixedPoint KisFilterWeightsApplicator::l_to_c ( KisFixedPoint pixel_l) const
inlineprivate

Definition at line 313 of file kis_filter_weights_applicator.h.

313 {
314 return pixel_l + KisFixedPoint(qreal(0.5));
315 }

◆ processLine()

template<class T >
LinePos KisFilterWeightsApplicator::processLine ( LinePos srcLine,
int line,
KisFilterWeightsBuffer * buffer,
qreal filterSupport )
inline

Since we are rounding the borders of the line we might end up to squashing our line into a single pixel. In such a case we should correct our line to be exactly one pixel

Since we are rounding the borders of the line we might end up to squashing our line into a single pixel. In such a case we should correct our line to be exactly one pixel

Definition at line 187 of file kis_filter_weights_applicator.h.

187 {
188 int dstStart;
189 int dstEnd;
190
191 int leftSrcBorder;
192 int rightSrcBorder;
193
194 if (m_realScale >= 0) {
195 dstStart = findAntialiasedDstStart(srcLine.start(), filterSupport, line);
196 dstEnd = findAntialiasedDstEnd(srcLine.end(), filterSupport, line);
197
201 if (dstStart == dstEnd) {
202 dstEnd = dstStart + 1;
203 }
204
205 leftSrcBorder = getLeftSrcNeedBorder(dstStart, line, buffer);
206 rightSrcBorder = getRightSrcNeedBorder(dstEnd - 1, line, buffer);
207 }
208 else {
209 dstStart = findAntialiasedDstStart(srcLine.end(), filterSupport, line);
210 dstEnd = findAntialiasedDstEnd(srcLine.start(), filterSupport, line);
211
215 if (dstStart == dstEnd) {
216 dstEnd = dstStart + 1;
217 }
218
219 leftSrcBorder = getLeftSrcNeedBorder(dstEnd - 1, line, buffer);
220 rightSrcBorder = getRightSrcNeedBorder(dstStart, line, buffer);
221 }
222
223 if (dstStart >= dstEnd) return LinePos(dstStart, 0);
224 if (leftSrcBorder >= rightSrcBorder) return LinePos(dstStart, 0);
225 if (leftSrcBorder > srcLine.start()) {
226 leftSrcBorder = srcLine.start();
227 }
228 if (srcLine.end() > rightSrcBorder) {
229 rightSrcBorder = srcLine.end();
230 }
231
232 int pixelSize = m_src->pixelSize();
234 const KoColor defaultPixelObject = m_src->defaultPixel();
235 const quint8 *defaultPixel = defaultPixelObject.data();
236 const quint8 *borderPixel = defaultPixel;
237 quint8 *srcLineBuf = new quint8[pixelSize * (rightSrcBorder - leftSrcBorder)];
238
239 int i = leftSrcBorder;
240 quint8 *bufPtr = srcLineBuf;
241
242 T srcIt = tmp::createIterator<T>(m_src, srcLine.start(), line, srcLine.size());
243
244 if (m_clampToEdge) {
245 borderPixel = srcIt->rawData();
246 }
247
248 for (; i < srcLine.start(); i++, bufPtr+=pixelSize) {
249 memcpy(bufPtr, borderPixel, pixelSize);
250 }
251
252 for (; i < srcLine.end(); i++, bufPtr+=pixelSize) {
253 quint8 *data = srcIt->rawData();
254 memcpy(bufPtr, data, pixelSize);
255 memcpy(data, defaultPixel, pixelSize);
256 srcIt->nextPixel();
257 }
258
259 if (m_clampToEdge) {
260 borderPixel = bufPtr - pixelSize;
261 }
262
263 for (; i < rightSrcBorder; i++, bufPtr+=pixelSize) {
264 memcpy(bufPtr, borderPixel, pixelSize);
265 }
266
267 const quint8 **colors = new const quint8* [buffer->maxSpan()];
268
269 T dstIt = tmp::createIterator<T>(m_dst, dstStart, line, dstEnd - dstStart);
270 for (int i = dstStart; i < dstEnd; i++) {
271 BlendSpan span = calculateBlendSpan(i, line, buffer);
272
273 int bufIndexStart = span.firstBlendPixel - leftSrcBorder;
274 int bufIndexEnd = bufIndexStart + span.weights->span;
275
276 const quint8 **colorsPtr = colors;
277 for (int j = bufIndexStart; j < bufIndexEnd; j++) {
278 *(colorsPtr++) = srcLineBuf + j * pixelSize;
279 }
280
281 mixOp->mixColors(colors, span.weights->weight, span.weights->span, dstIt->rawData());
282 dstIt->nextPixel();
283 }
284
285 delete[] colors;
286 delete[] srcLineBuf;
287
288 return LinePos(dstStart, qMax(0, dstEnd - dstStart));
289 }
int findAntialiasedDstEnd(int src_l, qreal support, int line)
int findAntialiasedDstStart(int src_l, qreal support, int line)
int getRightSrcNeedBorder(int dst_l, int line, KisFilterWeightsBuffer *buffer)
int getLeftSrcNeedBorder(int dst_l, int line, KisFilterWeightsBuffer *buffer)
quint32 pixelSize() const
const KoColorSpace * colorSpace() const
KoColor defaultPixel() const
KoMixColorsOp * mixColorsOp
quint8 * data()
Definition KoColor.h:144
virtual void mixColors(const quint8 *const *colors, const qint16 *weights, int nColors, quint8 *dst, int weightSum=255) const =0

References calculateBlendSpan(), KisPaintDevice::colorSpace(), KoColor::data(), KisPaintDevice::defaultPixel(), KisFilterWeightsApplicator::LinePos::end(), findAntialiasedDstEnd(), findAntialiasedDstStart(), KisFilterWeightsApplicator::BlendSpan::firstBlendPixel, getLeftSrcNeedBorder(), getRightSrcNeedBorder(), m_clampToEdge, m_dst, m_realScale, m_src, KisFilterWeightsBuffer::maxSpan(), KoMixColorsOp::mixColors(), KoColorSpace::mixColorsOp, KisPaintDevice::pixelSize(), KisFilterWeightsApplicator::LinePos::size(), KisFilterWeightsBuffer::FilterWeights::span, KisFilterWeightsApplicator::LinePos::start(), KisFilterWeightsBuffer::FilterWeights::weight, and KisFilterWeightsApplicator::BlendSpan::weights.

◆ srcToDst()

qreal KisFilterWeightsApplicator::srcToDst ( qreal src,
int line ) const
inlineprivate

Definition at line 321 of file kis_filter_weights_applicator.h.

321 {
322 return src * m_realScale + m_dx + line * m_shear;
323 }

References m_dx, m_realScale, and m_shear.

Member Data Documentation

◆ m_clampToEdge

bool KisFilterWeightsApplicator::m_clampToEdge
private

Definition at line 336 of file kis_filter_weights_applicator.h.

◆ m_dst

KisPaintDeviceSP KisFilterWeightsApplicator::m_dst
private

Definition at line 331 of file kis_filter_weights_applicator.h.

◆ m_dx

qreal KisFilterWeightsApplicator::m_dx
private

Definition at line 335 of file kis_filter_weights_applicator.h.

◆ m_realScale

qreal KisFilterWeightsApplicator::m_realScale
private

Definition at line 333 of file kis_filter_weights_applicator.h.

◆ m_shear

qreal KisFilterWeightsApplicator::m_shear
private

Definition at line 334 of file kis_filter_weights_applicator.h.

◆ m_src

KisPaintDeviceSP KisFilterWeightsApplicator::m_src
private

Definition at line 330 of file kis_filter_weights_applicator.h.


The documentation for this class was generated from the following file: