Krita Source Code Documentation
Loading...
Searching...
No Matches
KisTiledDataManager Class Reference

#include <kis_tiled_data_manager.h>

+ Inheritance diagram for KisTiledDataManager:

Public Member Functions

void bitBlt (KisTiledDataManager *srcDM, const QRect &rect)
 
void bitBltOldData (KisTiledDataManager *srcDM, const QRect &rect)
 
void bitBltRough (KisTiledDataManager *srcDM, const QRect &rect)
 
void bitBltRoughOldData (KisTiledDataManager *srcDM, const QRect &rect)
 
void clear ()
 
void clear (qint32 x, qint32 y, qint32 w, qint32 h, const quint8 *clearPixel)
 
void clear (qint32 x, qint32 y, qint32 w, qint32 h, quint8 clearValue)
 
void clear (QRect clearRect, const quint8 *clearPixel)
 
void clear (QRect clearRect, quint8 clearValue)
 
void commit ()
 
void debugPrintInfo ()
 
const quint8 * defaultPixel () const
 
QRect extent () const
 
void extent (qint32 &x, qint32 &y, qint32 &w, qint32 &h) const
 
KisMementoSP getMemento ()
 
KisTileSP getOldTile (qint32 col, qint32 row)
 
KisTileSP getOldTile (qint32 col, qint32 row, bool &existingTile)
 
KisTileSP getReadOnlyTileLazy (qint32 col, qint32 row, bool &existingTile)
 
KisTileSP getTile (qint32 col, qint32 row, bool writable)
 
void getTilesPair (qint32 col, qint32 row, bool writable, KisTileSP *tile, KisTileSP *oldTile)
 
bool hasCurrentMemento () const
 
 KisTiledDataManager (const KisTiledDataManager &dm)
 
 KisTiledDataManager (quint32 pixelSize, const quint8 *defPixel)
 
qint32 numContiguousColumns (qint32 x, qint32 minY, qint32 maxY) const
 
qint32 numContiguousRows (qint32 y, qint32 minX, qint32 maxX) const
 
KisTiledDataManageroperator= (const KisTiledDataManager &dm)
 
void purgeHistory (KisMementoSP oldestMemento)
 
void readBytes (quint8 *bytes, qint32 x, qint32 y, qint32 w, qint32 h, qint32 dataRowStride=-1) const
 
QVector< quint8 * > readPlanarBytes (QVector< qint32 > channelsizes, qint32 x, qint32 y, qint32 w, qint32 h) const
 
KisRegion region () const
 
void rollback (KisMementoSP memento)
 
void rollforward (KisMementoSP memento)
 
qint32 rowStride (qint32 x, qint32 y) const
 
void setDefaultPixel (const quint8 *defPixel)
 
void setExtent (qint32 x, qint32 y, qint32 w, qint32 h)
 
void setExtent (QRect newRect)
 
void setPixel (qint32 x, qint32 y, const quint8 *data)
 
void writeBytes (const quint8 *bytes, qint32 x, qint32 y, qint32 w, qint32 h, qint32 dataRowStride=-1)
 
void writePlanarBytes (QVector< quint8 * > planes, QVector< qint32 > channelsizes, qint32 x, qint32 y, qint32 w, qint32 h)
 
virtual ~KisTiledDataManager ()
 
- Public Member Functions inherited from KisShared
bool deref ()
 
bool ref ()
 
int refCount ()
 
QAtomicInt * sharedWeakReference ()
 

Static Public Member Functions

static void releaseInternalPools ()
 

Protected Member Functions

quint32 pixelSize () const
 
void purge (const QRect &area)
 
bool read (QIODevice *stream)
 
bool write (KisPaintDeviceWriter &store)
 
- Protected Member Functions inherited from KisShared
 KisShared ()
 
 ~KisShared ()
 

Private Member Functions

template<bool useOldSrcData>
void bitBltImpl (KisTiledDataManager *srcDM, const QRect &rect)
 
template<bool useOldSrcData>
void bitBltRoughImpl (KisTiledDataManager *srcDM, const QRect &rect)
 
qint32 divideRoundDown (qint32 x, const qint32 y) const
 
quint8 * duplicatePixel (qint32 num, const quint8 *pixel)
 
bool processTilesHeader (QIODevice *stream, quint32 &numTiles)
 
void readBytesBody (quint8 *data, qint32 x, qint32 y, qint32 width, qint32 height, qint32 dataRowStride=-1) const
 
QVector< quint8 * > readPlanarBytesBody (QVector< qint32 > channelsizes, qint32 x, qint32 y, qint32 w, qint32 h) const
 
void recalculateExtent ()
 
void setDefaultPixelImpl (const quint8 *defPixel)
 
void writeBytesBody (const quint8 *data, qint32 x, qint32 y, qint32 width, qint32 height, qint32 dataRowStride=-1)
 
template<bool allChannelsPresent>
void writePlanarBytesBody (QVector< quint8 * > planes, QVector< qint32 > channelsizes, qint32 x, qint32 y, qint32 w, qint32 h)
 
bool writeTilesHeader (KisPaintDeviceWriter &store, quint32 numTiles)
 
qint32 xToCol (qint32 x) const
 
qint32 yToRow (qint32 y) const
 

Private Attributes

quint8 * m_defaultPixel
 
KisTiledExtentManager m_extentManager
 
KisTileHashTablem_hashTable
 
QReadWriteLock m_lock
 
KisMementoManagerm_mementoManager
 
qint32 m_pixelSize
 

Static Private Attributes

static const qint32 CURRENT_VERSION = 2
 
static const qint32 LEGACY_VERSION = 1
 

Friends

class KisAbstractTileCompressor
 
class KisBaseIterator
 
class KisRandomAccessor2
 
class KisStressJob
 
class KisTileDataWrapper
 
class KisTiledIterator
 
class KisTiledRandomAccessor
 

Detailed Description

KisTiledDataManager implements the interface that KisDataManager defines

The interface definition is enforced by KisDataManager calling all the methods which must also be defined in KisTiledDataManager. It is not allowed to change the interface as other datamanagers may also rely on the same interface.

  • Storing undo/redo data
  • Offering ordered and unordered iterators over rects of pixels
  • (eventually) efficiently loading and saving data in a format that may allow deferred loading.

A datamanager knows nothing about the type of pixel data except how many quint8's a single pixel takes.

Definition at line 55 of file kis_tiled_data_manager.h.

Constructor & Destructor Documentation

◆ KisTiledDataManager() [1/2]

KisTiledDataManager::KisTiledDataManager ( quint32 pixelSize,
const quint8 * defPixel )

Definition at line 33 of file kis_tiled_data_manager.cc.

35{
36 /* See comment in destructor for details */
39
41 m_defaultPixel = new quint8[m_pixelSize];
43}
KisMementoManager * m_mementoManager
const quint8 * defaultPixel() const
void setDefaultPixel(const quint8 *defPixel)
KisTileHashTable * m_hashTable
KisTileHashTableTraits< KisTile > KisTileHashTable

References defaultPixel(), m_defaultPixel, m_hashTable, m_mementoManager, m_pixelSize, pixelSize(), and setDefaultPixel().

◆ ~KisTiledDataManager()

KisTiledDataManager::~KisTiledDataManager ( )
virtual

Here is an explanation why we use hash table and The Memento Manager dynamically allocated We need to destroy them in that very order. The reason is that when hash table destroying all her child tiles they all cry about it to The Memento Manager using a pointer. So The Memento Manager should be alive during that destruction. We could use shared pointers instead, but they create too much overhead.

Definition at line 69 of file kis_tiled_data_manager.cc.

70{
79 delete m_hashTable;
80 delete m_mementoManager;
81
82 delete[] m_defaultPixel;
83}

References m_defaultPixel, m_hashTable, and m_mementoManager.

◆ KisTiledDataManager() [2/2]

