krita
kis_histogram.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <kdebug.h>
00021 #include <qdatetime.h>
00022
00023 #include "kis_types.h"
00024 #include "kis_histogram.h"
00025 #include "kis_paint_layer.h"
00026 #include "kis_iterators_pixel.h"
00027 #include "kis_colorspace.h"
00028 #include "kis_debug_areas.h"
00029
00030 KisHistogram::KisHistogram(KisPaintLayerSP layer,
00031 KisHistogramProducerSP producer,
00032 const enumHistogramType type)
00033 {
00034 m_dev = layer->paintDevice();
00035 m_type = type;
00036 m_producer = producer;
00037 m_selection = false;
00038 m_channel = 0;
00039
00040 updateHistogram();
00041 }
00042
00043 KisHistogram::KisHistogram(KisPaintDeviceSP paintdev,
00044 KisHistogramProducerSP producer,
00045 const enumHistogramType type)
00046 {
00047 m_dev = paintdev;
00048 m_type = type;
00049 m_producer = producer;
00050 m_selection = false;
00051 m_channel = 0;
00052
00053 updateHistogram();
00054 }
00055
00056 KisHistogram::~KisHistogram()
00057 {
00058 }
00059
00060 void KisHistogram::updateHistogram()
00061 {
00062 Q_INT32 x,y,w,h;
00063 m_dev->exactBounds(x,y,w,h);
00064 KisRectIteratorPixel srcIt = m_dev->createRectIterator(x,y,w,h, false);
00065 KisColorSpace* cs = m_dev->colorSpace();
00066
00067 QTime t;
00068 t.start();
00069
00070
00071 m_producer->clear();
00072 int i;
00073
00074
00075 if (srcIt.isDone()) {
00076 m_producer->addRegionToBin(0, 0, 0, cs);
00077 } else {
00078 while ( !srcIt.isDone() ) {
00079 i = srcIt.nConseqPixels();
00080 m_producer->addRegionToBin(srcIt.rawData(), srcIt.selectionMask(), i, cs);
00081 srcIt += i;
00082 }
00083 }
00084
00085 computeHistogram();
00086 }
00087
00088 void KisHistogram::computeHistogram()
00089 {
00090 m_completeCalculations = calculateForRange(m_producer->viewFrom(),
00091 m_producer->viewFrom() + m_producer->viewWidth());
00092
00093 if (m_selection) {
00094 m_selectionCalculations = calculateForRange(m_selFrom, m_selTo);
00095 } else {
00096 m_selectionCalculations.clear();
00097 }
00098
00099 #if 1
00100 dump();
00101 #endif
00102 }
00103
00104 KisHistogram::Calculations KisHistogram::calculations() {
00105 return m_completeCalculations.at(m_channel);
00106 }
00107
00108 KisHistogram::Calculations KisHistogram::selectionCalculations() {
00109 return m_selectionCalculations.at(m_channel);
00110 }
00111
00112 QValueVector<KisHistogram::Calculations> KisHistogram::calculateForRange(double from, double to) {
00113 QValueVector<Calculations> calculations;
00114 uint count = m_producer->channels().count();
00115
00116 for (uint i = 0; i < count; i++) {
00117 calculations.append(calculateSingleRange(i, from, to));
00118 }
00119
00120 return calculations;
00121 }
00122
00123 KisHistogram::Calculations KisHistogram::calculateSingleRange(int channel, double from, double to) {
00124 Calculations c;
00125
00126
00127
00128 double max = from, min = to, total = 0.0, mean = 0.0;
00129 Q_UINT32 high = 0, low = (Q_UINT32) -1, count = 0;
00130
00131 if (m_producer->count() == 0) {
00132
00133
00134 return c;
00135 }
00136
00137 Q_INT32 totbins = m_producer->numberOfBins();
00138 Q_UINT32 current;
00139
00140
00141 double factor = static_cast<double>(totbins) / m_producer->viewWidth();
00142
00143 Q_INT32 fromBin = static_cast<Q_INT32>((from - m_producer->viewFrom()) * factor);
00144 Q_INT32 toBin = fromBin + static_cast<Q_INT32>((to - from) * factor);
00145
00146
00147 for (Q_INT32 i = fromBin; i < toBin; i++) {
00148 current = m_producer->getBinAt(channel, i);
00149 double pos = static_cast<double>(i) / factor + from;
00150 if (current > high)
00151 high = current;
00152 if (current < low)
00153 low = current;
00154 if (current > 0) {
00155 if (pos < min)
00156 min = pos;
00157 if (pos > max)
00158 max = pos;
00159 }
00160
00161
00162 count += current;
00163 total += current * pos;
00164 }
00165
00166 if (count > 0)
00167 mean = total / count;
00168
00169 c.m_high = high;
00170 c.m_low = low;
00171 c.m_count = count;
00172 c.m_min = min;
00173 c.m_max = max;
00174 c.m_mean = mean;
00175 c.m_total = total;
00176
00177 return c;
00178 }
00179
00180
00181 void KisHistogram::dump() {
00182 kdDebug(DBG_AREA_MATH) << "Histogram\n";
00183
00184 switch (m_type) {
00185 case LINEAR:
00186 kdDebug(DBG_AREA_MATH) << "Linear histogram\n";
00187 break;
00188 case LOGARITHMIC:
00189 kdDebug(DBG_AREA_MATH) << "Logarithmic histogram\n";
00190 }
00191
00192 kdDebug(DBG_AREA_MATH) << "Dumping channel " << m_channel << endl;
00193 Calculations c = calculations();
00194
00195
00196
00197
00198
00199
00200
00201
00202 kdDebug(DBG_AREA_MATH) << "\n";
00203
00204 kdDebug(DBG_AREA_MATH) << "Max: " << QString().setNum(c.getMax()) << "\n";
00205 kdDebug(DBG_AREA_MATH) << "Min: " << QString().setNum(c.getMin()) << "\n";
00206 kdDebug(DBG_AREA_MATH) << "High: " << QString().setNum(c.getHighest()) << "\n";
00207 kdDebug(DBG_AREA_MATH) << "Low: " << QString().setNum(c.getLowest()) << "\n";
00208 kdDebug(DBG_AREA_MATH) << "Mean: " << m_producer->positionToString(c.getMean()) << "\n";
00209 kdDebug(DBG_AREA_MATH) << "Total: " << QString().setNum(c.getTotal()) << "\n";
00210
00211
00212
00213
00214 kdDebug(DBG_AREA_MATH) << "\n";
00215 }
|