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 */