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

0001 /*
0002  *  SPDX-FileCopyrightText: 2002 patrick julien <freak@codepimps.org>
0003  *  SPDX-FileCopyrightText: 2006 Boudewijn Rempt <boud@valdyas.org>
0004  *  SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 #ifndef KIS_PAINT_DEVICE_IMPL_H_
0009 #define KIS_PAINT_DEVICE_IMPL_H_
0010 
0011 #include <QObject>
0012 #include <QRect>
0013 #include <QVector>
0014 
0015 #include "kis_debug.h"
0016 
0017 #include <KoColorConversionTransformation.h>
0018 
0019 #include "kis_types.h"
0020 #include "kis_shared.h"
0021 #include "kis_default_bounds_base.h"
0022 
0023 #include <kritaimage_export.h>
0024 
0025 class KUndo2Command;
0026 class QRect;
0027 class QImage;
0028 class QPoint;
0029 class QString;
0030 class QColor;
0031 class QIODevice;
0032 
0033 class KoColor;
0034 class KoColorSpace;
0035 class KoColorProfile;
0036 
0037 class KisRegion;
0038 class KisDataManager;
0039 class KisPaintDeviceWriter;
0040 class KisKeyframe;
0041 class KisRasterKeyframeChannel;
0042 
0043 class KisPaintDeviceFramesInterface;
0044 
0045 class KisInterstrokeData;
0046 using KisInterstrokeDataSP = QSharedPointer<KisInterstrokeData>;
0047 
0048 typedef KisSharedPtr<KisDataManager> KisDataManagerSP;
0049 
0050 namespace KritaUtils {
0051 enum DeviceCopyMode {
0052     CopySnapshot = 0,
0053     CopyAllFrames
0054 };
0055 }
0056 
0057 
0058 /**
0059  * A paint device contains the actual pixel data and offers methods
0060  * to read and write pixels. A paint device has an integer x, y position
0061  * (it is not positioned on the image with sub-pixel accuracy).
0062  * A KisPaintDevice doesn't have any fixed size, the size changes dynamically
0063  * when pixels are accessed by an iterator.
0064  */
0065 class KRITAIMAGE_EXPORT KisPaintDevice
0066     : public QObject
0067     , public KisShared
0068 {
0069 
0070     Q_OBJECT
0071 
0072 public:
0073 
0074     /**
0075      * Create a new paint device with the specified colorspace.
0076      *
0077      * @param colorSpace the colorspace of this paint device
0078      * @param name for debugging purposes
0079      */
0080     explicit KisPaintDevice(const KoColorSpace * colorSpace, const QString& name = QString());
0081 
0082     /**
0083      * Create a new paint device with the specified colorspace. The
0084      * parent node will be notified of changes to this paint device.
0085      *
0086      * @param parent the node that contains this paint device
0087      * @param colorSpace the colorspace of this paint device
0088      * @param defaultBounds boundaries of the device in case it is empty
0089      * @param name for debugging purposes
0090      */
0091     KisPaintDevice(KisNodeWSP parent, const KoColorSpace * colorSpace, KisDefaultBoundsBaseSP defaultBounds = KisDefaultBoundsBaseSP(), const QString& name = QString());
0092 
0093     /**
0094      * Creates a copy of this device.
0095      *
0096      * If \p copyMode is CopySnapshot, the newly created device clones the
0097      * current frame of \p rhs only (default and efficient
0098      * behavior). If \p copyFrames is CopyAllFrames, the new device is a deep
0099      * copy of the source with all the frames included.
0100      */
0101     KisPaintDevice(const KisPaintDevice& rhs, KritaUtils::DeviceCopyMode copyMode = KritaUtils::CopySnapshot, KisNode *newParentNode = 0);
0102     ~KisPaintDevice() override;
0103 
0104     void makeFullCopyFrom(const KisPaintDevice& rhs, KritaUtils::DeviceCopyMode copyMode = KritaUtils::CopySnapshot, KisNode *newParentNode = 0);
0105 
0106 protected:
0107     /**
0108      * A special constructor for usage in KisPixelSelection. It allows
0109      * two paint devices to share a data manager.
0110      *
0111      * @param explicitDataManager data manager to use inside paint device
0112      * @param src source paint device to copy parameters from
0113      * @param name for debugging purposes
0114      */
0115     KisPaintDevice(KisDataManagerSP explicitDataManager,
0116                    KisPaintDeviceSP src, const QString& name = QString());
0117 
0118 public:
0119 
0120     /**
0121      * Write the pixels of this paint device into the specified file store.
0122      */
0123     bool write(KisPaintDeviceWriter &store);
0124 
0125     /**
0126      * Fill this paint device with the pixels from the specified file store.
0127      */
0128     bool read(QIODevice *stream);
0129 
0130 public:
0131 
0132     /**
0133      * set the parent node of the paint device
0134      */
0135     void setParentNode(KisNodeWSP parent);
0136 
0137     /**
0138      * set the default bounds for the paint device when
0139      * the default pixel is not completely transparent
0140      */
0141     void setDefaultBounds(KisDefaultBoundsBaseSP bounds);
0142 
0143     /**
0144      * the default bounds rect of the paint device
0145      */
0146     KisDefaultBoundsBaseSP defaultBounds() const;
0147 
0148     /**
0149      * Moves the device to these new coordinates (no incremental move)
0150      */
0151     void moveTo(qint32 x, qint32 y);
0152 
0153     /**
0154      * Convenience method for the above.
0155      */
0156     virtual void moveTo(const QPoint& pt);
0157 
0158     /**
0159      * Return an X,Y offset of the device in a convenient form
0160      */
0161     QPoint offset() const;
0162 
0163     /**
0164      * The X offset of the paint device
0165      */
0166     qint32 x() const;
0167 
0168     /**
0169      * The Y offset of the paint device
0170      */
0171     qint32 y() const;
0172 
0173     /**
0174      * set the X offset of the paint device
0175      */
0176     void setX(qint32 x);
0177 
0178     /**
0179      * set the Y offset of the paint device
0180      */
0181     void setY(qint32 y);
0182 
0183     /**
0184      * Retrieve the bounds of the paint device. The size is not exact,
0185      * but may be larger if the underlying datamanager works that way.
0186      * For instance, the tiled datamanager keeps the extent to the nearest
0187      * multiple of 64.
0188      *
0189      * If default pixel is not transparent, then the actual extent
0190      * rect is united with the defaultBounds()->bounds() value
0191      * (the size of the image, usually).
0192      */
0193     QRect extent() const;
0194 
0195     /// Convenience method for the above
0196     void extent(qint32 &x, qint32 &y, qint32 &w, qint32 &h) const;
0197 
0198     /**
0199      * Get the exact bounds of this paint device. The real solution is
0200      * very slow because it does a linear scanline search, but it
0201      * uses caching, so calling to this function without changing
0202      * the device is quite cheap.
0203      *
0204      * Exactbounds follows these rules:
0205      *
0206      * <ul>
0207      * <li>if default pixel is transparent, then exact bounds
0208      *     of actual pixel data are returned
0209      * <li>if default pixel is not transparent, then the union
0210      *     (defaultBounds()->bounds() | nonDefaultPixelArea()) is
0211      *     returned
0212      * </ul>
0213      * \see calculateExactBounds()
0214      */
0215     QRect exactBounds() const;
0216 
0217     /**
0218      * Relaxed version of the exactBounds() that can be used in tight
0219      * loops.  If the exact bounds value is present in the paint
0220      * device cache, returns this value.  If the cache is invalidated,
0221      * returns extent() and tries to recalculate the exact bounds not
0222      * faster than once in 1000 ms.
0223      */
0224     QRect exactBoundsAmortized() const;
0225 
0226     /**
0227      * Returns exact rectangle of the paint device that contains
0228      * non-default pixels. For paint devices with fully transparent
0229      * default pixel is equivalent to exactBounds().
0230      *
0231      * nonDefaultPixelArea() follows these rules:
0232      *
0233      * <ul>
0234      * <li>if default pixel is transparent, then exact bounds
0235      *     of actual pixel data are returned. The same as exactBounds()
0236      * <li>if default pixel is not transparent, then calculates the
0237      *     rectangle of non-default pixels. May be smaller or greater
0238      *     than image bounds
0239      * </ul>
0240      * \see calculateExactBounds()
0241      */
0242     QRect nonDefaultPixelArea() const;
0243 
0244 
0245     /**
0246      * Returns a rough approximation of region covered by device.
0247      * For tiled data manager, it region will consist of a number
0248      * of rects each corresponding to a tile.
0249      */
0250     KisRegion region() const;
0251 
0252     /**
0253      * The slow version of region() that searches for exact bounds of
0254      * each rectangle in the region
0255      */
0256     KisRegion regionExact() const;
0257 
0258     /**
0259      * Cut the paint device down to the specified rect. If the crop
0260      * area is bigger than the paint device, nothing will happen.
0261      */
0262     void crop(qint32 x, qint32 y, qint32 w, qint32 h);
0263 
0264     /// Convenience method for the above
0265     void crop(const QRect & r);
0266 
0267     /**
0268      * Complete erase the current paint device. Its size will become 0. This
0269      * does not take the selection into account.
0270      */
0271     virtual void clear();
0272 
0273     /**
0274      * Clear the given rectangle to transparent black. The paint device will expand to
0275      * contain the given rect.
0276      */
0277     void clear(const QRect & rc);
0278 
0279     /**
0280      * Frees the memory occupied by the pixels containing default
0281      * values. The extents() and exactBounds() of the paint device will
0282      * probably also shrink
0283      */
0284     void purgeDefaultPixels();
0285 
0286     /**
0287      * Sets the default pixel. New data will be initialised with this pixel. The pixel is copied: the
0288      * caller still owns the pointer and needs to delete it to avoid memory leaks.
0289      * If frame ID is given, set default pixel for that frame. Otherwise use active frame.
0290      */
0291     void setDefaultPixel(const KoColor &defPixel);
0292 
0293     /**
0294      * Get a pointer to the default pixel.
0295      * If the frame parameter is given, get the default pixel of
0296      * specified frame. Otherwise use currently active frame.
0297      */
0298     KoColor defaultPixel() const;
0299 
0300     /**
0301      * Fill the given rectangle with the given pixel. The paint device will expand to
0302      * contain the given rect.
0303      */
0304     void fill(const QRect & rc, const KoColor &color);
0305 
0306     /**
0307      * Overloaded function. For legacy purposes only.
0308      * Please use fill(const QRect & rc, const KoColor &color) instead
0309      */
0310     void fill(qint32 x, qint32 y, qint32 w, qint32 h, const quint8 *fillPixel);
0311 
0312 public:
0313 
0314     /**
0315      * Prepares the device for fastBitBlt operation. It clears
0316      * the device, switches x,y shifts and colorspace if needed.
0317      * After this call fastBitBltPossible will return true.
0318      * May be used for initialization of temporary devices.
0319      */
0320     void prepareClone(KisPaintDeviceSP src);
0321 
0322     /**
0323      * Make this device to become a clone of \a src. It will have the same
0324      * x,y shifts, colorspace and will share pixels inside \a rect.
0325      * After calling this function:
0326      * (this->extent() >= this->exactBounds() == rect).
0327      *
0328      * Rule of thumb:
0329      *
0330      * "Use makeCloneFrom() or makeCloneFromRough() if and only if you
0331      * are the only owner of the destination paint device and you are
0332      * 100% sure no other thread has access to it"
0333      */
0334     void makeCloneFrom(KisPaintDeviceSP src, const QRect &rect);
0335 
0336     /**
0337      * Make this device to become a clone of \a src. It will have the same
0338      * x,y shifts, colorspace and will share pixels inside \a rect.
0339      * Be careful, this function will copy *at least* \a rect
0340      * of pixels. Actual copy area will be a bigger - it will
0341      * be aligned by tiles borders. So after calling this function:
0342      * (this->extent() == this->exactBounds() >= rect).
0343      *
0344      * Rule of thumb:
0345      *
0346      * "Use makeCloneFrom() or makeCloneFromRough() if and only if you
0347      * are the only owner of the destination paint device and you are
0348      * 100% sure no other thread has access to it"
0349      */
0350     void makeCloneFromRough(KisPaintDeviceSP src, const QRect &minimalRect);
0351 
0352 
0353 protected:
0354     friend class KisPaintDeviceTest;
0355     friend class DataReaderThread;
0356 
0357     /**
0358      * Checks whether a src paint device can be used as source
0359      * of fast bitBlt operation. The result of the check may
0360      * depend on whether color spaces coincide, whether there is
0361      * any shift of tiles between the devices and etc.
0362      *
0363      * WARNING: This check must be done <i>before</i> performing any
0364      * fast bitBlt operation!
0365      *
0366      * \see fastBitBlt
0367      * \see fastBitBltRough
0368      */
0369     bool fastBitBltPossible(KisPaintDeviceSP src);
0370 
0371     /**
0372      * Clones rect from another paint device. The cloned area will be
0373      * shared between both paint devices as much as possible using
0374      * copy-on-write. Parts of the rect that cannot be shared
0375      * (cross tiles) are deep-copied,
0376      *
0377      * \see fastBitBltPossible
0378      * \see fastBitBltRough
0379      */
0380     void fastBitBlt(KisPaintDeviceSP src, const QRect &rect);
0381 
0382     /**
0383      * The same as \ref fastBitBlt() but reads old data
0384      */
0385     void fastBitBltOldData(KisPaintDeviceSP src, const QRect &rect);
0386 
0387     /**
0388      * Clones rect from another paint device in a rough and fast way.
0389      * All the tiles touched by rect will be shared, between both
0390      * devices, that means it will copy a bigger area than was
0391      * requested. This method is supposed to be used for bitBlt'ing
0392      * into temporary paint devices.
0393      *
0394      * \see fastBitBltPossible
0395      * \see fastBitBlt
0396      */
0397     void fastBitBltRough(KisPaintDeviceSP src, const QRect &rect);
0398 
0399     /**
0400      * The same as \ref fastBitBltRough() but reads old data
0401      */
0402     void fastBitBltRoughOldData(KisPaintDeviceSP src, const QRect &rect);
0403 
0404 public:
0405     /**
0406      * Read the bytes representing the rectangle described by x, y, w, h into
0407      * data. If data is not big enough, Krita will gladly overwrite the rest
0408      * of your precious memory.
0409      *
0410      * Since this is a copy, you need to make sure you have enough memory.
0411      *
0412      * Reading from areas not previously initialized will read the default
0413      * pixel value into data but not initialize that region.
0414      */
0415     void readBytes(quint8 * data, qint32 x, qint32 y, qint32 w, qint32 h) const;
0416 
0417     /**
0418      * Read the bytes representing the rectangle rect into
0419      * data. If data is not big enough, Krita will gladly overwrite the rest
0420      * of your precious memory.
0421      *
0422      * Since this is a copy, you need to make sure you have enough memory.
0423      *
0424      * Reading from areas not previously initialized will read the default
0425      * pixel value into data but not initialize that region.
0426      * @param data The address of the memory to receive the bytes read
0427      * @param rect The rectangle in the paint device to read from
0428      */
0429     void readBytes(quint8 * data, const QRect &rect) const;
0430 
0431     /**
0432      * Copy the bytes in data into the rect specified by x, y, w, h. If the
0433      * data is too small or uninitialized, Krita will happily read parts of
0434      * memory you never wanted to be read.
0435      *
0436      * If the data is written to areas of the paint device not previously initialized,
0437      * the paint device will grow.
0438      */
0439     void writeBytes(const quint8 * data, qint32 x, qint32 y, qint32 w, qint32 h);
0440 
0441     /**
0442      * Copy the bytes in data into the rectangle rect. If the
0443      * data is too small or uninitialized, Krita will happily read parts of
0444      * memory you never wanted to be read.
0445      *
0446      * If the data is written to areas of the paint device not previously initialized,
0447      * the paint device will grow.
0448      * @param data The address of the memory to write bytes from
0449      * @param rect The rectangle in the paint device to write to
0450      */
0451     void writeBytes(const quint8 * data, const QRect &rect);
0452 
0453     /**
0454      * Copy the bytes in the paint device into a vector of arrays of bytes,
0455      * where the number of arrays is the number of channels in the
0456      * paint device. If the specified area is larger than the paint
0457      * device's extent, the default pixel will be read.
0458      */
0459     QVector<quint8*> readPlanarBytes(qint32 x, qint32 y, qint32 w, qint32 h) const;
0460 
0461     /**
0462      * Write the data in the separate arrays to the channels. If there
0463      * are less vectors than channels, the remaining channels will not
0464      * be copied. If any of the arrays points to 0, the channel in
0465      * that location will not be touched. If the specified area is
0466      * larger than the paint device, the paint device will be
0467      * extended. There are no guards: if the area covers more pixels
0468      * than there are bytes in the arrays, krita will happily fill
0469      * your paint device with areas of memory you never wanted to be
0470      * read. Krita may also crash.
0471      *
0472      * XXX: what about undo?
0473      */
0474     void writePlanarBytes(QVector<quint8*> planes, qint32 x, qint32 y, qint32 w, qint32 h);
0475 
0476     /**
0477      * Converts the paint device to a different colorspace
0478      */
0479     void convertTo(const KoColorSpace *dstColorSpace,
0480                    KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
0481                    KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags(),
0482                    KUndo2Command *parentCommand = nullptr,
0483                    KoUpdater *progressUpdater = nullptr);
0484 
0485     /**
0486      * Changes the profile of the colorspace of this paint device to the given
0487      * profile. If the given profile is 0, nothing happens.
0488      */
0489     bool setProfile(const KoColorProfile * profile, KUndo2Command *parentCommand);
0490 
0491     /**
0492      * Fill this paint device with the data from image; starting at (offsetX, offsetY)
0493      * @param image the image
0494      * @param profile name of the RGB profile to interpret the image as. 0 is interpreted as sRGB
0495      * @param offsetX x offset
0496      * @param offsetY y offset
0497      */
0498     void convertFromQImage(const QImage& image, const KoColorProfile *profile, qint32 offsetX = 0, qint32 offsetY = 0);
0499 
0500     /**
0501      * Create an RGBA QImage from a rectangle in the paint device.
0502      *
0503      * @param dstProfile RGB profile to use in conversion. May be 0, in which
0504      * case it's up to the color strategy to choose a profile (most
0505      * like sRGB).
0506      * @param x Left coordinate of the rectangle
0507      * @param y Top coordinate of the rectangle
0508      * @param w Width of the rectangle in pixels
0509      * @param h Height of the rectangle in pixels
0510      * @param renderingIntent Rendering intent
0511      * @param conversionFlags Conversion flags
0512      */
0513     QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h,
0514                            KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
0515                            KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const;
0516 
0517     /**
0518      * Overridden method for convenience
0519      */
0520     QImage convertToQImage(const KoColorProfile *dstProfile,
0521                            const QRect &rc,
0522                            KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
0523                            KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const;
0524 
0525     /**
0526      * Create an RGBA QImage from a rectangle in the paint device. The
0527      * rectangle is defined by the parent image's bounds.
0528      *
0529      * @param dstProfile RGB profile to use in conversion. May be 0, in which
0530      * case it's up to the color strategy to choose a profile (most
0531      * like sRGB).
0532      * @param renderingIntent Rendering intent
0533      * @param conversionFlags Conversion flags
0534      */
0535     QImage convertToQImage(const KoColorProfile *  dstProfile,
0536                            KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
0537                            KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const;
0538 
0539     /**
0540      * Creates a paint device thumbnail of the paint device, retaining
0541      * the aspect ratio. The width and height of the returned device
0542      * won't exceed \p maxw and \p maxw, but they may be smaller.
0543      *
0544      * @param w maximum width
0545      * @param h maximum height
0546      * @param rect only this rect will be used for the thumbnail
0547      * @param outputRect output rectangle
0548      *
0549      */
0550     KisPaintDeviceSP createThumbnailDevice(qint32 w, qint32 h, QRect rect = QRect(), QRect outputRect = QRect()) const;
0551     KisPaintDeviceSP createThumbnailDeviceOversampled(qint32 w, qint32 h, qreal oversample, QRect rect = QRect(),  QRect outputRect = QRect()) const;
0552 
0553     /**
0554      * Creates a thumbnail of the paint device, retaining the aspect ratio.
0555      * The width and height of the returned QImage won't exceed \p maxw and \p maxw, but they may be smaller.
0556      * The colors are not corrected for display!
0557      *
0558      * @param maxw: maximum width
0559      * @param maxh: maximum height
0560      * @param rect: only this rect will be used for the thumbnail
0561      * @param oversample: ratio used for antialiasing
0562      * @param renderingIntent Rendering intent
0563      * @param conversionFlags Conversion flags
0564      */
0565     QImage createThumbnail(qint32 maxw, qint32 maxh, QRect rect, qreal oversample = 1,
0566                            KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
0567                            KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags());
0568 
0569     /**
0570      * Cached version of createThumbnail(qint32 maxw, qint32 maxh, const KisSelection *selection, QRect rect)
0571      */
0572     QImage createThumbnail(qint32 maxw, qint32 maxh, qreal oversample = 1,
0573                            KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
0574                            KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags());
0575 
0576     /**
0577      * Cached version of createThumbnail that also adjusts aspect ratio of the
0578      * thumbnail to fit the extents of the paint device.
0579      */
0580     QImage createThumbnail(qint32 maxw, qint32 maxh,
0581                            Qt::AspectRatioMode aspectRatioMode,
0582                            qreal oversample = 1,
0583                            KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
0584                            KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags());
0585 
0586     /**
0587      * Fill c and opacity with the values found at x and y.
0588      *
0589      * The color values will be transformed from the profile of
0590      * this paint device to the display profile.
0591      *
0592      * @return true if the operation was successful.
0593      */
0594     bool pixel(qint32 x, qint32 y, QColor *c) const;
0595 
0596     /**
0597      * Fill kc with the values found at x and y. This method differs
0598      * from the above in using KoColor, which can be of any colorspace
0599      *
0600      * The color values will be transformed from the profile of
0601      * this paint device to the display profile.
0602      *
0603      * @return true if the operation was successful.
0604      */
0605     bool pixel(qint32 x, qint32 y, KoColor * kc) const;
0606 
0607     /**
0608      * Return pixel value in a form of KoColor. Please don't use this method
0609      * for iteration, it is highly inefficient. Use iterators instead.
0610      */
0611     KoColor pixel(const QPoint &pos) const;
0612 
0613     /**
0614      * Set the specified pixel to the specified color. Note that this
0615      * bypasses KisPainter. the PaintDevice is here used as an equivalent
0616      * to QImage, not QPixmap. This means that this is not undoable; also,
0617      * there is no compositing with an existing value at this location.
0618      *
0619      * The color values will be transformed from the display profile to
0620      * the paint device profile.
0621      *
0622      * Note that this will use 8-bit values and may cause a significant
0623      * degradation when used on 16-bit or hdr quality images.
0624      *
0625      * @return true if the operation was successful
0626      */
0627     bool setPixel(qint32 x, qint32 y, const QColor& c);
0628 
0629     /// Convenience method for the above
0630     bool setPixel(qint32 x, qint32 y, const KoColor& kc);
0631 
0632     /**
0633      * @return the colorspace of the pixels in this paint device
0634      */
0635     const KoColorSpace* colorSpace() const;
0636 
0637     /**
0638      * There is quite a common technique in Krita. It is used in
0639      * cases, when we want to paint something over a paint device
0640      * using the composition, opacity or selection. E.g. painting a
0641      * dab in a paint op, filling the selection in the Fill Tool.
0642      * Such work is usually done in the following way:
0643      *
0644      * 1) Create a paint device
0645      *
0646      * 2) Fill it with the desired color or data
0647      *
0648      * 3) Create a KisPainter and set all the properties of the
0649      *    transaction: selection, compositeOp, opacity and etc.
0650      *
0651      * 4) Paint a newly created paint device over the destination
0652      *    device.
0653      *
0654      * The following two methods (createCompositionSourceDevice() or
0655      * createCompositionSourceDeviceFixed())should be used for the
0656      * accomplishing the step 1). The point is that the desired color
0657      * space of the temporary device may not coincide with the color
0658      * space of the destination. That is the case, for example, for
0659      * the alpha8() colorspace used in the selections. So for such
0660      * devices the temporary target would have a different (grayscale)
0661      * color space.
0662      *
0663      * So there are two rules of thumb:
0664      *
0665      * 1) If you need a temporary device which you are going to fill
0666      *    with some data and then paint over the paint device, create
0667      *    it with either createCompositionSourceDevice() or
0668      *    createCompositionSourceDeviceFixed().
0669      *
0670      * 2) Do *not* expect that the color spaces of the destination and
0671      *    the temporary device would coincide. If you need to copy a
0672      *    single pixel from one device to another, you can use
0673      *    KisCrossDeviceColorSampler class, that will handle all the
0674      *    necessary conversions for you.
0675      *
0676      * \see createCompositionSourceDeviceFixed()
0677      * \see compositionSourceColorSpace()
0678      * \see KisCrossDeviceColorSampler
0679      * \see KisCrossDeviceColorSamplerInt
0680      */
0681     KisPaintDeviceSP createCompositionSourceDevice() const;
0682 
0683     /**
0684      * The same as createCompositionSourceDevice(), but initializes the
0685      * newly created device with the content of \p cloneSource
0686      *
0687      * \see createCompositionSourceDevice()
0688      */
0689     KisPaintDeviceSP createCompositionSourceDevice(KisPaintDeviceSP cloneSource) const;
0690 
0691     /**
0692      * The same as createCompositionSourceDevice(), but initializes
0693      * the newly created device with the *rough* \p roughRect of
0694      * \p cloneSource.
0695      *
0696      * "Rough rect" means that it may copy a bit more than
0697      * requested. It is expected that the caller will not use the area
0698      * outside \p roughRect.
0699      *
0700      * \see createCompositionSourceDevice()
0701      */
0702     KisPaintDeviceSP createCompositionSourceDevice(KisPaintDeviceSP cloneSource, const QRect roughRect) const;
0703 
0704     /**
0705      * This is a convenience method for createCompositionSourceDevice()
0706      *
0707      * \see createCompositionSourceDevice()
0708      */
0709     KisFixedPaintDeviceSP createCompositionSourceDeviceFixed() const;
0710 
0711     /**
0712      * This is a lowlevel method for the principle used in
0713      * createCompositionSourceDevice(). In most of the cases the paint
0714      * device creation methods should be used instead of this function.
0715      *
0716      * \see createCompositionSourceDevice()
0717      * \see createCompositionSourceDeviceFixed()
0718      */
0719     virtual const KoColorSpace* compositionSourceColorSpace() const;
0720 
0721     /**
0722      * @return the internal datamanager that keeps the pixels.
0723      */
0724     KisDataManagerSP dataManager() const;
0725 
0726     /**
0727      * Replace the pixel data, color strategy, and profile.
0728      */
0729     void setDataManager(KisDataManagerSP data, const KoColorSpace * colorSpace = 0);
0730 
0731     /**
0732      * Return the number of bytes a pixel takes.
0733      */
0734     quint32 pixelSize() const;
0735 
0736     /**
0737      * Return the number of channels a pixel takes
0738      */
0739     quint32 channelCount() const;
0740 
0741     /**
0742      * @return interstroke data that is atteched to the paint device.
0743      *
0744      * This data is managed by KisTransaction and can be used by brushes
0745      * to store some data that can be shared betweet the strokes. For
0746      * example, information about drying of the pigment.
0747      *
0748      * The interstroke data is stored in a per-frame manner, that is,
0749      * there is a separate per-stroke data for each frame.
0750      */
0751     KisInterstrokeDataSP interstrokeData() const;
0752 
0753     /**
0754      * @brief set interstroke data to the device
0755      *
0756      * Interstroke data is managed by KisTransaction, don't call this
0757      * method manually unless you really know what you are doing.
0758      *
0759      * @see interstrokeData()
0760      */
0761     KUndo2Command* createChangeInterstrokeDataCommand(KisInterstrokeDataSP data);
0762 
0763     /**
0764      * Create a keyframe channel for the content on this device.
0765      * @param id identifier for the channel
0766      * @return keyframe channel or 0 if there is not one
0767      */
0768     KisRasterKeyframeChannel *createKeyframeChannel(const KoID &id);
0769 
0770     KisRasterKeyframeChannel* keyframeChannel() const;
0771 
0772     /**
0773      * An interface to modify/load/save frames stored inside this device
0774      */
0775     KisPaintDeviceFramesInterface* framesInterface();
0776 
0777     /**
0778      * @brief burnKeyframe
0779      *
0780      * Take a frame from the keyframe channel,
0781      * Copy the contents onto the "base" frame,
0782      * and completely remove the keyframe channel.
0783      *
0784      * Should be useful for copy+paste operations where
0785      * we shouldn't expect keyframe data to persist.
0786      *
0787      * Parameterless version simply gets the current frameID.
0788      *
0789      * @param frameID -- frameID (from the framesInterface, **not the time**) to burn to device.
0790      * @return success
0791      */
0792     bool burnKeyframe(int frameID);
0793     bool burnKeyframe();
0794 
0795 public:
0796 
0797     /**
0798      * Add the specified rect to the parent layer's set of dirty rects
0799      * (if there is a parent layer)
0800      */
0801     void setDirty(const QRect & rc);
0802 
0803     void setDirty(const KisRegion &region);
0804 
0805     /**
0806      *  Set the parent layer completely dirty, if this paint device has
0807      *  as parent layer.
0808      */
0809     void setDirty();
0810 
0811     void setDirty(const QVector<QRect> &rects);
0812 
0813     /**
0814      * Called by KisTransactionData when it thinks current time should
0815      * be changed. And the requests is forwarded to the image if
0816      * needed.
0817      */
0818     void requestTimeSwitch(int time);
0819 
0820     /**
0821      * \return a sequence number corresponding to the current paint
0822      *         device state. Every time the paint device is changed,
0823      *         the sequence number is increased
0824      */
0825     int sequenceNumber() const;
0826 
0827 
0828     void estimateMemoryStats(qint64 &imageData, qint64 &temporaryData, qint64 &lodData) const;
0829 
0830 public:
0831 
0832     KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w);
0833     KisHLineConstIteratorSP createHLineConstIteratorNG(qint32 x, qint32 y, qint32 w) const;
0834 
0835     KisVLineIteratorSP createVLineIteratorNG(qint32 x, qint32 y, qint32 h);
0836     KisVLineConstIteratorSP createVLineConstIteratorNG(qint32 x, qint32 y, qint32 h) const;
0837 
0838     KisRandomAccessorSP createRandomAccessorNG();
0839     KisRandomConstAccessorSP createRandomConstAccessorNG() const;
0840 
0841     /**
0842      * Create an iterator that will "artificially" extend the paint device with the
0843      * value of the border when trying to access values outside the range of data.
0844      *
0845      * @param x x of top left corner
0846      * @param y y of top left corner
0847      * @param w width of the border
0848      * @param _dataWidth indicates the rectangle that truly contains data
0849      */
0850     KisRepeatHLineConstIteratorSP createRepeatHLineConstIterator(qint32 x, qint32 y, qint32 w, const QRect& _dataWidth) const;
0851     /**
0852      * Create an iterator that will "artificially" extend the paint device with the
0853      * value of the border when trying to access values outside the range of data.
0854      *
0855      * @param x x of top left corner
0856      * @param y y of top left corner
0857      * @param h height of the border
0858      * @param _dataWidth indicates the rectangle that truly contains data
0859      */
0860     KisRepeatVLineConstIteratorSP createRepeatVLineConstIterator(qint32 x, qint32 y, qint32 h, const QRect& _dataWidth) const;
0861 
0862     /**
0863      * This function create a random accessor which can easily access to sub pixel values.
0864      */
0865     KisRandomSubAccessorSP createRandomSubAccessor() const;
0866 
0867 
0868     /** Clear the selected pixels from the paint device */
0869     void clearSelection(KisSelectionSP selection);
0870 
0871     /**
0872      * Converts a paint device into a "new" paint device, that has
0873      * unconnected history. That is, after reincarnation, the device's
0874      * life starts a new page. No history. No memories.
0875      *
0876      * When the device is fed up with the new life, it can reincarnate
0877      * back to its previous life by undoing the command returned by
0878      * reincarnateWithDetachedHistory(). The old undo will continue
0879      * working as if nothing has happened.
0880      *
0881      * NOTE: reincarnation affects only the current lod plane and/or
0882      *       current frame. All other frames are kept unaffected.
0883      *
0884      * @param copyContent decides if the device should take its current
0885      *                    content to the new life
0886      * @return undo command for execution and undoing of the reincarnation
0887      */
0888     KUndo2Command* reincarnateWithDetachedHistory(bool copyContent);
0889 
0890 Q_SIGNALS:
0891 
0892     void profileChanged(const KoColorProfile *  profile);
0893     void colorSpaceChanged(const KoColorSpace *colorspace);
0894 
0895 public:
0896     friend class PaintDeviceCache;
0897 
0898     /**
0899      * Caclculates exact bounds of the device. Used internally
0900      * by a transparent caching system. The solution is very slow
0901      * because it does a linear scanline search. So the complexity
0902      * is n*n at worst.
0903      *
0904      * \see exactBounds(), nonDefaultPixelArea()
0905      */
0906     QRect calculateExactBounds(bool nonDefaultOnly) const;
0907 
0908 public:
0909     struct MemoryReleaseObject : public QObject {
0910         ~MemoryReleaseObject() override;
0911     };
0912 
0913     static MemoryReleaseObject* createMemoryReleaseObject();
0914 
0915 public:
0916     struct LodDataStruct {
0917         virtual ~LodDataStruct();
0918     };
0919 
0920     KisRegion regionForLodSyncing() const;
0921     LodDataStruct* createLodDataStruct(int lod);
0922     void updateLodDataStruct(LodDataStruct *dst, const QRect &srcRect);
0923     void uploadLodDataStruct(LodDataStruct *dst);
0924 
0925     void generateLodCloneDevice(KisPaintDeviceSP dst, const QRect &originalRect, int lod);
0926 
0927     void setProjectionDevice(bool value);
0928     void tesingFetchLodDevice(KisPaintDeviceSP targetDevice);
0929 
0930 private:
0931     KisPaintDevice& operator=(const KisPaintDevice&);
0932     void init(const KoColorSpace *colorSpace,
0933               KisDefaultBoundsBaseSP defaultBounds,
0934               KisNodeWSP parent, const QString& name);
0935 
0936     // Only KisPainter is allowed to have access to these low-level methods
0937     friend class KisPainter;
0938 
0939     /**
0940      * Return a vector with in order the size in bytes of the channels
0941      * in the colorspace of this paint device.
0942      */
0943     QVector<qint32> channelSizes() const;
0944 
0945     void emitColorSpaceChanged();
0946     void emitProfileChanged();
0947 
0948 private:
0949     friend class KisPaintDeviceFramesInterface;
0950 
0951 protected:
0952     friend class KisSelectionTest;
0953     KisNodeWSP parentNode() const;
0954 
0955 private:
0956     struct Private;
0957     Private * const m_d;
0958 };
0959 
0960 #endif // KIS_PAINT_DEVICE_IMPL_H_