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

#include <kis_filter_weights_buffer.h>

Classes

struct  FilterWeights
 

Public Member Functions

 KisFilterWeightsBuffer (KisFilterStrategy *filterStrategy, qreal realScale)
 
int maxSpan () const
 
FilterWeightsweights (KisFixedPoint pos) const
 
KisFixedPoint weightsPositionScale () const
 
 ~KisFilterWeightsBuffer ()
 

Private Member Functions

int findMaxIndex (qint16 *buf, int size)
 

Private Attributes

FilterWeightsm_filterWeights
 
int m_maxSpan
 
KisFixedPoint m_weightsPositionScale
 

Detailed Description

Stores the cached values for the weights of neighbouring pixels that would form the pixel in a result of resampling. The object of this class is created before a pass of the transformation basing on the desired scale factor and the filter strategy used for resampling.

Here is an example of a calculation of the span for a pixel with scale equal to 1.0. The result of the blending will be written into the dst(0) pixel, which is marked with '*' sign. Note that all the coordinates here are related to the center of the pixel, not to its leftmost border as it is common in other systems. The centerSrc coordinate represents the offset between the source and the destination buffers.

dst-coordinates: the coordinates in the resulting image. The values of the filter strategy are calculated in these coordinates.

src-coordinates: the coordinates in the source image/buffer. We pick integer values from there and calculate their dst-position to know their weights.

                  +----+----+----+-- scaledIter (samples, measured in dst pixels,
                  |    |    |    |               correspond to integers in src)

                         +---------+-- supportDst == filterStrategy->intSupport()
                         |         |
               +-- beginDst        +-- endDst
               |         |         |
               |         +-- centerDst (always zero)
               |         |         |

dst: -—|-—|-—|-—|-—*-—|-—|-—|-—|-—|--> -4 -3 -2 -1 0 1 2 3 4 5

src: –|-—|-—|-—|-—|-—|-—|-—|-—|-—|----> -4 -3 -2 -1 0 1 2 3 4 5

         ^         ^         ^
         |         |         |
         |         +-- centerSrc
         |         |         |
         +-- beginSrc        +endSrc
         |         |         |
         |         +---------+-- supportSrc ~= supportDst / realScale
         |                   |
         +-------------------+-- span (number of integers in the region)

Definition at line 133 of file kis_filter_weights_buffer.h.

Constructor & Destructor Documentation

◆ KisFilterWeightsBuffer()

KisFilterWeightsBuffer::KisFilterWeightsBuffer ( KisFilterStrategy * filterStrategy,
qreal realScale )
inline

Definition at line 147 of file kis_filter_weights_buffer.h.

147 {
148 Q_ASSERT(realScale > 0);
149
150 m_filterWeights = new FilterWeights[256];
151 m_maxSpan = 0;
153
154 KisFixedPoint supportSrc;
155 KisFixedPoint supportDst;
156
157 if (realScale < 1.0 && realScale > (1.0 / (1 << 8))) {
159 supportSrc.from256Frac(filterStrategy->intSupport(m_weightsPositionScale.toFloat()) / realScale);
160 supportDst.from256Frac(filterStrategy->intSupport(m_weightsPositionScale.toFloat()));
161
162 } else {
163 supportSrc.from256Frac(filterStrategy->intSupport(m_weightsPositionScale.toFloat()));
164 supportDst.from256Frac(filterStrategy->intSupport(m_weightsPositionScale.toFloat()));
165 }
166
167 for (int i = 0; i < 256; i++) {
168 KisFixedPoint centerSrc;
169 centerSrc.from256Frac(i);
170
171 KisFixedPoint beginDst = -supportDst;
172 KisFixedPoint endDst = supportDst;
173
174 KisFixedPoint beginSrc = -supportSrc - centerSrc / m_weightsPositionScale;
175 KisFixedPoint endSrc = supportSrc - centerSrc / m_weightsPositionScale;
176
177 int span = (2 * supportSrc).toInt() +
178 (beginSrc.isInteger() && endSrc.isInteger());
179
180 int centerIndex = -beginSrc.toInt();
181
182 m_filterWeights[i].centerIndex = centerIndex;
183 m_filterWeights[i].span = span;
184 m_filterWeights[i].weight = new qint16[span];
185 m_maxSpan = qMax(m_maxSpan, span);
186
187 // in dst coordinate system:
188 KisFixedPoint scaledIter = centerSrc + beginSrc.toInt() * m_weightsPositionScale;
190
191 DEBUG_ALL();
192
193 int sum = 0;
194 for (int j = 0; j < span; j++) {
195 int t = filterStrategy->intValueAt(scaledIter.to256Frac(), m_weightsPositionScale.toFloat());
196 m_filterWeights[i].weight[j] = t;
197 sum += t;
198
199 DEBUG_SAMPLE();
201
202 scaledIter += scaledInc;
203 }
204
205 SANITY_ZEROS();
206
207 if (sum != 255 && sum > 0) {
208 qreal fixFactor = 255.0 / sum;
209 sum = 0;
210
211 for (int j = 0; j < span; j++) {
212 int t = qRound(m_filterWeights[i].weight[j] * fixFactor);
213
214 m_filterWeights[i].weight[j] = t;
215 sum += t;
216 }
217 }
218
219 while (sum != 255) {
220 int diff = sum < 255 ? 1 : -1;
221 int index = findMaxIndex(m_filterWeights[i].weight, span);
222 m_filterWeights[i].weight[index] += diff;
223 sum += diff;
224 }
225
227 }
228 }
virtual qint32 intSupport(qreal weightsPositionScale)
virtual qint32 intValueAt(qint32 t, qreal weightsPositionScale) const
int findMaxIndex(qint16 *buf, int size)
qreal toFloat() const
KisFixedPoint & from256Frac(qint32 v)
qint32 toInt() const
qint32 to256Frac() const
#define SANITY_ZEROS()
#define DEBUG_SAMPLE()
#define SANITY_CHECKSUM()
#define DEBUG_ALL()
#define SANITY_CENTER_POSITION()
int toInt(const QString &str, bool *ok=nullptr)

