File indexing completed on 2025-02-23 04:09:00

0001 /*
0002  *  SPDX-FileCopyrightText: 2009 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_IMAGE_PYRAMID
0008 #define __KIS_IMAGE_PYRAMID
0009 
0010 #include <QImage>
0011 #include <QVector>
0012 #include <QThreadStorage>
0013 
0014 #include <KoColorSpace.h>
0015 #include <kis_image.h>
0016 #include <kis_paint_device.h>
0017 #include "kis_projection_backend.h"
0018 
0019 
0020 class KisImagePyramid : QObject, public KisProjectionBackend
0021 {
0022     Q_OBJECT
0023 
0024 public:
0025     KisImagePyramid(qint32 pyramidHeight);
0026     ~KisImagePyramid() override;
0027 
0028     void setImage(KisImageWSP newImage) override;
0029     void setImageSize(qint32 w, qint32 h) override;
0030     void setMonitorProfile(const KoColorProfile* monitorProfile, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) override;
0031     void setChannelFlags(const QBitArray &channelFlags) override;
0032     void setDisplayFilter(QSharedPointer<KisDisplayFilter> displayFilter) override;
0033     void updateCache(const QRect &dirtyImageRect) override;
0034     void recalculateCache(KisPPUpdateInfoSP info) override;
0035 
0036     KisImagePatch getNearestPatch(KisPPUpdateInfoSP info) override;
0037     void drawFromOriginalImage(QPainter& gc, KisPPUpdateInfoSP info) override;
0038 
0039     /**
0040      * Render the projection onto a QImage.
0041      * Color profiling occurs here
0042      */
0043     QImage convertToQImage(qreal scale,
0044                            const QRect& unscaledRect,
0045                            enum Qt::TransformationMode transformMode);
0046 
0047     QImage convertToQImage(qreal scale,
0048                            qint32 unscaledX,
0049                            qint32 unscaledY,
0050                            qint32 unscaledWidth,
0051                            qint32 unscaledHeight);
0052 
0053     /**
0054      * Draw the projection onto a QPainter.
0055      * Color profiling occurs here
0056      */
0057     void drawImage(qreal scale,
0058                    QPainter& gc,
0059                    const QPoint& topLeftScaled,
0060                    const QRect& unscaledSourceRect);
0061 
0062     void alignSourceRect(QRect& rect, qreal scale) override;
0063 
0064 private:
0065 
0066     void retrieveImageData(const QRect &rect);
0067     void rebuildPyramid();
0068     void clearPyramid();
0069 
0070     /**
0071      * Downsamples @srcRect from @src paint device and writes
0072      * result into proper place of @dst paint device
0073      * Returns modified rect of @dst paintDevice
0074      */
0075     QRect downsampleByFactor2(const QRect& srcRect,
0076                               KisPaintDevice* src, KisPaintDevice* dst);
0077 
0078     /**
0079      * Auxiliary function. Downsamples two lines in @srcRow0
0080      * and @srcRow1 into one line @dstRow
0081      * Note: @numSrcPixels must be EVEN
0082      */
0083     void downsamplePixels(const quint8 *srcRow0, const quint8 *srcRow1,
0084                           quint8 *dstRow, qint32 numSrcPixels);
0085 
0086     /**
0087      * Searches for the last pyramid plane that can cover
0088      * canvas on current zoom level
0089      */
0090 
0091     int findFirstGoodPlaneIndex(qreal scale, QSize originalSize);
0092 
0093 
0094     /**
0095      * Fast workaround for converting paintDevices
0096      */
0097     QImage convertToQImageFast(KisPaintDeviceSP paintDevice,
0098                                const QRect& unscaledRect);
0099 
0100 private Q_SLOTS:
0101 
0102     void configChanged();
0103 
0104 private:
0105 
0106     QVector<KisPaintDeviceSP> m_pyramid;
0107     KisImageWSP  m_originalImage;
0108 
0109     const KoColorProfile* m_monitorProfile {0};
0110     const KoColorSpace* m_monitorColorSpace {0};
0111 
0112     QSharedPointer<KisDisplayFilter> m_displayFilter;
0113 
0114     KoColorConversionTransformation::Intent m_renderingIntent { KoColorConversionTransformation::IntentPerceptual };
0115     KoColorConversionTransformation::ConversionFlags m_conversionFlags { KoColorConversionTransformation::Empty };
0116 
0117 
0118     /**
0119      * Number of planes inside pyramid
0120      */
0121     qint32 m_pyramidHeight {0};
0122 
0123     bool m_useOcio {false};
0124 
0125     QBitArray m_channelFlags;
0126     bool m_allChannelsSelected {false};
0127     bool m_onlyOneChannelSelected {false};
0128     int m_selectedChannelIndex {-1};
0129 
0130 };
0131 
0132 #endif /* __KIS_IMAGE_PYRAMID */