KisTiledDataManager::KisTiledDataManager ( const KisTiledDataManager & dm)

We won't call setDefaultTileData here, as defaultTileDatas has already been made shared in m_hashTable(dm->m_hashTable)

Definition at line 45 of file kis_tiled_data_manager.cc.

46 : KisShared()
47{
48 /* See comment in destructor for details */
49
50 /* We do not clone the history of the device, there is no usecase for it */
52
53 KisTileData *defaultTileData = dm.m_hashTable->refAndFetchDefaultTileData();
54 m_mementoManager->setDefaultTileData(defaultTileData);
55 defaultTileData->deref();
56
58
60 m_defaultPixel = new quint8[m_pixelSize];
67}
void setDefaultTileData(KisTileData *defaultTileData)
KisTileData * refAndFetchDefaultTileData() const

References KisTileData::deref(), m_defaultPixel, m_hashTable, m_mementoManager, m_pixelSize, recalculateExtent(), KisTileHashTableTraits< T >::refAndFetchDefaultTileData(), and KisMementoManager::setDefaultTileData().

Member Function Documentation

◆ bitBlt()

void KisTiledDataManager::bitBlt ( KisTiledDataManager * srcDM,
const QRect & rect )

Clones rect from another datamanager. The cloned area will be shared between both datamanagers as much as possible using copy-on-write. Parts of the rect that cannot be shared (cross tiles) are deep-copied,

Definition at line 560 of file kis_tiled_data_manager.cc.

561{
562 bitBltImpl<false>(srcDM, rect);
563}

◆ bitBltImpl()

template<bool useOldSrcData>
void KisTiledDataManager::bitBltImpl ( KisTiledDataManager * srcDM,
const QRect & rect )
private

Definition at line 433 of file kis_tiled_data_manager.cc.

