File indexing completed on 2024-05-12 15:59:30
0001 /* 0002 * SPDX-FileCopyrightText: 2005 Bart Coppens <kde@bartcoppens.be> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #ifndef _Ko_BASIC_HISTOGRAM_PRODUCERS_ 0008 #define _Ko_BASIC_HISTOGRAM_PRODUCERS_ 0009 0010 #include "KoHistogramProducer.h" 0011 0012 #include <QVector> 0013 0014 #include <KoConfig.h> 0015 0016 #include "KoColorSpace.h" 0017 #include "KoID.h" 0018 #include "kritapigment_export.h" 0019 #include "KoColorSpaceRegistry.h" 0020 0021 class KRITAPIGMENT_EXPORT KoBasicHistogramProducer : public KoHistogramProducer 0022 { 0023 public: 0024 explicit KoBasicHistogramProducer(const KoID& id, int channelCount, int nrOfBins); 0025 explicit KoBasicHistogramProducer(const KoID& id, int nrOfBins, const KoColorSpace *colorSpace); 0026 ~KoBasicHistogramProducer() override {} 0027 0028 void clear() override; 0029 0030 void setView(qreal from, qreal size) override { 0031 m_from = from; m_width = size; 0032 } 0033 0034 const KoID& id() const override { 0035 return m_id; 0036 } 0037 QList<KoChannelInfo *> channels() override { 0038 return m_colorSpace->channels(); 0039 } 0040 qint32 numberOfBins() override { 0041 return m_nrOfBins; 0042 } 0043 qreal viewFrom() const override { 0044 return m_from; 0045 } 0046 qreal viewWidth() const override { 0047 return m_width; 0048 } 0049 0050 qint32 count() override { 0051 return m_count; 0052 } 0053 0054 qint32 getBinAt(int channel, int position) override { 0055 return m_bins.at(externalToInternal(channel)).at(position); 0056 } 0057 0058 qint32 outOfViewLeft(int channel) override { 0059 return m_outLeft.at(externalToInternal(channel)); 0060 } 0061 0062 qint32 outOfViewRight(int channel) override { 0063 return m_outRight.at(externalToInternal(channel)); 0064 } 0065 0066 protected: 0067 /** 0068 * The order in which channels() returns is not the same as the internal representation, 0069 * that of the pixel internally. This method converts external usage to internal usage. 0070 * This method uses some basic assumptions about the layout of the pixel, so _extremely_ 0071 * exotic spaces might want to override this (see makeExternalToInternal source for 0072 * those assumptions) 0073 **/ 0074 virtual int externalToInternal(int ext) { 0075 if (channels().count() > 0 && m_external.count() == 0) // Set up the translation table 0076 makeExternalToInternal(); 0077 return m_external.at(ext); 0078 } 0079 // not virtual since that is useless: we call it from constructor 0080 void makeExternalToInternal(); 0081 typedef QVector<quint32> vBins; 0082 QVector<vBins> m_bins; 0083 vBins m_outLeft, m_outRight; 0084 qreal m_from, m_width; 0085 qint32 m_count; 0086 int m_channels, m_nrOfBins; 0087 const KoColorSpace *m_colorSpace; 0088 KoID m_id; 0089 QVector<qint32> m_external; 0090 }; 0091 0092 class KRITAPIGMENT_EXPORT KoBasicU8HistogramProducer : public KoBasicHistogramProducer 0093 { 0094 public: 0095 KoBasicU8HistogramProducer(const KoID& id, const KoColorSpace *colorSpace); 0096 ~KoBasicU8HistogramProducer() override {} 0097 void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; 0098 QString positionToString(qreal pos) const override; 0099 qreal maximalZoom() const override { 0100 return 1.0; 0101 } 0102 }; 0103 0104 class KRITAPIGMENT_EXPORT KoBasicU16HistogramProducer : public KoBasicHistogramProducer 0105 { 0106 public: 0107 KoBasicU16HistogramProducer(const KoID& id, const KoColorSpace *colorSpace); 0108 ~KoBasicU16HistogramProducer() override {} 0109 void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; 0110 QString positionToString(qreal pos) const override; 0111 qreal maximalZoom() const override; 0112 }; 0113 0114 class KRITAPIGMENT_EXPORT KoBasicF32HistogramProducer : public KoBasicHistogramProducer 0115 { 0116 public: 0117 KoBasicF32HistogramProducer(const KoID& id, const KoColorSpace *colorSpace); 0118 ~KoBasicF32HistogramProducer() override {} 0119 void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; 0120 QString positionToString(qreal pos) const override; 0121 qreal maximalZoom() const override; 0122 }; 0123 0124 0125 #ifdef HAVE_OPENEXR 0126 class KRITAPIGMENT_EXPORT KoBasicF16HalfHistogramProducer : public KoBasicHistogramProducer 0127 { 0128 public: 0129 KoBasicF16HalfHistogramProducer(const KoID& id, const KoColorSpace *colorSpace); 0130 ~KoBasicF16HalfHistogramProducer() override {} 0131 void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; 0132 QString positionToString(qreal pos) const override; 0133 qreal maximalZoom() const override; 0134 }; 0135 #endif 0136 0137 /** 0138 * Parametrized on a specific KoHistogramProducer. Its generated producers 0139 * will have the same KoID as the factory's. This is acceptable because we can't mix 0140 * Factories with Producers in the code because they are incompatible types, and 0141 * in the GUI we actually only need a producer's name, not a factory's. 0142 */ 0143 template<class T> class KoBasicHistogramProducerFactory : public KoHistogramProducerFactory 0144 { 0145 public: 0146 KoBasicHistogramProducerFactory(const KoID& id, const QString& modelId, const QString& depthId ) 0147 : KoHistogramProducerFactory(id), m_modelId(modelId), m_depthId(depthId) { 0148 } 0149 ~KoBasicHistogramProducerFactory() override {} 0150 0151 KoHistogramProducer *generate() override { 0152 KoHistogramProducer *producer = 0; 0153 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(m_modelId, m_depthId, 0); 0154 if (cs) { 0155 producer = new T(KoID(id(), name()), cs); 0156 } 0157 return producer; 0158 0159 } 0160 bool isCompatibleWith(const KoColorSpace* colorSpace, bool strict = false) const override { 0161 if( strict ){ 0162 return colorSpace->colorDepthId().id() == m_depthId; 0163 } 0164 return colorSpace->colorModelId().id() == m_modelId || colorSpace->colorDepthId().id() == m_depthId; 0165 } 0166 float preferrednessLevelWith(const KoColorSpace* colorSpace) const override { 0167 return 0.5 * ( (colorSpace->colorModelId().id() == m_modelId) + (colorSpace->colorDepthId().id() == m_depthId) ); 0168 } 0169 protected: 0170 QString m_modelId, m_depthId; 0171 }; 0172 0173 /** 0174 * This is a Producer (with associated factory) that converts the pixels of the colorspace 0175 * to RGB8 with toQColor, and then does its counting on RGB. This is NOT registered with the 0176 * Registry, because it isCompatibleWith all colorspaces, and should only be used in extreme 0177 * cases (like no other producer being available 0178 **/ 0179 class KRITAPIGMENT_EXPORT KoGenericRGBHistogramProducer : public KoBasicHistogramProducer 0180 { 0181 public: 0182 KoGenericRGBHistogramProducer(); 0183 ~KoGenericRGBHistogramProducer() override {} 0184 void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; 0185 QString positionToString(qreal pos) const override; 0186 qreal maximalZoom() const override; 0187 QList<KoChannelInfo *> channels() override; 0188 protected: 0189 QList<KoChannelInfo *> m_channelsList; 0190 }; 0191 0192 /** KoGenericRGBHistogramProducer his special Factory that isCompatibleWith everything. */ 0193 class KRITAPIGMENT_EXPORT KoGenericRGBHistogramProducerFactory : public KoHistogramProducerFactory 0194 { 0195 public: 0196 KoGenericRGBHistogramProducerFactory(); 0197 0198 ~KoGenericRGBHistogramProducerFactory() override {} 0199 0200 KoHistogramProducer *generate() override { 0201 return new KoGenericRGBHistogramProducer(); 0202 } 0203 0204 bool isCompatibleWith(const KoColorSpace*, bool strict = false) const override { 0205 Q_UNUSED(strict); 0206 return true; 0207 } 0208 0209 float preferrednessLevelWith(const KoColorSpace*) const override { 0210 return 0.0; 0211 } 0212 }; 0213 0214 0215 /** 0216 * This is a Producer (with associated factory) that converts the pixels of the colorspace 0217 * to L*a*b*, and then does its counting. 0218 * It isCompatibleWith all colorspaces 0219 **/ 0220 class KRITAPIGMENT_EXPORT KoGenericLabHistogramProducer : public KoBasicHistogramProducer 0221 { 0222 public: 0223 KoGenericLabHistogramProducer(); 0224 ~KoGenericLabHistogramProducer() override; 0225 void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; 0226 QString positionToString(qreal pos) const override; 0227 qreal maximalZoom() const override; 0228 QList<KoChannelInfo *> channels() override; 0229 protected: 0230 QList<KoChannelInfo *> m_channelsList; 0231 }; 0232 0233 /** KoGenericLabHistogramProducer his special Factory that isCompatibleWith everything. */ 0234 class /*KRITAPIGMENT_EXPORT*/ KoGenericLabHistogramProducerFactory : public KoHistogramProducerFactory 0235 { 0236 public: 0237 KoGenericLabHistogramProducerFactory(); 0238 ~KoGenericLabHistogramProducerFactory() override {} 0239 0240 KoHistogramProducer *generate() override { 0241 return new KoGenericLabHistogramProducer(); 0242 } 0243 0244 bool isCompatibleWith(const KoColorSpace*, bool strict = false) const override { 0245 Q_UNUSED(strict); 0246 return true; 0247 } 0248 0249 float preferrednessLevelWith(const KoColorSpace*) const override { 0250 return 0.0; 0251 } 0252 }; 0253 0254 0255 #endif // _Ko_BASIC_HISTOGRAM_PRODUCERS_