Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_histogram.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt
3 * SPDX-FileCopyrightText: 2005 Bart Coppens <kde@bartcoppens.be>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#include "kis_histogram.h"
9
10#include <QVector>
11
12#include "kis_image.h"
13#include "kis_paint_layer.h"
14#include "kis_paint_device.h"
15#include "KoColorSpace.h"
16#include "kis_debug.h"
17#include "kis_iterator_ng.h"
18
20 KoHistogramProducer *producer,
21 const enumHistogramType type)
22 : m_paintDevice(layer->projection())
23{
24 Q_ASSERT(producer);
25
26 KisImageSP imageSP = layer->image().toStrongRef();
27 if (imageSP) {
28 m_bounds = imageSP->bounds();
29 }
30 m_type = type;
32 m_selection = false;
33 m_channel = 0;
34
36}
37
39 const QRect &bounds,
40 KoHistogramProducer *producer,
41 const enumHistogramType type)
42 : m_paintDevice(paintdev)
43{
44 Q_ASSERT(producer);
45
48 m_type = type;
49
50 m_selection = false;
51 m_channel = 0;
52
53 // TODO: Why does Krita crash when updateHistogram() is *not* called here?
55}
56
61
63{
64 if (m_bounds.isEmpty()) {
65 int numChannels = m_producer->channels().count();
66
68 m_completeCalculations.resize(numChannels);
69
71 m_completeCalculations.resize(numChannels);
72
73 return;
74 }
75
78
79 // Let the producer do it's work
81
82
83 // XXX: the original code depended on their being a selection mask in the iterator
84 // if the paint device had a selection. When we changed that to passing an
85 // explicit selection to the createRectIterator call, that broke because
86 // paint devices didn't know about their selections anymore.
87 // updateHistogram should get a selection parameter.
88 int numConseqPixels = srcIt.nConseqPixels();
89 while (srcIt.nextPixels(numConseqPixels)) {
90
91 numConseqPixels = srcIt.nConseqPixels();
92 m_producer->addRegionToBin(srcIt.oldRawData(), 0, numConseqPixels, cs);
93 }
94
96}
97
99{
100 if (!m_producer) return;
101
104
105 if (m_selection) {
107 } else {
109 }
110
111#if 1
112 dump();
113#endif
114}
115
120
125
127{
129 if (m_producer) {
130 uint count = m_producer->channels().count();
131
132 for (uint i = 0; i < count; i++) {
133 calculations.append(calculateSingleRange(i, from, to));
134 }
135 }
136 return calculations;
137}
138
140{
141 Calculations c;
142
143 // XXX If from == to, we only want a specific bin, handle that properly!
144
145 double max = from, min = to, total = 0.0, mean = 0.0; //, median = 0.0, stddev = 0.0;
146 quint32 high = 0, low = (quint32) - 1, count = 0;
147
148 if (m_producer->count() == 0) {
149 // We won't get anything, even if a range is specified
150 // XXX make sure all initial '0' values are correct here!
151 return c;
152 }
153
154 qint32 totbins = m_producer->numberOfBins();
155 quint32 current;
156
157 // convert the double range into actual bins:
158 double factor = static_cast<double>(totbins) / m_producer->viewWidth();
159
160 qint32 fromBin = static_cast<qint32>((from - m_producer->viewFrom()) * factor);
161 qint32 toBin = fromBin + static_cast<qint32>((to - from) * factor);
162
163 // Min, max, count, low, high
164 for (qint32 i = fromBin; i < toBin; i++) {
165 current = m_producer->getBinAt(channel, i);
166 double pos = static_cast<double>(i) / factor + from;
167 if (current > high)
168 high = current;
169 if (current < low)
170 low = current;
171 if (current > 0) {
172 if (pos < min)
173 min = pos;
174 if (pos > max)
175 max = pos;
176 }
177 // We do the count here as well.
178 // we can't use m_producer->count() for this, because of the range
179 count += current;
180 total += current * pos;
181 }
182
183 if (count > 0)
184 mean = total / count;
185
186 c.m_high = high;
187 c.m_low = low;
188 c.m_count = count;
189 c.m_min = min;
190 c.m_max = max;
191 c.m_mean = mean;
192 c.m_total = total;
193
194 return c;
195}
196
197
199{
200 dbgMath << "Histogram";
201
202 switch (m_type) {
203 case LINEAR:
204 dbgMath << "Linear histogram";
205 break;
206 case LOGARITHMIC:
207 dbgMath << "Logarithmic histogram";
208 }
209
210 dbgMath << "Dumping channel" << m_channel;
212
213 /* for( int i = 0; i <256; ++i ) {
214 dbgMath <<"Value"
215 << QString().setNum(i)
216 << ": "
217 << QString().setNum(m_values[i])
218 << "\n";
219 }*/
220 dbgMath << "";
221
222 dbgMath << "Max:" << QString().setNum(c.getMax()) << "";
223 dbgMath << "Min:" << QString().setNum(c.getMin()) << "";
224 dbgMath << "High:" << QString().setNum(c.getHighest()) << "";
225 dbgMath << "Low:" << QString().setNum(c.getLowest()) << "";
226 dbgMath << "Mean:" << m_producer->positionToString(c.getMean()) << "";
227 dbgMath << "Total:" << QString().setNum(c.getTotal()) << "";
228 // dbgMath <<"Median:" << QString().setNum(m_median) <<"";
229 // dbgMath <<"Stddev:" << QString().setNum(m_stddev) <<"";
230 // dbgMath <<"percentile:" << QString().setNum(m_percentile) <<"";
231
232 dbgMath << "";
233}
unsigned int uint
double getMean()
This function return the mean of value of the histogram.
quint32 getHighest()
This function return the highest value of the histogram.
quint32 getLowest()
This function return the lowest value of the histogram.
virtual ~KisHistogram()
KoHistogramProducer * producer()
QVector< Calculations > m_completeCalculations
qint32 channel()
const KisPaintDeviceSP m_paintDevice
Calculations selectionCalculations()
QVector< Calculations > m_selectionCalculations
Calculations calculateSingleRange(int channel, double from, double to)
enumHistogramType m_type
void computeHistogram()
KoHistogramProducer * m_producer
QVector< Calculations > calculateForRange(double from, double to)
Calculations calculations()
KisHistogram(KisPaintLayerSP layer, KoHistogramProducer *producer, const enumHistogramType type)
void updateHistogram()
QRect bounds() const override
const KoColorSpace * colorSpace() const
ALWAYS_INLINE const quint8 * oldRawData() const
KisSharedPtr< T > toStrongRef() const
toStrongRef returns a KisSharedPtr which may be dereferenced.
virtual void clear()=0
virtual qreal viewFrom() const =0
virtual qint32 getBinAt(qint32 channel, qint32 position)=0
virtual qint32 numberOfBins()=0
virtual QList< KoChannelInfo * > channels()=0
virtual QString positionToString(qreal pos) const =0
virtual void addRegionToBin(const quint8 *pixels, const quint8 *selectionMask, quint32 nPixels, const KoColorSpace *colorSpace)=0
virtual qreal viewWidth() const =0
virtual qint32 count()=0
#define bounds(x, a, b)
#define dbgMath
Definition kis_debug.h:54
enumHistogramType
@ LOGARITHMIC
@ LINEAR
KisImageWSP image