434{
435 if (rect.isEmpty()) return;
436
437 const qint32 pixelSize = this->pixelSize();
438 const bool defaultPixelsCoincide =
439 !memcmp(srcDM->defaultPixel(), m_defaultPixel, pixelSize);
440
441 const quint32 rowStride = KisTileData::WIDTH * pixelSize;
442
443 qint32 firstColumn = xToCol(rect.left());
444 qint32 lastColumn = xToCol(rect.right());
445
446 qint32 firstRow = yToRow(rect.top());
447 qint32 lastRow = yToRow(rect.bottom());
448
449 for (qint32 row = firstRow; row <= lastRow; ++row) {
450 for (qint32 column = firstColumn; column <= lastColumn; ++column) {
451
452 bool srcTileExists = false;
453
454 // this is the only variation in the template
455 KisTileSP srcTile = useOldSrcData ?
456 srcDM->getOldTile(column, row, srcTileExists) :
457 srcDM->getReadOnlyTileLazy(column, row, srcTileExists);
458
459 QRect tileRect(column*KisTileData::WIDTH, row*KisTileData::HEIGHT,
461 QRect cloneTileRect = rect & tileRect;
462
463 if (cloneTileRect == tileRect) {
464 // Clone whole tile
465 const bool wasDeleted =
466 m_hashTable->deleteTile(column, row);
467
468 if (srcTileExists || !defaultPixelsCoincide) {
469 srcTile->lockForRead();
470 KisTileData *td = srcTile->tileData();
471 KisTileSP clonedTile = KisTileSP(new KisTile(column, row, td, m_mementoManager));
472 srcTile->unlockForRead();
473
474 m_hashTable->addTile(clonedTile);
475
476 if (!wasDeleted) {
477 m_extentManager.notifyTileAdded(column, row);
478 }
479 } else if (wasDeleted) {
481 }
482
483 } else {
484 const qint32 lineSize = cloneTileRect.width() * pixelSize;
485 qint32 rowsRemaining = cloneTileRect.height();
486
487 KisTileDataWrapper tw(this,
488 cloneTileRect.left(),
489 cloneTileRect.top(),
491 srcTile->lockForRead();
492 // We suppose that the shift in both tiles is the same
493 const quint8* srcTileIt = srcTile->data() + tw.offset();
494 quint8* dstTileIt = tw.data();
495
496 while (rowsRemaining > 0) {
497 memcpy(dstTileIt, srcTileIt, lineSize);
498 srcTileIt += rowStride;
499 dstTileIt += rowStride;
500 rowsRemaining--;
501 }
502
503 srcTile->unlockForRead();
504 }
505 }
506 }
507}
static const qint32 HEIGHT
static const qint32 WIDTH
void addTile(TileTypeSP tile)
bool deleteTile(TileTypeSP tile)
void lockForRead() const
Definition kis_tile.cc:208
KisTileData * tileData() const
Definition kis_tile.h:118
void unlockForRead() const
Definition kis_tile.cc:275
quint8 * data() const
Definition kis_tile.h:85
qint32 rowStride(qint32 x, qint32 y) const
KisTiledExtentManager m_extentManager
qint32 yToRow(qint32 y) const
qint32 xToCol(qint32 x) const
KisTileSP getOldTile(qint32 col, qint32 row, bool &existingTile)
KisTileSP getReadOnlyTileLazy(qint32 col, qint32 row, bool &existingTile)
void notifyTileAdded(qint32 col, qint32 row)
void notifyTileRemoved(qint32 col, qint32 row)
KisSharedPtr< KisTile > KisTileSP
Definition kis_tile.h:27

References KisTileHashTableTraits< T >::addTile(), KisTile::data(), KisTileDataWrapper::data(), defaultPixel(), KisTileHashTableTraits< T >::deleteTile(), getOldTile(), getReadOnlyTileLazy(), KisTileData::HEIGHT, KisTile::lockForRead(), m_defaultPixel, m_extentManager, m_hashTable, m_mementoManager, KisTiledExtentManager::notifyTileAdded(), KisTiledExtentManager::notifyTileRemoved(), KisTileDataWrapper::offset(), pixelSize(), rowStride(), KisTile::tileData(), KisTile::unlockForRead(), KisTileData::WIDTH, KisTileDataWrapper::WRITE, xToCol(), and yToRow().

◆ bitBltOldData()

void KisTiledDataManager::bitBltOldData ( KisTiledDataManager * srcDM,
const QRect & rect )

The same as bitBlt(), but reads old data

Definition at line 565 of file kis_tiled_data_manager.cc.

566{
567 bitBltImpl<true>(srcDM, rect);
568}

◆ bitBltRough()

void KisTiledDataManager::bitBltRough ( KisTiledDataManager * srcDM,
const QRect & rect )

Clones rect from another datamanager in a rough and fast way. All the tiles touched by rect will be shared, between both managers, that means it will copy a bigger area than was requested. This method is supposed to be used for bitBlt'ing into temporary paint devices.

Definition at line 570 of file kis_tiled_data_manager.cc.

571{
572 bitBltRoughImpl<false>(srcDM, rect);
573}

◆ bitBltRoughImpl()

template<bool useOldSrcData>
void KisTiledDataManager::bitBltRoughImpl ( KisTiledDataManager * srcDM,
const QRect & rect )
private

We are cloning whole tiles here so let's not be so boring to check any borders :)

Definition at line 510 of file kis_tiled_data_manager.cc.

511{
512 if (rect.isEmpty()) return;
513
514 const qint32 pixelSize = this->pixelSize();
515 const bool defaultPixelsCoincide =
516 !memcmp(srcDM->defaultPixel(), m_defaultPixel, pixelSize);
517
518 qint32 firstColumn = xToCol(rect.left());
519 qint32 lastColumn = xToCol(rect.right());
520
521 qint32 firstRow = yToRow(rect.top());
522 qint32 lastRow = yToRow(rect.bottom());
523
524 for (qint32 row = firstRow; row <= lastRow; ++row) {
525 for (qint32 column = firstColumn; column <= lastColumn; ++column) {
526
532 bool srcTileExists = false;
533
534 // this is the only variation in the template
535 KisTileSP srcTile = useOldSrcData ?
536 srcDM->getOldTile(column, row, srcTileExists) :
537 srcDM->getReadOnlyTileLazy(column, row, srcTileExists);
538
539 const bool wasDeleted =
540 m_hashTable->deleteTile(column, row);
541
542 if (srcTileExists || !defaultPixelsCoincide) {
543 srcTile->lockForRead();
544 KisTileData *td = srcTile->tileData();
545 KisTileSP clonedTile = KisTileSP(new KisTile(column, row, td, m_mementoManager));
546 srcTile->unlockForRead();
547
548 m_hashTable->addTile(clonedTile);
549
550 if (!wasDeleted) {
551 m_extentManager.notifyTileAdded(column, row);
552 }
553 } else if (wasDeleted) {
555 }
556 }
557 }
558}

References KisTileHashTableTraits< T >::addTile(), defaultPixel(), KisTileHashTableTraits< T >::deleteTile(), getOldTile(), getReadOnlyTileLazy(), KisTile::lockForRead(), m_defaultPixel, m_extentManager, m_hashTable, m_mementoManager, KisTiledExtentManager::notifyTileAdded(), KisTiledExtentManager::notifyTileRemoved(), pixelSize(), KisTile::tileData(), KisTile::unlockForRead(), xToCol(), and yToRow().

◆ bitBltRoughOldData()

void KisTiledDataManager::bitBltRoughOldData ( KisTiledDataManager * srcDM,
const QRect & rect )

The same as bitBltRough(), but reads old data

Definition at line 575 of file kis_tiled_data_manager.cc.

576{
577 bitBltRoughImpl<true>(srcDM, rect);
578}

◆ clear() [1/5]

◆ clear() [2/5]

void KisTiledDataManager::clear ( qint32 x,
qint32 y,
qint32 w,
qint32 h,
const quint8 * clearPixel )

Definition at line 416 of file kis_tiled_data_manager.cc.

417{
418 clear(QRect(x, y, w, h), clearPixel);
419}

References clear().

◆ clear() [3/5]

void KisTiledDataManager::clear ( qint32 x,
qint32 y,
qint32 w,
qint32 h,
quint8 clearValue )

Definition at line 420 of file kis_tiled_data_manager.cc.

421{
422 clear(QRect(x, y, w, h), clearValue);
423}

References clear().

◆ clear() [4/5]

void KisTiledDataManager::clear ( QRect clearRect,
const quint8 * clearPixel )

Definition at line 309 of file kis_tiled_data_manager.cc.

310{
311 if (clearPixel == 0)
313
314 if (clearRect.isEmpty())
315 return;
316
317 const qint32 pixelSize = this->pixelSize();
318
319 bool pixelBytesAreDefault = !memcmp(clearPixel, m_defaultPixel, pixelSize);
320
321 bool pixelBytesAreTheSame = true;
322 for (qint32 i = 0; i < pixelSize; ++i) {
323 if (clearPixel[i] != clearPixel[0]) {
324 pixelBytesAreTheSame = false;
325 break;
326 }
327 }
328
329 if (pixelBytesAreDefault) {
330 clearRect &= m_extentManager.extent();
331 }
332
333 qint32 firstColumn = xToCol(clearRect.left());
334 qint32 lastColumn = xToCol(clearRect.right());
335
336 qint32 firstRow = yToRow(clearRect.top());
337 qint32 lastRow = yToRow(clearRect.bottom());
338
339 const quint32 rowStride = KisTileData::WIDTH * pixelSize;
340
341 // Generate one row
342 quint8 *clearPixelData = 0;
343 quint32 maxRunLength = qMin(clearRect.width(), KisTileData::WIDTH);
344 clearPixelData = duplicatePixel(maxRunLength, clearPixel);
345
346 KisTileData *td = 0;
347 if (!pixelBytesAreDefault &&
348 clearRect.width() >= KisTileData::WIDTH &&
349 clearRect.height() >= KisTileData::HEIGHT) {
350
352 td->acquire();
353 }
354
355 for (qint32 row = firstRow; row <= lastRow; ++row) {
356 for (qint32 column = firstColumn; column <= lastColumn; ++column) {
357
358 QRect tileRect(column*KisTileData::WIDTH, row*KisTileData::HEIGHT,
360 QRect clearTileRect = clearRect & tileRect;
361
362 if (clearTileRect == tileRect) {
363 // Clear whole tile
364 const bool wasDeleted =
365 m_hashTable->deleteTile(column, row);
366
367 if (wasDeleted) {
369 }
370
371
372 if (!pixelBytesAreDefault) {
373 KisTileSP clearedTile = KisTileSP(new KisTile(column, row, td, m_mementoManager));
374 m_hashTable->addTile(clearedTile);
375 m_extentManager.notifyTileAdded(column, row);
376 }
377 } else {
378 const qint32 lineSize = clearTileRect.width() * pixelSize;
379 qint32 rowsRemaining = clearTileRect.height();
380
381 KisTileDataWrapper tw(this,
382 clearTileRect.left(),
383 clearTileRect.top(),
385 quint8* tileIt = tw.data();
386
387 if (pixelBytesAreTheSame) {
388 while (rowsRemaining > 0) {
389 memset(tileIt, *clearPixelData, lineSize);
390 tileIt += rowStride;
391 rowsRemaining--;
392 }
393 } else {
394 while (rowsRemaining > 0) {
395 memcpy(tileIt, clearPixelData, lineSize);
396 tileIt += rowStride;
397 rowsRemaining--;
398 }
399 }
400 }
401 }
402 }
403
404 if (td) td->release();
405 delete[] clearPixelData;
406}
KisTileData * createDefaultTileData(qint32 pixelSize, const quint8 *defPixel)
static KisTileDataStore * instance()
quint8 * duplicatePixel(qint32 num, const quint8 *pixel)
ALWAYS_INLINE void clearPixel(quint8 *dst)

References KisTileData::acquire(), KisTileHashTableTraits< T >::addTile(), KisTileDataStore::createDefaultTileData(), KisTileDataWrapper::data(), KisTileHashTableTraits< T >::deleteTile(), duplicatePixel(), KisTiledExtentManager::extent(), KisTileData::HEIGHT, KisTileDataStore::instance(), m_defaultPixel, m_extentManager, m_hashTable, m_mementoManager, KisTiledExtentManager::notifyTileAdded(), KisTiledExtentManager::notifyTileRemoved(), pixelSize(), KisTileData::release(), rowStride(), KisTileData::WIDTH, KisTileDataWrapper::WRITE, xToCol(), and yToRow().

◆ clear() [5/5]

void KisTiledDataManager::clear ( QRect clearRect,
quint8 clearValue )

Definition at line 408 of file kis_tiled_data_manager.cc.

409{
410 quint8 *buf = new quint8[pixelSize()];
411 memset(buf, clearValue, pixelSize());
412 clear(clearRect, buf);
413 delete[] buf;
414}

References clear(), and pixelSize().

◆ commit()

void KisTiledDataManager::commit ( )
inline

Finishes having already started transaction

Definition at line 144 of file kis_tiled_data_manager.h.

144 {
145 QWriteLocker locker(&m_lock);
146
148 if(memento) {
150 }
151
153 }
KisMementoSP currentMemento()
void saveNewDefaultPixel(const quint8 *pixel, quint32 pixelSize)
Definition kis_memento.h:72

References KisMemento::saveNewDefaultPixel().

◆ debugPrintInfo()

void KisTiledDataManager::debugPrintInfo ( )
inline

◆ defaultPixel()

const quint8 * KisTiledDataManager::defaultPixel ( ) const
inline

Definition at line 81 of file kis_tiled_data_manager.h.

81 {
82 return m_defaultPixel;
83 }

◆ divideRoundDown()

qint32 KisTiledDataManager::divideRoundDown ( qint32 x,
const qint32 y ) const
inlineprivate

Equivalent to the following: -(( -x + (y-1) ) / y)

Definition at line 363 of file kis_tiled_data_manager.h.

364 {
370 return x >= 0 ? x / y : -(((-x - 1) / y) + 1);
371 }

◆ duplicatePixel()

quint8 * KisTiledDataManager::duplicatePixel ( qint32 num,
const quint8 * pixel )
private

Definition at line 296 of file kis_tiled_data_manager.cc.

297{
298 const qint32 pixelSize = this->pixelSize();
299 /* FIXME: Make a fun filling here */
300 quint8 *dstBuf = new quint8[num * pixelSize];
301 quint8 *dstIt = dstBuf;
302 for (qint32 i = 0; i < num; i++) {
303 memcpy(dstIt, pixel, pixelSize);
304 dstIt += pixelSize;
305 }
306 return dstBuf;
307}

References pixelSize().

◆ extent() [1/2]

QRect KisTiledDataManager::extent ( ) const

Definition at line 658 of file kis_tiled_data_manager.cc.

659{
660 return m_extentManager.extent();
661}

References KisTiledExtentManager::extent(), and m_extentManager.

◆ extent() [2/2]

void KisTiledDataManager::extent ( qint32 & x,
qint32 & y,
qint32 & w,
qint32 & h ) const

Definition at line 652 of file kis_tiled_data_manager.cc.

653{
654 QRect rect = extent();
655 rect.getRect(&x, &y, &w, &h);
656}

References extent().

◆ getMemento()

KisMementoSP KisTiledDataManager::getMemento ( )
inline

Definition at line 134 of file kis_tiled_data_manager.h.

134 {
135 QWriteLocker locker(&m_lock);
138 return memento;
139 }
void saveOldDefaultPixel(const quint8 *pixel, quint32 pixelSize)
Definition kis_memento.h:67

References KisMemento::saveOldDefaultPixel().

◆ getOldTile() [1/2]

KisTileSP KisTiledDataManager::getOldTile ( qint32 col,
qint32 row )
inline

Definition at line 129 of file kis_tiled_data_manager.h.

129 {
130 bool unused;
131 return getOldTile(col, row, unused);
132 }

◆ getOldTile() [2/2]

KisTileSP KisTiledDataManager::getOldTile ( qint32 col,
qint32 row,
bool & existingTile )
inline

Definition at line 124 of file kis_tiled_data_manager.h.

124 {
125 KisTileSP tile = m_mementoManager->getCommittedTile(col, row, existingTile);
126 return tile ? tile : getReadOnlyTileLazy(col, row, existingTile);
127 }
KisTileSP getCommittedTile(qint32 col, qint32 row, bool &existingTile)

◆ getReadOnlyTileLazy()

KisTileSP KisTiledDataManager::getReadOnlyTileLazy ( qint32 col,
qint32 row,
bool & existingTile )
inline

Definition at line 120 of file kis_tiled_data_manager.h.

120 {
121 return m_hashTable->getReadOnlyTileLazy(col, row, existingTile);
122 }
TileTypeSP getReadOnlyTileLazy(qint32 col, qint32 row, bool &existingTile)

◆ getTile()

KisTileSP KisTiledDataManager::getTile ( qint32 col,
qint32 row,
bool writable )
inline

Definition at line 105 of file kis_tiled_data_manager.h.

105 {
106 if (writable) {
107 bool newTile;
108 KisTileSP tile = m_hashTable->getTileLazy(col, row, newTile);
109 if (newTile) {
111 }
112 return tile;
113
114 } else {
115 bool unused;
116 return m_hashTable->getReadOnlyTileLazy(col, row, unused);
117 }
118 }
TileTypeSP getTileLazy(qint32 col, qint32 row, bool &newTile)
struct Tile * newTile(struct rect r)
Definition pixels.c:231

References newTile().

◆ getTilesPair()

void KisTiledDataManager::getTilesPair ( qint32 col,
qint32 row,
bool writable,
KisTileSP * tile,
KisTileSP * oldTile )
inline

Every iterator fetches both types of tiles all the time: old and new. For projection devices these tiles are always the same, but doing two distinct calls makes double pressure on the read-write lock in the hash table.

Merging two calls into one allows us to avoid additional tile fetch from the hash table and therefore reduce waiting time.

Definition at line 94 of file kis_tiled_data_manager.h.

94 {
95 *tile = getTile(col, row, writable);
96
97 bool unused;
98 *oldTile = m_mementoManager->getCommittedTile(col, row, unused);
99
100 if (!*oldTile) {
101 *oldTile = *tile;
102 }
103 }
KisTileSP getTile(qint32 col, qint32 row, bool writable)

◆ hasCurrentMemento()

bool KisTiledDataManager::hasCurrentMemento ( ) const
inline

Definition at line 177 of file kis_tiled_data_manager.h.

177 {
179 //return true;
180 }

◆ numContiguousColumns()

qint32 KisTiledDataManager::numContiguousColumns ( qint32 x,
qint32 minY,
qint32 maxY ) const

Get the number of contiguous columns starting at x, valid for all values of y between minY and maxY.

Definition at line 739 of file kis_tiled_data_manager.cc.

740{
741 qint32 numColumns;
742
743 Q_UNUSED(minY);
744 Q_UNUSED(maxY);
745
746 if (x >= 0) {
747 numColumns = KisTileData::WIDTH - (x % KisTileData::WIDTH);
748 } else {
749 numColumns = ((-x - 1) % KisTileData::WIDTH) + 1;
750 }
751
752 return numColumns;
753}

References KisTileData::WIDTH.

◆ numContiguousRows()

qint32 KisTiledDataManager::numContiguousRows ( qint32 y,
qint32 minX,
qint32 maxX ) const

Get the number of contiguous rows starting at y, valid for all values of x between minX and maxX.

Definition at line 755 of file kis_tiled_data_manager.cc.

756{
757 qint32 numRows;
758
759 Q_UNUSED(minX);
760 Q_UNUSED(maxX);
761
762 if (y >= 0) {
764 } else {
765 numRows = ((-y - 1) % KisTileData::HEIGHT) + 1;
766 }
767
768 return numRows;
769}

References KisTileData::HEIGHT.

◆ operator=()

KisTiledDataManager & KisTiledDataManager::operator= ( const KisTiledDataManager & dm)

◆ pixelSize()

quint32 KisTiledDataManager::pixelSize ( ) const
inlineprotected

Definition at line 204 of file kis_tiled_data_manager.h.

204 {
205 return m_pixelSize;
206 }

◆ processTilesHeader()

bool KisTiledDataManager::processTilesHeader ( QIODevice * stream,
quint32 & numTiles )
private

We assume that there is only one version of this header possible. In case we invent something new, it'll be quite easy to modify the behavior

Definition at line 209 of file kis_tiled_data_manager.cc.

210{
217 const qint32 maxLineLength = 25;
218 const qint32 totalNumTests = 4;
219 bool foundDataMark = false;
220 qint32 testsPassed = 0;
221
222 QString keyword;
223 qint32 value;
224
225 while(!foundDataMark && stream->canReadLine()) {
226 takeOneLine(stream, maxLineLength, keyword, value);
227
228 if (keyword == "TILEWIDTH") {
230 goto wrongString;
231 }
232 else if (keyword == "TILEHEIGHT") {
234 goto wrongString;
235 }
236 else if (keyword == "PIXELSIZE") {
237 if((quint32)value != pixelSize())
238 goto wrongString;
239 }
240 else if (keyword == "DATA") {
241 numTiles = value;
242 foundDataMark = true;
243 }
244 else {
245 goto wrongString;
246 }
247
248 testsPassed++;
249 }
250
251 if(testsPassed != totalNumTests) {
252 warnTiles << "Not enough fields of tiles header present"
253 << testsPassed << "of" << totalNumTests;
254 }
255
256 return testsPassed == totalNumTests;
257
258wrongString:
259 warnTiles << "Wrong string in tiles header:" << keyword << value;
260 return false;
261}
float value(const T *src, size_t ch)
#define warnTiles
Definition kis_debug.h:91
#define takeOneLine(stream, maxLine, keyword, value)

References KisTileData::HEIGHT, pixelSize(), takeOneLine, value(), warnTiles, and KisTileData::WIDTH.

◆ purge()

void KisTiledDataManager::purge ( const QRect & area)
protected

Definition at line 263 of file kis_tiled_data_manager.cc.

264{
265 QList<KisTileSP> tilesToDelete;
266 {
267 const qint32 tileDataSize = KisTileData::HEIGHT * KisTileData::WIDTH * pixelSize();
269 tileData->blockSwapping();
270 const quint8 *defaultData = tileData->data();
271
273 KisTileSP tile;
274
275 while ((tile = iter.tile())) {
276 if (tile->extent().intersects(area)) {
277 tile->lockForRead();
278 if(memcmp(defaultData, tile->data(), tileDataSize) == 0) {
279 tilesToDelete.push_back(tile);
280 }
281 tile->unlockForRead();
282 }
283 iter.next();
284 }
285
286 tileData->unblockSwapping();
287 tileData->deref();
288 }
289 Q_FOREACH (KisTileSP tile, tilesToDelete) {
290 if (m_hashTable->deleteTile(tile)) {
291 m_extentManager.notifyTileRemoved(tile->col(), tile->row());
292 }
293 }
294}
void unblockSwapping()
void blockSwapping()
quint8 * data() const
qint32 row() const
Definition kis_tile.h:92
qint32 col() const
Definition kis_tile.h:95
QRect extent() const
Definition kis_tile.h:99

References KisTileData::blockSwapping(), KisTile::col(), KisTile::data(), KisTileData::data(), KisTileHashTableTraits< T >::deleteTile(), KisTileData::deref(), KisTile::extent(), KisTileData::HEIGHT, KisTile::lockForRead(), m_extentManager, m_hashTable, KisTileHashTableIteratorTraits< T, LockerType >::next(), KisTiledExtentManager::notifyTileRemoved(), pixelSize(), KisTileHashTableTraits< T >::refAndFetchDefaultTileData(), KisTile::row(), KisTileHashTableIteratorTraits< T, LockerType >::tile(), KisTileData::unblockSwapping(), KisTile::unlockForRead(), and KisTileData::WIDTH.

◆ purgeHistory()

void KisTiledDataManager::purgeHistory ( KisMementoSP oldestMemento)
inline

Removes all the history that precedes the revision pointed by oldestMemento. That is after calling to purgeHistory(someMemento) you won't be able to do rollback(someMemento) anymore.

Definition at line 188 of file kis_tiled_data_manager.h.

188 {
189 QWriteLocker locker(&m_lock);
190 m_mementoManager->purgeHistory(oldestMemento);
191 }
void purgeHistory(KisMementoSP oldestMemento)

◆ read()

bool KisTiledDataManager::read ( QIODevice * stream)
protected

Definition at line 133 of file kis_tiled_data_manager.cc.

134{
135 clear();
136
137 QWriteLocker locker(&m_lock);
139
140 if (!stream) {
142 return false;
143 }
144
145 const qint32 maxLineLength = 79; // Legacy magic
146 QByteArray line = stream->readLine(maxLineLength);
147 line = line.trimmed();
148
149 quint32 numTiles;
150 qint32 tilesVersion = LEGACY_VERSION;
151
152 if (line[0] == 'V') {
153 QList<QByteArray> lineItems = line.split(' ');
154
155 QString keyword = lineItems.takeFirst();
156 Q_ASSERT(keyword == "VERSION");
157
158 tilesVersion = lineItems.takeFirst().toInt();
159
160 if(!processTilesHeader(stream, numTiles))
161 return false;
162 }
163 else {
164 numTiles = line.toUInt();
165 }
166
167 KisAbstractTileCompressorSP compressor =
169
170 bool readSuccess = true;
171 for (quint32 i = 0; i < numTiles; i++) {
172 if (!compressor->readTile(stream, this)) {
173 readSuccess = false;
174 }
175 }
176
178 return readSuccess;
179}
static KisAbstractTileCompressorSP create(qint32 version)
static const qint32 LEGACY_VERSION
bool processTilesHeader(QIODevice *stream, quint32 &numTiles)

References clear(), KisMementoManager::commit(), KisTileCompressorFactory::create(), KisMementoManager::getMemento(), LEGACY_VERSION, m_lock, m_mementoManager, and processTilesHeader().

◆ readBytes()

void KisTiledDataManager::readBytes ( quint8 * bytes,
qint32 x,
qint32 y,
qint32 w,
qint32 h,
qint32 dataRowStride = -1 ) const

Copy the bytes in the specified rect to a vector. The caller is responsible for managing the vector.

Parameters
bytesthe bytes
xx of top left corner
yy of top left corner
wwidth
hheight
dataRowStrideis the step (in bytes) which should be added to bytes pointer to get to the next row

Definition at line 694 of file kis_tiled_data_manager.cc.

698{
699 QReadLocker locker(&m_lock);
700 // Actual bytes reading/writing is done in private header
701 readBytesBody(data, x, y, width, height, dataRowStride);
702}
void readBytesBody(quint8 *data, qint32 x, qint32 y, qint32 width, qint32 height, qint32 dataRowStride=-1) const

References m_lock, and readBytesBody().

◆ readBytesBody()

void KisTiledDataManager::readBytesBody ( quint8 * data,
qint32 x,
qint32 y,
qint32 width,
qint32 height,
qint32 dataRowStride = -1 ) const
private

Definition at line 78 of file kis_tiled_data_manager_p.h.

82{
83 if (!data) return;
84
85 width = width < 0 ? 0 : width;
86 height = height < 0 ? 0 : height;
87
88 qint32 dataY = 0;
89 qint32 imageY = y;
90 qint32 rowsRemaining = height;
91 const qint32 pixelSize = this->pixelSize();
92
93 if (dataRowStride <= 0) {
94 dataRowStride = pixelSize * width;
95 }
96
97 while (rowsRemaining > 0) {
98
99 qint32 dataX = 0;
100 qint32 imageX = x;
101 qint32 columnsRemaining = width;
102 qint32 numContiguousImageRows = numContiguousRows(imageY, imageX,
103 imageX + width - 1);
104
105 qint32 rowsToWork = qMin(numContiguousImageRows, rowsRemaining);
106
107 while (columnsRemaining > 0) {
108
109 qint32 numContiguousImageColumns = numContiguousColumns(imageX, imageY,
110 imageY + rowsToWork - 1);
111
112 qint32 columnsToWork = qMin(numContiguousImageColumns,
113 columnsRemaining);
114
115 // XXX: Ugly const cast because of the old pixelPtr design copied from tiles1.
116 KisTileDataWrapper tw(const_cast<KisTiledDataManager*>(this), imageX, imageY, KisTileDataWrapper::READ);
117 quint8 *tileIt = tw.data();
118
119
120 const qint32 tileRowStride = rowStride(imageX, imageY);
121
122 quint8 *dataIt = data +
123 dataX * pixelSize + dataY * dataRowStride;
124
125 const qint32 lineSize = columnsToWork * pixelSize;
126
127 for (qint32 row = 0; row < rowsToWork; row++) {
128 memcpy(dataIt, tileIt, lineSize);
129 tileIt += tileRowStride;
130 dataIt += dataRowStride;
131 }
132
133 imageX += columnsToWork;
134 dataX += columnsToWork;
135 columnsRemaining -= columnsToWork;
136 }
137
138 imageY += rowsToWork;
139 dataY += rowsToWork;
140 rowsRemaining -= rowsToWork;
141 }
142}
qint32 numContiguousRows(qint32 y, qint32 minX, qint32 maxX) const
qint32 numContiguousColumns(qint32 x, qint32 minY, qint32 maxY) const

References KisTileDataWrapper::data(), numContiguousColumns(), numContiguousRows(), pixelSize(), KisTileDataWrapper::READ, and rowStride().

◆ readPlanarBytes()

QVector< quint8 * > KisTiledDataManager::readPlanarBytes ( QVector< qint32 > channelsizes,
qint32 x,
qint32 y,
qint32 w,
qint32 h ) const

Copy the bytes in the paint device into a vector of arrays of bytes, where the number of arrays is the number of channels in the paint device. If the specified area is larger than the paint device's extent, the default pixel will be read.

Definition at line 705 of file kis_tiled_data_manager.cc.

708{
709 QReadLocker locker(&m_lock);
710 // Actual bytes reading/writing is done in private header
711 return readPlanarBytesBody(channelSizes, x, y, width, height);
712}
QVector< quint8 * > readPlanarBytesBody(QVector< qint32 > channelsizes, qint32 x, qint32 y, qint32 w, qint32 h) const

References m_lock, and readPlanarBytesBody().

◆ readPlanarBytesBody()

QVector< quint8 * > KisTiledDataManager::readPlanarBytesBody ( QVector< qint32 > channelsizes,
qint32 x,
qint32 y,
qint32 w,
qint32 h ) const
private

Definition at line 229 of file kis_tiled_data_manager_p.h.

232{
233 Q_ASSERT(channelSizes.size() > 0);
234
235 width = width < 0 ? 0 : width;
236 height = height < 0 ? 0 : height;
237
238 const qint32 numChannels = channelSizes.size();
239 const qint32 pixelSize = this->pixelSize();
240
241 QVector<quint8*> planes;
242 forEachChannel(i, channelSize) {
243 planes.append(new quint8[width * height * channelSize]);
244 }
245
246 qint32 dataY = 0;
247 qint32 imageY = y;
248 qint32 rowsRemaining = height;
249
250 while (rowsRemaining > 0) {
251
252 qint32 dataX = 0;
253 qint32 imageX = x;
254 qint32 columnsRemaining = width;
255 qint32 numContiguousImageRows = numContiguousRows(imageY, imageX,
256 imageX + width - 1);
257
258 qint32 rowsToWork = qMin(numContiguousImageRows, rowsRemaining);
259
260 while (columnsRemaining > 0) {
261
262 qint32 numContiguousImageColumns =
263 numContiguousColumns(imageX, imageY,
264 imageY + rowsToWork - 1);
265 qint32 columnsToWork = qMin(numContiguousImageColumns,
266 columnsRemaining);
267
268 const qint32 dataIdx = dataX + dataY * width;
269 const qint32 tileRowStride = rowStride(imageX, imageY) -
270 columnsToWork * pixelSize;
271
272 // XXX: Ugly const cast because of the old pixelPtr design copied from tiles1.
273 KisTileDataWrapper tw(const_cast<KisTiledDataManager*>(this), imageX, imageY,
275 quint8 *tileItStart = tw.data();
276
277
278 forEachChannel(i, channelSize) {
279 quint8* planeIt = planes[i] + dataIdx * channelSize;
280 qint32 dataStride = (width - columnsToWork) * channelSize;
281 quint8* tileIt = tileItStart;
282
283 for (qint32 row = 0; row < rowsToWork; row++) {
284 for (int col = 0; col < columnsToWork; col++) {
285 memcpy(planeIt, tileIt, channelSize);
286 tileIt += pixelSize;
287 planeIt += channelSize;
288 }
289
290 tileIt += tileRowStride;
291 planeIt += dataStride;
292 }
293 tileItStart += channelSize;
294 }
295
296 imageX += columnsToWork;
297 dataX += columnsToWork;
298 columnsRemaining -= columnsToWork;
299 }
300
301
302 imageY += rowsToWork;
303 dataY += rowsToWork;
304 rowsRemaining -= rowsToWork;
305 }
306 return planes;
307}
#define forEachChannel(_idx, _channelSize)

References KisTileDataWrapper::data(), forEachChannel, numContiguousColumns(), numContiguousRows(), pixelSize(), KisTileDataWrapper::READ, and rowStride().

◆ recalculateExtent()

void KisTiledDataManager::recalculateExtent ( )
private

Definition at line 635 of file kis_tiled_data_manager.cc.

636{
637 QVector<QPoint> indexes;
638
639 {
641 KisTileSP tile;
642
643 while ((tile = iter.tile())) {
644 indexes << QPoint(tile->col(), tile->row());
645 iter.next();
646 }
647 }
648
650}
void replaceTileStats(const QVector< QPoint > &indexes)

References KisTile::col(), m_extentManager, m_hashTable, KisTileHashTableIteratorTraits< T, LockerType >::next(), KisTiledExtentManager::replaceTileStats(), KisTile::row(), and KisTileHashTableIteratorTraits< T, LockerType >::tile().

◆ region()

KisRegion KisTiledDataManager::region ( ) const

Definition at line 663 of file kis_tiled_data_manager.cc.

664{
665 QVector<QRect> rects;
666
668 KisTileSP tile;
669
670 while ((tile = iter.tile())) {
671 rects << tile->extent();
672 iter.next();
673 }
674
675 return KisRegion(std::move(rects));
676}

References KisTile::extent(), m_hashTable, KisTileHashTableIteratorTraits< T, LockerType >::next(), and KisTileHashTableIteratorTraits< T, LockerType >::tile().

◆ releaseInternalPools()

void KisTiledDataManager::releaseInternalPools ( )
static

Definition at line 779 of file kis_tiled_data_manager.cc.

780{
782}
static void releaseInternalPools()

References KisTileData::releaseInternalPools().

◆ rollback()

void KisTiledDataManager::rollback ( KisMementoSP memento)
inline

Definition at line 155 of file kis_tiled_data_manager.h.

155 {
156 commit();
157
158 QWriteLocker locker(&m_lock);
160 const quint8 *defaultPixel = memento->oldDefaultPixel();
163 }
165 }
void rollback(KisTileHashTable *ht, KisMementoSP memento)
const quint8 * oldDefaultPixel() const
Definition kis_memento.h:77
void setDefaultPixelImpl(const quint8 *defPixel)

References KisMemento::oldDefaultPixel().

◆ rollforward()

void KisTiledDataManager::rollforward ( KisMementoSP memento)
inline

Definition at line 166 of file kis_tiled_data_manager.h.

166 {
167 commit();
168
169 QWriteLocker locker(&m_lock);
171 const quint8 *defaultPixel = memento->newDefaultPixel();
174 }
176 }
void rollforward(KisTileHashTable *ht, KisMementoSP memento)
const quint8 * newDefaultPixel() const
Definition kis_memento.h:81

References KisMemento::newDefaultPixel().

◆ rowStride()

qint32 KisTiledDataManager::rowStride ( qint32 x,
qint32 y ) const

Get the row stride at pixel (x, y). This is the number of bytes to add to a pointer to pixel (x, y) to access (x, y + 1).

Definition at line 771 of file kis_tiled_data_manager.cc.

772{
773 Q_UNUSED(x);
774 Q_UNUSED(y);
775
776 return KisTileData::WIDTH * pixelSize();
777}

References pixelSize(), and KisTileData::WIDTH.

◆ setDefaultPixel()

void KisTiledDataManager::setDefaultPixel ( const quint8 * defPixel)

Definition at line 85 of file kis_tiled_data_manager.cc.

86{
87 QWriteLocker locker(&m_lock);
89}

References defaultPixel(), m_lock, and setDefaultPixelImpl().

◆ setDefaultPixelImpl()

◆ setExtent() [1/2]

void KisTiledDataManager::setExtent ( qint32 x,
qint32 y,
qint32 w,
qint32 h )

Definition at line 580 of file kis_tiled_data_manager.cc.

581{
582 setExtent(QRect(x, y, w, h));
583}
void setExtent(qint32 x, qint32 y, qint32 w, qint32 h)

References setExtent().

◆ setExtent() [2/2]

void KisTiledDataManager::setExtent ( QRect newRect)

Definition at line 585 of file kis_tiled_data_manager.cc.

586{
587 QRect oldRect = extent();
588 newRect = newRect.normalized();
589
590 // Do nothing if the desired size is bigger than we currently are:
591 // that is handled by the autoextending automatically
592 if (newRect.contains(oldRect)) return;
593
594 KisTileSP tile;
595 QRect tileRect;
596 {
598
599 while (!iter.isDone()) {
600 tile = iter.tile();
601
602 tileRect = tile->extent();
603 if (newRect.contains(tileRect)) {
604 //do nothing
605 iter.next();
606 } else if (newRect.intersects(tileRect)) {
607 QRect intersection = newRect & tileRect;
608 intersection.translate(- tileRect.topLeft());
609
610 const qint32 pixelSize = this->pixelSize();
611
612 tile->lockForWrite();
613 quint8* data = tile->data();
614 quint8* ptr;
615
616 /* FIXME: make it faster */
617 for (int y = 0; y < KisTileData::HEIGHT; y++) {
618 for (int x = 0; x < KisTileData::WIDTH; x++) {
619 if (!intersection.contains(x, y)) {
620 ptr = data + pixelSize * (y * KisTileData::WIDTH + x);
621 memcpy(ptr, m_defaultPixel, pixelSize);
622 }
623 }
624 }
625 tile->unlockForWrite();
626 iter.next();
627 } else {
628 m_extentManager.notifyTileRemoved(tile->col(), tile->row());
629 iter.deleteCurrent();
630 }
631 }
632 }
633}
void lockForWrite()
Definition kis_tile.cc:221
void unlockForWrite()
Definition kis_tile.cc:264

References KisTile::col(), KisTile::data(), KisTileHashTableIteratorTraits< T, LockerType >::deleteCurrent(), KisTile::extent(), extent(), KisTileData::HEIGHT, KisTileHashTableIteratorTraits< T, LockerType >::isDone(), KisTile::lockForWrite(), m_defaultPixel, m_extentManager, m_hashTable, KisTileHashTableIteratorTraits< T, LockerType >::next(), KisTiledExtentManager::notifyTileRemoved(), pixelSize(), KisTile::row(), KisTileHashTableIteratorTraits< T, LockerType >::tile(), KisTile::unlockForWrite(), and KisTileData::WIDTH.

◆ setPixel()

void KisTiledDataManager::setPixel ( qint32 x,
qint32 y,
const quint8 * data )

write the specified data to x, y. There is no checking on pixelSize!

Definition at line 678 of file kis_tiled_data_manager.cc.

679{
681 memcpy(tw.data(), data, pixelSize());
682}

References KisTileDataWrapper::data(), pixelSize(), and KisTileDataWrapper::WRITE.

◆ write()

bool KisTiledDataManager::write ( KisPaintDeviceWriter & store)
protected

Reads and writes the tiles

Definition at line 100 of file kis_tiled_data_manager.cc.

101{
102 QReadLocker locker(&m_lock);
103
104 bool retval = true;
105
107 char str[80];
108 sprintf(str, "%d\n", m_hashTable->numTiles());
109 retval = store.write(str, strlen(str));
110 }
111 else {
112 retval = writeTilesHeader(store, m_hashTable->numTiles());
113 }
114
115
117 KisTileSP tile;
118
119 KisAbstractTileCompressorSP compressor =
121
122 while ((tile = iter.tile())) {
123 retval = compressor->writeTile(tile, store);
124 if (!retval) {
125 warnFile << "Failed to write tile";
126 break;
127 }
128 iter.next();
129 }
130
131 return retval;
132}
virtual bool write(const QByteArray &data)=0
bool writeTilesHeader(KisPaintDeviceWriter &store, quint32 numTiles)
static const qint32 CURRENT_VERSION
#define warnFile
Definition kis_debug.h:95

References KisTileCompressorFactory::create(), CURRENT_VERSION, LEGACY_VERSION, m_hashTable, m_lock, KisTileHashTableIteratorTraits< T, LockerType >::next(), KisTileHashTableTraits< T >::numTiles(), KisTileHashTableIteratorTraits< T, LockerType >::tile(), warnFile, KisPaintDeviceWriter::write(), and writeTilesHeader().

◆ writeBytes()

void KisTiledDataManager::writeBytes ( const quint8 * bytes,
qint32 x,
qint32 y,
qint32 w,
qint32 h,
qint32 dataRowStride = -1 )

Copy the bytes in the vector to the specified rect. If there are bytes left in the vector after filling the rect, they will be ignored. If there are not enough bytes, the rest of the rect will be filled with the default value given (by default, 0);

Parameters
bytesthe bytes
xx of top left corner
yy of top left corner
wwidth
hheight
dataRowStrideis the step (in bytes) which should be added to bytes pointer to get to the next row

Definition at line 684 of file kis_tiled_data_manager.cc.

688{
689 QWriteLocker locker(&m_lock);
690 // Actual bytes reading/writing is done in private header
691 writeBytesBody(data, x, y, width, height, dataRowStride);
692}
void writeBytesBody(const quint8 *data, qint32 x, qint32 y, qint32 width, qint32 height, qint32 dataRowStride=-1)

References m_lock, and writeBytesBody().

◆ writeBytesBody()

void KisTiledDataManager::writeBytesBody ( const quint8 * data,
qint32 x,
qint32 y,
qint32 width,
qint32 height,
qint32 dataRowStride = -1 )
private

Definition at line 11 of file kis_tiled_data_manager_p.h.

15{
16 if (!data) return;
17
18 width = width < 0 ? 0 : width;
19 height = height < 0 ? 0 : height;
20
21 qint32 dataY = 0;
22 qint32 imageY = y;
23 qint32 rowsRemaining = height;
24 const qint32 pixelSize = this->pixelSize();
25
26 if (dataRowStride <= 0) {
27 dataRowStride = pixelSize * width;
28 }
29
30 while (rowsRemaining > 0) {
31
32 qint32 dataX = 0;
33 qint32 imageX = x;
34 qint32 columnsRemaining = width;
35 qint32 numContiguousImageRows = numContiguousRows(imageY, imageX,
36 imageX + width - 1);
37
38 qint32 rowsToWork = qMin(numContiguousImageRows, rowsRemaining);
39
40 while (columnsRemaining > 0) {
41
42 qint32 numContiguousImageColumns =
43 numContiguousColumns(imageX, imageY,
44 imageY + rowsToWork - 1);
45
46 qint32 columnsToWork = qMin(numContiguousImageColumns,
47 columnsRemaining);
48
49 KisTileDataWrapper tw(this, imageX, imageY, KisTileDataWrapper::WRITE);
50 quint8 *tileIt = tw.data();
51
52
53 const qint32 tileRowStride = rowStride(imageX, imageY);
54
55 const quint8 *dataIt = data +
56 dataX * pixelSize + dataY * dataRowStride;
57
58 const qint32 lineSize = columnsToWork * pixelSize;
59
60 for (qint32 row = 0; row < rowsToWork; row++) {
61 memcpy(tileIt, dataIt, lineSize);
62 tileIt += tileRowStride;
63 dataIt += dataRowStride;
64 }
65
66 imageX += columnsToWork;
67 dataX += columnsToWork;
68 columnsRemaining -= columnsToWork;
69 }
70
71 imageY += rowsToWork;
72 dataY += rowsToWork;
73 rowsRemaining -= rowsToWork;
74 }
75}

References KisTileDataWrapper::data(), numContiguousColumns(), numContiguousRows(), pixelSize(), rowStride(), and KisTileDataWrapper::WRITE.

◆ writePlanarBytes()

void KisTiledDataManager::writePlanarBytes ( QVector< quint8 * > planes,
QVector< qint32 > channelsizes,
qint32 x,
qint32 y,
qint32 w,
qint32 h )

Write the data in the separate arrays to the channels. If there are less vectors than channels, the remaining channels will not be copied. If any of the arrays points to 0, the channel in that location will not be touched. If the specified area is larger than the paint device, the paint device will be extended. There are no guards: if the area covers more pixels than there are bytes in the arrays, krita will happily fill your paint device with areas of memory you never wanted to be read. Krita may also crash.

Definition at line 715 of file kis_tiled_data_manager.cc.

719{
720 QWriteLocker locker(&m_lock);
721 // Actual bytes reading/writing is done in private header
722
723 bool allChannelsPresent = true;
724
725 Q_FOREACH (const quint8* plane, planes) {
726 if (!plane) {
727 allChannelsPresent = false;
728 break;
729 }
730 }
731
732 if (allChannelsPresent) {
733 writePlanarBytesBody<true>(planes, channelSizes, x, y, width, height);
734 } else {
735 writePlanarBytesBody<false>(planes, channelSizes, x, y, width, height);
736 }
737}

References m_lock.

◆ writePlanarBytesBody()

template<bool allChannelsPresent>
void KisTiledDataManager::writePlanarBytesBody ( QVector< quint8 * > planes,
QVector< qint32 > channelsizes,
qint32 x,
qint32 y,
qint32 w,
qint32 h )
private

Definition at line 151 of file kis_tiled_data_manager_p.h.

155{
156 Q_ASSERT(planes.size() == channelSizes.size());
157 Q_ASSERT(planes.size() > 0);
158
159 width = width < 0 ? 0 : width;
160 height = height < 0 ? 0 : height;
161
162 const qint32 numChannels = planes.size();
163 const qint32 pixelSize = this->pixelSize();
164
165 qint32 dataY = 0;
166 qint32 imageY = y;
167 qint32 rowsRemaining = height;
168
169 while (rowsRemaining > 0) {
170
171 qint32 dataX = 0;
172 qint32 imageX = x;
173 qint32 columnsRemaining = width;
174 qint32 numContiguousImageRows = numContiguousRows(imageY, imageX,
175 imageX + width - 1);
176
177 qint32 rowsToWork = qMin(numContiguousImageRows, rowsRemaining);
178
179 while (columnsRemaining > 0) {
180
181 qint32 numContiguousImageColumns =
182 numContiguousColumns(imageX, imageY,
183 imageY + rowsToWork - 1);
184 qint32 columnsToWork = qMin(numContiguousImageColumns,
185 columnsRemaining);
186
187 const qint32 dataIdx = dataX + dataY * width;
188 const qint32 tileRowStride = rowStride(imageX, imageY) -
189 columnsToWork * pixelSize;
190
191 KisTileDataWrapper tw(this, imageX, imageY,
193 quint8 *tileItStart = tw.data();
194
195
196 forEachChannel(i, channelSize) {
197 if (allChannelsPresent || planes[i]) {
198 const quint8* planeIt = planes[i] + dataIdx * channelSize;
199 qint32 dataStride = (width - columnsToWork) * channelSize;
200 quint8* tileIt = tileItStart;
201
202 for (qint32 row = 0; row < rowsToWork; row++) {
203 for (int col = 0; col < columnsToWork; col++) {
204 memcpy(tileIt, planeIt, channelSize);
205 tileIt += pixelSize;
206 planeIt += channelSize;
207 }
208
209 tileIt += tileRowStride;
210 planeIt += dataStride;
211 }
212 }
213
214 tileItStart += channelSize;
215 }
216
217 imageX += columnsToWork;
218 dataX += columnsToWork;
219 columnsRemaining -= columnsToWork;
220 }
221
222
223 imageY += rowsToWork;
224 dataY += rowsToWork;
225 rowsRemaining -= rowsToWork;
226 }
227}

References KisTileDataWrapper::data(), forEachChannel, numContiguousColumns(), numContiguousRows(), pixelSize(), rowStride(), and KisTileDataWrapper::WRITE.

◆ writeTilesHeader()

bool KisTiledDataManager::writeTilesHeader ( KisPaintDeviceWriter & store,
quint32 numTiles )
private

Definition at line 181 of file kis_tiled_data_manager.cc.

182{
183 QString buffer;
184
185 buffer = QString("VERSION %1\n"
186 "TILEWIDTH %2\n"
187 "TILEHEIGHT %3\n"
188 "PIXELSIZE %4\n"
189 "DATA %5\n")
190 .arg(CURRENT_VERSION)
193 .arg(pixelSize())
194 .arg(numTiles);
195
196 return store.write(buffer.toLatin1());
197}

References CURRENT_VERSION, KisTileData::HEIGHT, pixelSize(), KisTileData::WIDTH, and KisPaintDeviceWriter::write().

◆ xToCol()

qint32 KisTiledDataManager::xToCol ( qint32 x) const
inlineprivate

Definition at line 348 of file kis_tiled_data_manager.h.

349 {
351 }
qint32 divideRoundDown(qint32 x, const qint32 y) const

References KisTileData::WIDTH.

◆ yToRow()

qint32 KisTiledDataManager::yToRow ( qint32 y) const
inlineprivate

Definition at line 352 of file kis_tiled_data_manager.h.

353 {
355 }

References KisTileData::HEIGHT.

Friends And Related Symbol Documentation

◆ KisAbstractTileCompressor

friend class KisAbstractTileCompressor
friend

Definition at line 346 of file kis_tiled_data_manager.h.

◆ KisBaseIterator

friend class KisBaseIterator
friend

Definition at line 74 of file kis_tiled_data_manager.h.

◆ KisRandomAccessor2

friend class KisRandomAccessor2
friend

Definition at line 76 of file kis_tiled_data_manager.h.

◆ KisStressJob

friend class KisStressJob
friend

Definition at line 77 of file kis_tiled_data_manager.h.

◆ KisTileDataWrapper

friend class KisTileDataWrapper
friend

Definition at line 347 of file kis_tiled_data_manager.h.

◆ KisTiledIterator

friend class KisTiledIterator
friend

Definition at line 73 of file kis_tiled_data_manager.h.

◆ KisTiledRandomAccessor

friend class KisTiledRandomAccessor
friend

Definition at line 75 of file kis_tiled_data_manager.h.

Member Data Documentation

◆ CURRENT_VERSION

const qint32 KisTiledDataManager::CURRENT_VERSION = 2
staticprivate

Definition at line 59 of file kis_tiled_data_manager.h.

◆ LEGACY_VERSION

const qint32 KisTiledDataManager::LEGACY_VERSION = 1
staticprivate

Definition at line 58 of file kis_tiled_data_manager.h.

◆ m_defaultPixel

quint8* KisTiledDataManager::m_defaultPixel
private

Definition at line 337 of file kis_tiled_data_manager.h.

◆ m_extentManager

KisTiledExtentManager KisTiledDataManager::m_extentManager
private

Definition at line 339 of file kis_tiled_data_manager.h.

◆ m_hashTable

KisTileHashTable* KisTiledDataManager::m_hashTable
private

Definition at line 335 of file kis_tiled_data_manager.h.

◆ m_lock

QReadWriteLock KisTiledDataManager::m_lock
mutableprivate

Definition at line 341 of file kis_tiled_data_manager.h.

◆ m_mementoManager

KisMementoManager* KisTiledDataManager::m_mementoManager
private

Definition at line 336 of file kis_tiled_data_manager.h.

◆ m_pixelSize

qint32 KisTiledDataManager::m_pixelSize
private

Definition at line 338 of file kis_tiled_data_manager.h.


The documentation for this class was generated from the following files: