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

0001 /*
0002  *  SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef KIS_DATAMANAGER_H_
0007 #define KIS_DATAMANAGER_H_
0008 
0009 #include <QtGlobal>
0010 
0011 class QRect;
0012 class KisPaintDeviceWriter;
0013 class QIODevice;
0014 
0015 #include <tiles3/kis_tiled_data_manager.h>
0016 #include <tiles3/kis_memento.h>
0017 
0018 #define ACTUAL_DATAMGR KisTiledDataManager
0019 
0020 /**
0021  * KisDataManager defines the interface that modules responsible for
0022  * storing and retrieving data must inmplement. Data modules, like
0023  * the tile manager, are responsible for:
0024  *
0025  * * Storing undo/redo data
0026  * * Offering ordered and unordered iterators over rects of pixels
0027  * * (eventually) efficiently loading and saving data in a format
0028  * that may allow deferred loading.
0029  *
0030  * A datamanager knows nothing about the type of pixel data except
0031  * how many quint8's a single pixel takes.
0032  */
0033 class KisDataManager : public ACTUAL_DATAMGR
0034 {
0035 
0036 public:
0037 
0038     /**
0039      * Create a new datamanger where every pixel will take pixelSize bytes and will be initialized
0040      * by default with defPixel. The value of defPixel is copied, the caller still owns the pointer.
0041      *
0042      * Note that if pixelSize > size of the defPixel array, we will happily read beyond the
0043      * defPixel array.
0044      */
0045 KisDataManager(quint32 pixelSize, const quint8 *defPixel) : ACTUAL_DATAMGR(pixelSize, defPixel) {}
0046     KisDataManager(const KisDataManager& dm) : ACTUAL_DATAMGR(dm) { }
0047 
0048     ~KisDataManager() override {
0049     }
0050 
0051 public:
0052     /**
0053      * Sets the default pixel. New data will be initialised with this pixel. The pixel is copied: the
0054      * caller still owns the pointer.
0055      */
0056     inline void setDefaultPixel(const quint8 *defPixel) {
0057         return ACTUAL_DATAMGR::setDefaultPixel(defPixel);
0058     }
0059 
0060     /**
0061      * Get a pointer to the default pixel.
0062      */
0063     inline const quint8 *defaultPixel() const {
0064         return ACTUAL_DATAMGR::defaultPixel();
0065     }
0066 
0067     /**
0068      * Reguests a memento from the data manager. There is only one memento active
0069      * at any given moment for a given paint device and all and any
0070      * write actions on the datamanger builds undo data into this memento
0071      * necessary to rollback the transaction.
0072      */
0073     inline KisMementoSP getMemento() {
0074         return ACTUAL_DATAMGR::getMemento();
0075     }
0076 
0077     /**
0078      * Restores the image data to the state at the time of the getMemento() call.
0079      *
0080      * Note that rollback should be performed with mementos in the reverse order of
0081      * their creation, as mementos only store incremental changes
0082      */
0083     inline void rollback(KisMementoSP memento) {
0084         ACTUAL_DATAMGR::rollback(memento);
0085     }
0086 
0087     /**
0088      * Restores the image data to the state at the time of the rollback call of the memento.
0089      *
0090      * Note that rollforward must only be called when an rollback have previously been performed, and
0091      * no intermittent actions have been performed (though it's ok to rollback other mementos and
0092      * roll them forward again)
0093      */
0094     inline void rollforward(KisMementoSP memento) {
0095         ACTUAL_DATAMGR::rollforward(memento);
0096     }
0097 
0098     /**
0099      * @returns true if there is a memento active. This means that
0100      * iterators can rely on the oldData() function.
0101      */
0102     inline bool hasCurrentMemento() const {
0103         return ACTUAL_DATAMGR::hasCurrentMemento();
0104     }
0105 
0106 public:
0107 
0108     /**
0109      * Reads and writes the tiles
0110      *
0111      */
0112     inline bool write(KisPaintDeviceWriter &writer) {
0113         return ACTUAL_DATAMGR::write(writer);
0114     }
0115 
0116     inline bool read(QIODevice *io) {
0117         return ACTUAL_DATAMGR::read(io);
0118     }
0119 
0120     inline void purge(const QRect& area) {
0121         ACTUAL_DATAMGR::purge(area);
0122     }
0123 
0124     /**
0125      * The tiles may be not allocated directly from the glibc, but
0126      * instead can be allocated in bigger blobs. After you freed quite
0127      * a lot of data and are sure you won't need it anymore, you can
0128      * release these pools to save the memory.
0129      */
0130     static inline void releaseInternalPools() {
0131         ACTUAL_DATAMGR::releaseInternalPools();
0132     }
0133 
0134 public:
0135 
0136     /**
0137      * Returns the number of bytes a pixel takes
0138      */
0139     inline quint32 pixelSize() const {
0140         return ACTUAL_DATAMGR::pixelSize();
0141     }
0142 
0143     /**
0144      * Return the extent of the data in x,y,w,h.
0145      */
0146     inline void extent(qint32 &x, qint32 &y, qint32 &w, qint32 &h) const {
0147         return ACTUAL_DATAMGR::extent(x, y, w, h);
0148     }
0149 
0150     QRect extent() const {
0151         return ACTUAL_DATAMGR::extent();
0152     }
0153 
0154     KisRegion region() const {
0155         return ACTUAL_DATAMGR::region();
0156     }
0157 
0158 public:
0159 
0160     /**
0161       * Crop or extend the data to x, y, w, h.
0162       */
0163     inline void setExtent(qint32 x, qint32 y, qint32 w, qint32 h) {
0164         return ACTUAL_DATAMGR::setExtent(x, y, w, h);
0165     }
0166 
0167     inline void setExtent(const QRect & rect) {
0168         setExtent(rect.x(), rect.y(), rect.width(), rect.height());
0169     }
0170 
0171 public:
0172 
0173     /**
0174      * Clear the specified rect to the specified value.
0175      */
0176     inline void clear(qint32 x, qint32 y,
0177                       qint32 w, qint32 h,
0178                       quint8 def) {
0179         ACTUAL_DATAMGR::clear(x, y, w, h, def);
0180     }
0181 
0182     /**
0183      * Clear the specified rect to the specified pixel value.
0184      */
0185     inline void clear(qint32 x, qint32 y,
0186                       qint32 w, qint32 h,
0187                       const quint8 * def) {
0188         ACTUAL_DATAMGR::clear(x, y, w, h, def);
0189     }
0190 
0191 
0192     /**
0193      * Clear all back to default values.
0194      */
0195     inline void clear() {
0196         ACTUAL_DATAMGR::clear();
0197     }
0198 
0199 public:
0200 
0201     /**
0202      * Clones rect from another datamanager. The cloned area will be
0203      * shared between both datamanagers as much as possible using
0204      * copy-on-write. Parts of the rect that cannot be shared
0205      * (cross tiles) are deep-copied,
0206      */
0207     inline void bitBlt(KisTiledDataManagerSP srcDM, const QRect &rect) {
0208         ACTUAL_DATAMGR::bitBlt(const_cast<KisTiledDataManager*>(srcDM.data()), rect);
0209     }
0210 
0211     /**
0212      * The same as \ref bitBlt() but reads old data
0213      */
0214     inline void bitBltOldData(KisTiledDataManagerSP srcDM, const QRect &rect) {
0215         ACTUAL_DATAMGR::bitBltOldData(const_cast<KisTiledDataManager*>(srcDM.data()), rect);
0216     }
0217 
0218     /**
0219      * Clones rect from another datamanager in a rough and fast way.
0220      * All the tiles touched by rect will be shared, between both
0221      * devices, that means it will copy a bigger area than was
0222      * requested. This method is supposed to be used for bitBlt'ing
0223      * into temporary paint devices.
0224      */
0225     inline void bitBltRough(KisTiledDataManagerSP srcDM, const QRect &rect) {
0226         ACTUAL_DATAMGR::bitBltRough(const_cast<KisTiledDataManager*>(srcDM.data()), rect);
0227     }
0228 
0229     /**
0230      * The same as \ref bitBltRough() but reads old data
0231      */
0232     inline void bitBltRoughOldData(KisTiledDataManagerSP srcDM, const QRect &rect) {
0233         ACTUAL_DATAMGR::bitBltRoughOldData(const_cast<KisTiledDataManager*>(srcDM.data()), rect);
0234     }
0235 
0236 public:
0237 
0238     /**
0239      * Write the specified data to x, y. There is no checking on pixelSize!
0240      */
0241     inline void setPixel(qint32 x, qint32 y, const quint8 * data) {
0242         ACTUAL_DATAMGR::setPixel(x, y, data);
0243     }
0244 
0245 
0246     /**
0247      * Copy the bytes in the specified rect to a chunk of memory.
0248      * The pixelSize in bytes is w * h * pixelSize
0249      */
0250     inline void readBytes(quint8 * data,
0251                           qint32 x, qint32 y,
0252                           qint32 w, qint32 h,
0253                           qint32 dataRowStride = -1) const {
0254         ACTUAL_DATAMGR::readBytes(data, x, y, w, h, dataRowStride);
0255     }
0256 
0257     /**
0258      * Copy the bytes to the specified rect. w * h * pixelSize bytes
0259      * will be read, whether the caller prepared them or not.
0260      */
0261     inline void writeBytes(const quint8 * data,
0262                            qint32 x, qint32 y,
0263                            qint32 w, qint32 h,
0264                            qint32 dataRowStride = -1) {
0265         ACTUAL_DATAMGR::writeBytes(data, x, y, w, h, dataRowStride);
0266     }
0267 
0268 
0269     /**
0270      * Copy the bytes in the paint device into a vector of arrays of bytes,
0271      * where the number of arrays is the number of channels in the
0272      * paint device. If the specified area is larger than the paint
0273      * device's extent, the default pixel will be read.
0274      *
0275      * @param channelsizes a vector with for every channel its size in bytes
0276      * @param x x coordinate of the top left corner
0277      * @param y y coordinate of the top left corner
0278      * @param w width
0279      * @param h height
0280      */
0281     QVector<quint8*> readPlanarBytes(QVector<qint32> channelsizes, qint32 x, qint32 y, qint32 w, qint32 h) const {
0282         return ACTUAL_DATAMGR::readPlanarBytes(channelsizes, x, y, w, h);
0283     }
0284 
0285     /**
0286      * Write the data in the separate arrays to the channels. If there
0287      * are less vectors than channels, the remaining channels will not
0288      * be copied. If any of the arrays points to 0, the channel in
0289      * that location will not be touched. If the specified area is
0290      * larger than the paint device, the paint device will be
0291      * extended. There are no guards: if the area covers more pixels
0292      * than there are bytes in the arrays, krita will happily fill
0293      * your paint device with areas of memory you never wanted to be
0294      * read. Krita may also crash.
0295      *
0296      * @param planes a vector with a byte array for every plane
0297      * @param channelsizes a vector with for every channel its size in
0298      * bytes
0299      * @param x x coordinate of the top left corner
0300      * @param y y coordinate of the top left corner
0301      * @param w width
0302      * @param h height
0303      *
0304      * XXX: what about undo?
0305      */
0306     void writePlanarBytes(QVector<quint8*> planes, QVector<qint32> channelsizes,  qint32 x, qint32 y, qint32 w, qint32 h) {
0307         ACTUAL_DATAMGR::writePlanarBytes(planes, channelsizes, x, y, w, h);
0308     }
0309 
0310 
0311     /**
0312      * Get the number of contiguous columns starting at x, valid for all values
0313      * of y between minY and maxY.
0314      */
0315     inline qint32 numContiguousColumns(qint32 x, qint32 minY, qint32 maxY) const {
0316         return ACTUAL_DATAMGR::numContiguousColumns(x, minY, maxY);
0317     }
0318 
0319 
0320     /**
0321      * Get the number of contiguous rows starting at y, valid for all
0322      * values of x between minX and maxX.
0323      */
0324     inline qint32 numContiguousRows(qint32 y, qint32 minX, qint32 maxX) const {
0325         return ACTUAL_DATAMGR::numContiguousRows(y, minX, maxX);
0326     }
0327 
0328 
0329     /**
0330      * Get the row stride at pixel (x, y). This is the number of bytes
0331      * to add to a pointer to pixel (x, y) to access (x, y + 1).
0332      */
0333     inline qint32 rowStride(qint32 x, qint32 y) const {
0334         return ACTUAL_DATAMGR::rowStride(x, y);
0335     }
0336 
0337 protected:
0338     friend class KisRectIterator;
0339     friend class KisHLineIterator;
0340     friend class KisVLineIterator;
0341 };
0342 
0343 
0344 #endif // KIS_DATAMANAGER_H_
0345