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_