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