References KisFilterWeightsBuffer::FilterWeights::centerIndex, DEBUG_ALL, DEBUG_SAMPLE, findMaxIndex(), KisFixedPoint::from256Frac(), KisFilterStrategy::intSupport(), KisFilterStrategy::intValueAt(), KisFixedPoint::isInteger(), m_filterWeights, m_maxSpan, m_weightsPositionScale, SANITY_CENTER_POSITION, SANITY_CHECKSUM, SANITY_ZEROS, KisFilterWeightsBuffer::FilterWeights::span, KisFixedPoint::to256Frac(), KisFixedPoint::toFloat(), KisFixedPoint::toInt(), and KisFilterWeightsBuffer::FilterWeights::weight.

◆ ~KisFilterWeightsBuffer()

KisFilterWeightsBuffer::~KisFilterWeightsBuffer ( )
inline

Definition at line 230 of file kis_filter_weights_buffer.h.

230 {
231 delete[] m_filterWeights;
232 }

References m_filterWeights.

Member Function Documentation

◆ findMaxIndex()

int KisFilterWeightsBuffer::findMaxIndex ( qint16 * buf,
int size )
inlineprivate

Definition at line 261 of file kis_filter_weights_buffer.h.

261 {
262 int maxValue = buf[0];
263 int maxIndex = 0;
264
265 for (int i = 1; i < size; i++) {
266 if (buf[i] > maxValue) {
267 maxValue = buf[i];
268 maxIndex = i;
269 }
270 }
271
272 return maxIndex;
273 }
int size(const Forest< T > &forest)
Definition KisForest.h:1232

◆ maxSpan()

int KisFilterWeightsBuffer::maxSpan ( ) const
inline

The maximum width of the buffer that would be needed for calculation of a pixel value. In other words, the maximum number of support pixels that are needed for calculation of a single result pixel

Definition at line 247 of file kis_filter_weights_buffer.h.

247 {
248 return m_maxSpan;
249 }

References m_maxSpan.

◆ weights()

FilterWeights * KisFilterWeightsBuffer::weights ( KisFixedPoint pos) const
inline

Return a weights buffer for a particular value of offset

Definition at line 237 of file kis_filter_weights_buffer.h.

237 {
238 return m_filterWeights + pos.to256Frac();
239 }

References m_filterWeights, and KisFixedPoint::to256Frac().

◆ weightsPositionScale()

KisFixedPoint KisFilterWeightsBuffer::weightsPositionScale ( ) const
inline

The scale of the support buffer. Note that it is not always equal to the real scale of the transformation due to interpolation/blending difference.

Definition at line 256 of file kis_filter_weights_buffer.h.

256 {
258 }

References m_weightsPositionScale.

Member Data Documentation

◆ m_filterWeights

FilterWeights* KisFilterWeightsBuffer::m_filterWeights
private

Definition at line 276 of file kis_filter_weights_buffer.h.

◆ m_maxSpan

int KisFilterWeightsBuffer::m_maxSpan
private

Definition at line 277 of file kis_filter_weights_buffer.h.

◆ m_weightsPositionScale

KisFixedPoint KisFilterWeightsBuffer::m_weightsPositionScale
private

Definition at line 278 of file kis_filter_weights_buffer.h.


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