File indexing completed on 2024-05-12 15:58:51
0001 /* 0002 * SPDX-FileCopyrightText: 2018 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KISFASTDEVICEPROCESSINGUTILS_H 0008 #define KISFASTDEVICEPROCESSINGUTILS_H 0009 0010 #include "kis_random_accessor_ng.h" 0011 #include <KoAlwaysInline.h> 0012 0013 namespace KritaUtils { 0014 0015 0016 /** 0017 * this is a special helper function for iterating 0018 * through pixels in an extremely efficient way. One 0019 * should either pass a functor or a lambda to it. 0020 */ 0021 template <class PixelProcessor> 0022 void processTwoDevices(const QRect &rc, 0023 KisRandomConstAccessorSP srcIt, 0024 KisRandomAccessorSP dstIt, 0025 const int srcPixelSize, 0026 const int dstPixelSize, 0027 PixelProcessor pixelProcessor) 0028 { 0029 qint32 dstY = rc.y(); 0030 qint32 rowsRemaining = rc.height(); 0031 0032 while (rowsRemaining > 0) { 0033 qint32 dstX = rc.x(); 0034 0035 qint32 numContiguousSrcRows = srcIt->numContiguousRows(dstY); 0036 qint32 numContiguousDstRows = dstIt->numContiguousRows(dstY); 0037 qint32 rows = std::min({rowsRemaining, numContiguousSrcRows, numContiguousDstRows}); 0038 0039 qint32 columnsRemaining = rc.width(); 0040 0041 while (columnsRemaining > 0) { 0042 0043 qint32 numContiguousSrcColumns = srcIt->numContiguousColumns(dstX); 0044 qint32 numContiguousDstColumns = dstIt->numContiguousColumns(dstX); 0045 qint32 columns = std::min({columnsRemaining, numContiguousSrcColumns, numContiguousDstColumns}); 0046 0047 qint32 dstRowStride = dstIt->rowStride(dstX, dstY); 0048 qint32 srcRowStride = srcIt->rowStride(dstX, dstY); 0049 0050 dstIt->moveTo(dstX, dstY); 0051 srcIt->moveTo(dstX, dstY); 0052 0053 quint8 *dstRowStart = dstIt->rawData(); 0054 const quint8 *srcRowStart = srcIt->rawDataConst(); 0055 0056 for (int i = 0; i < rows; i++) { 0057 const quint8 *srcPtr = reinterpret_cast<const quint8*>(srcRowStart); 0058 quint8 *dstPtr = reinterpret_cast<quint8*>(dstRowStart); 0059 0060 for (int j = 0; j < columns; j++) { 0061 pixelProcessor(srcPtr, dstPtr); 0062 0063 srcPtr += srcPixelSize; 0064 dstPtr += dstPixelSize; 0065 } 0066 0067 srcRowStart += srcRowStride; 0068 dstRowStart += dstRowStride; 0069 } 0070 0071 dstX += columns; 0072 columnsRemaining -= columns; 0073 } 0074 0075 dstY += rows; 0076 rowsRemaining -= rows; 0077 } 0078 } 0079 0080 /** 0081 * this is a special helper function for iterating through pixels in an 0082 * extremely efficient way using strides. One should either pass a functor or a 0083 * lambda to it. 0084 */ 0085 template <class PixelProcessor> 0086 void processTwoDevicesWithStrides(const QRect &rc, 0087 KisRandomConstAccessorSP srcIt, 0088 KisRandomAccessorSP dstIt, 0089 PixelProcessor pixelProcessor) 0090 { 0091 qint32 dstY = rc.y(); 0092 qint32 rowsRemaining = rc.height(); 0093 0094 while (rowsRemaining > 0) { 0095 qint32 dstX = rc.x(); 0096 0097 qint32 numContiguousSrcRows = srcIt->numContiguousRows(dstY); 0098 qint32 numContiguousDstRows = dstIt->numContiguousRows(dstY); 0099 qint32 rows = std::min({rowsRemaining, numContiguousSrcRows, numContiguousDstRows}); 0100 0101 qint32 columnsRemaining = rc.width(); 0102 0103 while (columnsRemaining > 0) { 0104 0105 qint32 numContiguousSrcColumns = srcIt->numContiguousColumns(dstX); 0106 qint32 numContiguousDstColumns = dstIt->numContiguousColumns(dstX); 0107 qint32 columns = std::min({columnsRemaining, numContiguousSrcColumns, numContiguousDstColumns}); 0108 0109 qint32 dstRowStride = dstIt->rowStride(dstX, dstY); 0110 qint32 srcRowStride = srcIt->rowStride(dstX, dstY); 0111 0112 dstIt->moveTo(dstX, dstY); 0113 srcIt->moveTo(dstX, dstY); 0114 0115 quint8 *dstRowStart = dstIt->rawData(); 0116 const quint8 *srcRowStart = srcIt->rawDataConst(); 0117 0118 pixelProcessor(srcRowStart, srcRowStride, 0119 dstRowStart, dstRowStride, 0120 rows, columns); 0121 0122 dstX += columns; 0123 columnsRemaining -= columns; 0124 } 0125 0126 dstY += rows; 0127 rowsRemaining -= rows; 0128 } 0129 } 0130 0131 } 0132 0133 0134 #endif // KISFASTDEVICEPROCESSINGUTILS_H