File indexing completed on 2024-05-12 15:58:28

0001 /*
0002  *  This file is part of the KDE project
0003  *
0004  *  SPDX-FileCopyrightText: 2005 Cyrille Berger <cberger@cberger.net>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #ifndef KIS_MATH_TOOLBOX_H
0010 #define KIS_MATH_TOOLBOX_H
0011 
0012 #include <QObject>
0013 #include <QRect>
0014 
0015 #include <new>
0016 
0017 #include <KoColorSpace.h>
0018 
0019 #include "kis_types.h"
0020 #include "kis_paint_device.h"
0021 
0022 #ifdef _MSC_VER
0023 #pragma warning(disable: 4290) // disable "C++ exception specification ignored" warning
0024 #endif
0025 
0026 #if !defined _MSC_VER
0027 #pragma GCC diagnostic ignored "-Wcast-align"
0028 #endif
0029 
0030 typedef double(*PtrToDouble)(const quint8*, int);
0031 typedef void (*PtrFromDouble)(quint8*, int, double);
0032 typedef void (*PtrFromDoubleCheckNull)(quint8*, int, double, bool*);
0033 
0034 class KRITAIMAGE_EXPORT KisMathToolbox
0035 {
0036 
0037 public:
0038 
0039     struct KisFloatRepresentation {
0040 
0041         KisFloatRepresentation(uint nsize, uint ndepth)
0042             : coeffs(new float[nsize*nsize*ndepth])
0043             , size(nsize)
0044             , depth(ndepth) {
0045             // XXX: Valgrind shows that these are being used without being initialised.
0046             for (quint32 i = 0; i < nsize * nsize * ndepth; ++i) {
0047                 coeffs[i] = 0;
0048             }
0049         }
0050 
0051         ~KisFloatRepresentation() {
0052             if (coeffs) delete[] coeffs;
0053         }
0054 
0055         float* coeffs;
0056         uint size;
0057         uint depth;
0058     };
0059 
0060     typedef KisFloatRepresentation KisWavelet;
0061 
0062     /**
0063      * This function initializes a wavelet structure
0064      * @param lay the layer that will be used for the transformation
0065      * @param rect the rectangular for transformation
0066      */
0067     inline KisWavelet* initWavelet(KisPaintDeviceSP lay, const QRect&);
0068 
0069     inline uint fastWaveletTotalSteps(const QRect&);
0070 
0071     /**
0072      * This function reconstruct the layer from the information of a wavelet
0073      * @param src layer from which the wavelet will be computed
0074      * @param rect the rectangular for reconstruction
0075      * @param buff if set to 0, the buffer will be initialized by the function,
0076      * you might want to give a buff to the function if you want to use the same buffer
0077      * in transformToWavelet and in untransformToWavelet, use initWavelet to initialize
0078      * the buffer
0079      */
0080     KisWavelet* fastWaveletTransformation(KisPaintDeviceSP src, const QRect&, KisWavelet* buff = 0);
0081 
0082     /**
0083      * This function reconstruct the layer from the information of a wavelet
0084      * @param dst layer on which the wavelet will be untransform
0085      * @param rect the rectangular for reconstruction
0086      * @param wav the wavelet
0087      * @param buff if set to 0, the buffer will be initialized by the function,
0088      * you might want to give a buff to the function if you want to use the same buffer
0089      * in transformToWavelet and in untransformToWavelet, use initWavelet to initialize
0090      * the buffer
0091      */
0092     void fastWaveletUntransformation(KisPaintDeviceSP dst, const QRect&, KisWavelet* wav, KisWavelet* buff = 0);
0093 
0094     bool getToDoubleChannelPtr(QList<KoChannelInfo *> cis, QVector<PtrToDouble>& f);
0095     bool getFromDoubleChannelPtr(QList<KoChannelInfo *> cis, QVector<PtrFromDouble>& f);
0096     bool getFromDoubleCheckNullChannelPtr(QList<KoChannelInfo *> cis, QVector<PtrFromDoubleCheckNull>& f);
0097 
0098     double minChannelValue(KoChannelInfo *);
0099     double maxChannelValue(KoChannelInfo *);
0100 
0101 private:
0102 
0103     void wavetrans(KisWavelet* wav, KisWavelet* buff, uint halfsize);
0104     void waveuntrans(KisWavelet* wav, KisWavelet* buff, uint halfsize);
0105 
0106     /**
0107      * This function transform a paint device into a KisFloatRepresentation, this function is colorspace independent,
0108      * for Wavelet, Pyramid and FFT the data is always the exact value of the channel stored in a float.
0109      */
0110     void transformToFR(KisPaintDeviceSP src, KisFloatRepresentation*, const QRect&);
0111 
0112     /**
0113      * This function transform a KisFloatRepresentation into a paint device, this function is colorspace independent,
0114      * for Wavelet, Pyramid and FFT the data is always the exact value of the channel stored in a float.
0115      */
0116     void transformFromFR(KisPaintDeviceSP dst, KisFloatRepresentation*, const QRect&);
0117 
0118 };
0119 
0120 inline KisMathToolbox::KisWavelet* KisMathToolbox::initWavelet(KisPaintDeviceSP src, const QRect& rect)
0121 {
0122     int size;
0123     int maxrectsize = (rect.height() < rect.width()) ? rect.width() : rect.height();
0124     for (size = 2; size < maxrectsize; size *= 2) ;
0125     qint32 depth = src->colorSpace()->colorChannelCount();
0126     return new KisWavelet(size, depth);
0127 }
0128 
0129 inline uint KisMathToolbox::fastWaveletTotalSteps(const QRect& rect)
0130 {
0131     int size, steps;
0132     int maxrectsize = (rect.height() < rect.width()) ? rect.width() : rect.height();
0133     steps = 0;
0134     for (size = 2; size < maxrectsize; size *= 2) steps += size / 2; ;
0135     return steps;
0136 }
0137 
0138 #endif