File indexing completed on 2024-05-12 15:58:19
0001 /* 0002 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt 0003 * SPDX-FileCopyrightText: 2005 Bart Coppens <kde@bartcoppens.be> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 #ifndef KIS_HISTOGRAM_ 0008 #define KIS_HISTOGRAM_ 0009 0010 #include <QVector> 0011 #include <QRect> 0012 0013 #include "KoHistogramProducer.h" 0014 0015 #include "kis_shared.h" 0016 #include "kis_types.h" 0017 #include "kritaimage_export.h" 0018 0019 enum enumHistogramType { 0020 LINEAR, 0021 LOGARITHMIC 0022 }; 0023 /** 0024 * The histogram class computes the histogram data from the specified layer 0025 * for the specified channel, through the use of a KoHistogramProducer. 0026 * This class is only for layers and paintdevices. KisImages are not supported, 0027 * but you can use the mergedImage function to create a paintdevice and feed that to this class. 0028 * 0029 * A Histogram also can have a selection: this is a specific range in the current histogram 0030 * that will get calculations done on it as well. If the range's begin and end are the same, 0031 * it is supposed to specify a single bin in the histogram. 0032 * 0033 * The calculations are done in the range 0 - 1, instead of the native range that a pixel 0034 * might have, so it's not always as precise as it could be. But you can't have it all... 0035 */ 0036 class KRITAIMAGE_EXPORT KisHistogram : public KisShared 0037 { 0038 0039 public: 0040 /** 0041 * Class that stores the result of histogram calculations. 0042 * Doubles are in the 0-1 range, use the producer's positionToString function to display it. 0043 **/ 0044 class Calculations 0045 { 0046 0047 double m_max {0.0}; 0048 double m_min {0.0}; 0049 double m_mean {0.0}; 0050 double m_total {0.0}; 0051 0052 quint32 m_high {0}; 0053 quint32 m_low {0}; 0054 quint32 m_count {0}; 0055 0056 friend class KisHistogram; 0057 0058 public: 0059 0060 Calculations() 0061 { 0062 } 0063 /** 0064 * This function return the maximum bound of the histogram 0065 * (values at greater position than the maximum are null) 0066 */ 0067 inline double getMax() { 0068 return m_max; 0069 } 0070 /** 0071 * This function return the minimum bound of the histogram 0072 * (values at smaller position than the minimum are null) 0073 */ 0074 inline double getMin() { 0075 return m_min; 0076 } 0077 /// This function return the highest value of the histogram 0078 inline quint32 getHighest() { 0079 return m_high; 0080 } 0081 /// This function return the lowest value of the histogram 0082 inline quint32 getLowest() { 0083 return m_low; 0084 } 0085 /// This function return the mean of value of the histogram 0086 inline double getMean() { 0087 return m_mean; 0088 } 0089 //double getMedian() { return m_median; } 0090 //double getStandardDeviation() { return m_stddev; } 0091 /// This function return the number of pixels used by the histogram 0092 inline quint32 getCount() { 0093 return m_count; 0094 } 0095 /** The sum of (the contents of every bin * the double value of that bin)*/ 0096 inline double getTotal() { 0097 return m_total; 0098 } 0099 //quint8 getPercentile() { return m_percentile; } // What is this exactly? XXX 0100 }; 0101 0102 KisHistogram(KisPaintLayerSP layer, 0103 KoHistogramProducer *producer, 0104 const enumHistogramType type); 0105 0106 KisHistogram(KisPaintDeviceSP paintdev, 0107 const QRect &bounds, 0108 KoHistogramProducer *producer, 0109 const enumHistogramType type); 0110 0111 virtual ~KisHistogram(); 0112 0113 /** Updates the information in the producer */ 0114 void updateHistogram(); 0115 0116 /** 0117 * (Re)computes the mathematical information from the information currently in the producer. 0118 * Needs to be called when you change the selection and want to get that information 0119 **/ 0120 void computeHistogram(); 0121 0122 /** The information on the entire view for the current channel */ 0123 Calculations calculations(); 0124 /** The information on the current selection for the current channel */ 0125 Calculations selectionCalculations(); 0126 0127 inline quint32 getValue(quint8 i) { 0128 return m_producer->getBinAt(m_channel, i); 0129 } 0130 0131 inline enumHistogramType getHistogramType() { 0132 return m_type; 0133 } 0134 inline void setHistogramType(enumHistogramType type) { 0135 m_type = type; 0136 } 0137 inline void setProducer(KoHistogramProducer *producer) { 0138 m_channel = 0; 0139 m_producer = producer; 0140 } 0141 inline void setChannel(qint32 channel) { 0142 Q_ASSERT(m_channel < m_completeCalculations.size()); 0143 m_channel = channel; 0144 } 0145 inline KoHistogramProducer *producer() { 0146 return m_producer; 0147 } 0148 inline qint32 channel() { 0149 return m_channel; 0150 } 0151 0152 inline bool hasSelection() { 0153 return m_selection; 0154 } 0155 inline double selectionFrom() { 0156 return m_selFrom; 0157 } 0158 inline double selectionTo() { 0159 return m_selTo; 0160 } 0161 inline void setNoSelection() { 0162 m_selection = false; 0163 } 0164 /** Sets the current selection */ 0165 inline void setSelection(double from, double to) { 0166 m_selection = true; m_selFrom = from; m_selTo = to; 0167 } 0168 0169 0170 private: 0171 // Dump the histogram to debug. 0172 void dump(); 0173 QVector<Calculations> calculateForRange(double from, double to); 0174 Calculations calculateSingleRange(int channel, double from, double to); 0175 0176 const KisPaintDeviceSP m_paintDevice; 0177 QRect m_bounds; 0178 KoHistogramProducer *m_producer {nullptr}; 0179 enumHistogramType m_type {LINEAR}; 0180 0181 qint32 m_channel {0}; 0182 double m_selFrom {0.0}; 0183 double m_selTo {0.0}; 0184 bool m_selection {false}; 0185 0186 QVector<Calculations> m_completeCalculations, m_selectionCalculations; 0187 }; 0188 0189 0190 #endif // KIS_HISTOGRAM_WIDGET_