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