void KisConvolutionPainterTest::testAsymmConvolutionImp(QBitArray channelFlags) { qreal offset = 0.0; qreal factor = 1.0; Eigen::Matrix<qreal, 3, 3> filter = initAsymmFilter(offset, factor); QRect imageRect; int pixelSize = -1; QByteArray initialData; KisPaintDeviceSP dev = initAsymTestDevice(imageRect, pixelSize, initialData); KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMatrix(filter, offset, factor); KisConvolutionPainter gc(dev); gc.beginTransaction(); gc.setChannelFlags(channelFlags); QRect filterRect = imageRect.adjusted(1,1,-1,-1); gc.applyMatrix(kernel, dev, filterRect.topLeft(), filterRect.topLeft(), filterRect.size()); gc.deleteTransaction(); QByteArray resultData(initialData.size(), 0); dev->readBytes((quint8*)resultData.data(), imageRect); QRect filteredRect = imageRect.adjusted(1, 1, -1, -1); quint8 *srcPtr = (quint8*) initialData.data(); quint8 *resPtr = (quint8*) resultData.data(); for(int row = 0; row < imageRect.height(); row++) { for(int col = 0; col < imageRect.width(); col++) { bool isFiltered = filteredRect.contains(col, row); int pixelValue = 8 + row * imageRect.width() + col; KoColor filteredPixel(QColor(pixelValue, pixelValue, pixelValue, 255), dev->colorSpace()); KoColor resultPixel(dev->colorSpace()); for(int j = 0; j < pixelSize; j++) { resultPixel.data()[j] = isFiltered && channelFlags[j] ? filteredPixel.data()[j] : srcPtr[j]; } if(memcmp(resPtr, resultPixel.data(), pixelSize)) { printPixel("Actual: ", pixelSize, resPtr); printPixel("Expected:", pixelSize, resultPixel.data()); QFAIL("Failed to filter area"); } srcPtr += pixelSize; resPtr += pixelSize; } } }
// #include <valgrind/callgrind.h> void KisConvolutionPainterTest::benchmarkConvolution() { QImage referenceImage(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa.png"); QRect imageRect(QPoint(), referenceImage.size()); KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8()); dev->convertFromQImage(referenceImage, 0, 0, 0); qreal offset = 0.0; qreal factor = 1.0; Matrix<qreal, 3, 3> filter = initAsymmFilter(offset, factor); int diameter = 1; for (int i = 0; i < 10; i++) { KisCircleMaskGenerator* kas = new KisCircleMaskGenerator(diameter, 1.0, 5, 5, 2); KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMaskGenerator(kas); KisConvolutionPainter gc(dev); QTime timer; timer.start(); // CALLGRIND_START_INSTRUMENTATION; gc.beginTransaction(0); gc.applyMatrix(kernel, dev, imageRect.topLeft(), imageRect.topLeft(), imageRect.size()); gc.deleteTransaction(); // CALLGRIND_STOP_INSTRUMENTATION; qDebug() << "Diameter:" << diameter << "time:" << timer.elapsed(); if(diameter < 10) { diameter += 2; } else { diameter += 8; } } }