void KisConvolutionFilter::process(KisConstProcessingInformation srcInfo, KisProcessingInformation dstInfo, const QSize& size, const KisFilterConfiguration* config, KoUpdater* progressUpdater ) const { Q_UNUSED(config); const KisPaintDeviceSP src = srcInfo.paintDevice(); KisPaintDeviceSP dst = dstInfo.paintDevice(); QPoint dstTopLeft = dstInfo.topLeft(); QPoint srcTopLeft = srcInfo.topLeft(); Q_ASSERT(src != 0); Q_ASSERT(dst != 0); KisConvolutionPainter painter(dst, dstInfo.selection()); QBitArray channelFlags; if (config) { channelFlags = config->channelFlags(); } if (channelFlags.isEmpty() || !config) { channelFlags = QBitArray(src->colorSpace()->channelCount(), true); } // disable alpha channel channelFlags.clearBit(1); painter.setChannelFlags(channelFlags); painter.setProgress(progressUpdater); painter.applyMatrix(m_matrix, src, srcTopLeft, dstTopLeft, size, BORDER_REPEAT); }
void KoPatternGenerator::generate(KisProcessingInformation dstInfo, const QSize& size, const KisFilterConfiguration* config, KoUpdater* progressUpdater) const { KisPaintDeviceSP dst = dstInfo.paintDevice(); Q_ASSERT(!dst.isNull()); Q_ASSERT(config); if (!config) return; QString patternName = config->getString("pattern", "Grid01.pat"); KoResourceServer<KoPattern> *rserver = KoResourceServerProvider::instance()->patternServer(); KoPattern *pattern = rserver->resourceByName(patternName); // KoColor c = config->getColor("color"); KisFillPainter gc(dst); gc.setPattern(pattern); // gc.setPaintColor(c); gc.setProgress(progressUpdater); gc.setChannelFlags(config->channelFlags()); gc.setOpacity(OPACITY_OPAQUE_U8); gc.setSelection(dstInfo.selection()); gc.setWidth(size.width()); gc.setHeight(size.height()); gc.setFillStyle(KisFillPainter::FillStylePattern); gc.fillRect(QRect(dstInfo.topLeft(), size), pattern); gc.end(); }
void KisCubismFilter::process(KisConstProcessingInformation srcInfo, KisProcessingInformation dstInfo, const QSize& size, const KisFilterConfiguration* configuration, KoUpdater* progressUpdater ) const { Q_UNUSED(progressUpdater); const KisPaintDeviceSP src = srcInfo.paintDevice(); KisPaintDeviceSP dst = dstInfo.paintDevice(); QPoint dstTopLeft = dstInfo.topLeft(); QPoint srcTopLeft = srcInfo.topLeft(); Q_ASSERT(src); Q_ASSERT(dst); Q_ASSERT(configuration); //read the filter configuration values from the KisFilterConfiguration object quint32 tileSize = configuration->getInt("tileSize", 1); quint32 tileSaturation = configuration->getInt("tileSaturation"); if (srcInfo.selection()) { KisPaintDeviceSP dev = new KisPaintDevice(src->colorSpace()); cubism(src, srcTopLeft, dev, dstTopLeft, size, tileSize, tileSaturation); KisPainter gc(dst); gc.setSelection(srcInfo.selection()); gc.bitBlt(dstTopLeft.x(), dstTopLeft.y(), dev, dstTopLeft.x(), dstTopLeft.y(), size.width(), size.height()); gc.end(); } else { cubism(src, srcTopLeft, dst, dstTopLeft, size, tileSize, tileSaturation); } }
void ShivaGenerator::generate(KisProcessingInformation dstInfo, const QSize& size, const KisFilterConfiguration* config, KoUpdater* progressUpdater) const { Q_UNUSED(progressUpdater); KisPaintDeviceSP dst = dstInfo.paintDevice(); QPoint dstTopLeft = dstInfo.topLeft(); UpdaterProgressReport* report = 0; if (progressUpdater) { progressUpdater->setRange(0, size.height()); report = new UpdaterProgressReport(progressUpdater); } Q_ASSERT(!dst.isNull()); // Q_ASSERT(config); // TODO implement the generating of pixel OpenShiva::Kernel kernel; kernel.setSource(*m_source); if (config) { QMap<QString, QVariant> map = config->getProperties(); for (QMap<QString, QVariant>::iterator it = map.begin(); it != map.end(); ++it) { const GTLCore::Metadata::Entry* entry = kernel.metadata()->parameter(it.key().toAscii().data()); if (entry && entry->asParameterEntry()) { #if OPENSHIVA_12 GTLCore::Value val = qvariantToValue(it.value(), entry->asParameterEntry()->valueType()); #else GTLCore::Value val = qvariantToValue(it.value(), entry->asParameterEntry()->type()); #endif if(val.isValid()) { kernel.setParameter(it.key().toAscii().data(), val); } } } } { QMutexLocker l(shivaMutex); kernel.compile(); } if (kernel.isCompiled()) { PaintDeviceImage pdi(dst); #if OPENSHIVA_12 std::list< GTLCore::AbstractImage* > inputs; GTLCore::Region region(dstTopLeft.x(), dstTopLeft.y() , size.width(), size.height()); kernel.evaluatePixeles(region, inputs, &pdi, report ); #else std::list< const GTLCore::AbstractImage* > inputs; GTLCore::RegionI region(dstTopLeft.x(), dstTopLeft.y() , size.width(), size.height()); kernel.evaluatePixels(region, inputs, &pdi, report ); #endif } #if OPENSHIVA_13_OR_MORE else { dbgPlugins << "Error: " << kernel.compilationMessages().toString().c_str(); } #endif }
void KisFilterColorToAlpha::process(KisConstProcessingInformation srcInfo, KisProcessingInformation dstInfo, const QSize& size, const KisFilterConfiguration* config, KoUpdater* progressUpdater ) const { const KisPaintDeviceSP src = srcInfo.paintDevice(); KisPaintDeviceSP dst = dstInfo.paintDevice(); QPoint dstTopLeft = dstInfo.topLeft(); QPoint srcTopLeft = srcInfo.topLeft(); Q_ASSERT(src != 0); Q_ASSERT(dst != 0); if (config == 0) config = new KisFilterConfiguration("colortoalpha", 1); QVariant value; QColor cTA = (config->getProperty("targetcolor", value)) ? value.value<QColor>() : QColor(255, 255, 255); int threshold = (config->getProperty("threshold", value)) ? value.toInt() : 0; qreal thresholdF = threshold; KisRectIteratorPixel dstIt = dst->createRectIterator(dstTopLeft.x(), dstTopLeft.y(), size.width(), size.height(), dstInfo.selection()); KisRectConstIteratorPixel srcIt = src->createRectConstIterator(srcTopLeft.x(), srcTopLeft.y(), size.width(), size.height(), srcInfo.selection()); int totalCost = size.width() * size.height() / 100; if (totalCost == 0) totalCost = 1; int currentProgress = 0; const KoColorSpace * cs = src->colorSpace(); qint32 pixelsize = cs->pixelSize(); quint8* color = new quint8[pixelsize]; cs->fromQColor(cTA, color); while (! srcIt.isDone()) { if (srcIt.isSelected()) { quint8 d = cs->difference(color, srcIt.oldRawData()); qreal newOpacity; // = cs->opacityF(srcIt.rawData()); if (d >= threshold) { newOpacity = 1.0; } else { newOpacity = d / thresholdF; } memcpy(dstIt.rawData(), srcIt.rawData(), pixelsize); if(newOpacity < cs->opacityF(srcIt.rawData())) { cs->setOpacity(dstIt.rawData(), newOpacity, 1); } } if (progressUpdater) progressUpdater->setProgress((++currentProgress) / totalCost); ++srcIt; ++dstIt; } delete[] color; }
void KisSmallTilesFilter::process(KisConstProcessingInformation srcInfo, KisProcessingInformation dstInfo, const QSize& size, const KisFilterConfiguration* config, KoUpdater* progressUpdater ) const { const KisPaintDeviceSP src = srcInfo.paintDevice(); KisPaintDeviceSP dst = dstInfo.paintDevice(); QPoint dstTopLeft = dstInfo.topLeft(); QPoint srcTopLeft = srcInfo.topLeft(); Q_ASSERT(!src.isNull()); Q_ASSERT(!dst.isNull()); //read the filter configuration values from the KisFilterConfiguration object quint32 numberOfTiles = config->getInt("numberOfTiles", 2); QRect srcRect = src->exactBounds(); int w = static_cast<int>(srcRect.width() / numberOfTiles); int h = static_cast<int>(srcRect.height() / numberOfTiles); KisPaintDeviceSP tile = KisPaintDeviceSP(0); if (srcInfo.selection()) { KisPaintDeviceSP tmp = new KisPaintDevice(src->colorSpace()); KisPainter gc(tmp); gc.setCompositeOp(COMPOSITE_COPY); gc.bitBlt(0, 0, src, srcTopLeft.x(), srcTopLeft.y(), size.width(), size.height()); tile = tmp->createThumbnailDevice(srcRect.width() / numberOfTiles, srcRect.height() / numberOfTiles); } else { tile = src->createThumbnailDevice(srcRect.width() / numberOfTiles, srcRect.height() / numberOfTiles); } if (tile.isNull()) return; KisPainter gc(dst); gc.setCompositeOp(COMPOSITE_COPY); if (progressUpdater) { progressUpdater->setRange(0, numberOfTiles); } if (srcInfo.selection()) { gc.setSelection(srcInfo.selection()); } for (uint y = 0; y < numberOfTiles; ++y) { for (uint x = 0; x < numberOfTiles; ++x) { gc.bitBlt(w * x, h * y, tile, 0, 0, w, h); } if (progressUpdater) progressUpdater->setValue(y); } gc.end(); }
void KisRainDropsFilter::process(KisConstProcessingInformation srcInfo, KisProcessingInformation dstInfo, const QSize& size, const KisFilterConfiguration* config, KoUpdater* progressUpdater ) const { const KisPaintDeviceSP src = srcInfo.paintDevice(); KisPaintDeviceSP dst = dstInfo.paintDevice(); QPoint dstTopLeft = dstInfo.topLeft(); QPoint srcTopLeft = srcInfo.topLeft(); Q_UNUSED(config); Q_ASSERT(!src.isNull()); Q_ASSERT(!dst.isNull()); //read the filter configuration values from the KisFilterConfiguration object quint32 DropSize = config->getInt("dropSize", 80); quint32 number = config->getInt("number", 80); quint32 fishEyes = config->getInt("fishEyes", 30); if (progressUpdater) { progressUpdater->setRange(0, size.width() * size.height()); } int count = 0; if (fishEyes <= 0) fishEyes = 1; if (fishEyes > 100) fishEyes = 100; int Width = size.width(); int Height = size.height(); bool** BoolMatrix = CreateBoolArray(Width, Height); int i, j, k, l, m, n; // loop variables int Bright; // Bright value for shadows and highlights int x, y; // center coordinates int Counter = 0; // Counter (duh !) int NewSize; // Size of current raindrop int halfSize; // Half of the current raindrop int Radius; // Maximum radius for raindrop int BlurRadius; // Blur Radius int BlurPixels; double r, a; // polar coordinates double OldRadius; // Radius before processing double NewfishEyes = (double)fishEyes * 0.01; // FishEye fishEyesicients double s; double R, G, B; bool FindAnother = false; // To search for good coordinates const KoColorSpace * cs = src->colorSpace(); // XXX: move the seed to the config, so the filter can be used as // and adjustment filter (boud). // And use a thread-safe random number generator QDateTime dt = QDateTime::currentDateTime(); QDateTime Y2000(QDate(2000, 1, 1), QTime(0, 0, 0)); srand((uint) dt.secsTo(Y2000)); // Init booleen Matrix. for (i = 0 ; (i < Width) && !(progressUpdater && progressUpdater->interrupted()) ; ++i) { for (j = 0 ; (j < Height) && !(progressUpdater && progressUpdater->interrupted()); ++j) { BoolMatrix[i][j] = false; } } KisRandomAccessorSP dstAccessor = dst->createRandomAccessorNG(dstTopLeft.x(), dstTopLeft.y()); KisRandomConstAccessorSP srcAccessor = src->createRandomConstAccessorNG(dstTopLeft.x(), dstTopLeft.y()); for (uint NumBlurs = 0; (NumBlurs <= number) && !(progressUpdater && progressUpdater->interrupted()); ++NumBlurs) { NewSize = (int)(rand() * ((double)(DropSize - 5) / RAND_MAX) + 5); halfSize = NewSize / 2; Radius = halfSize; s = Radius / log(NewfishEyes * Radius + 1); Counter = 0; do { FindAnother = false; y = (int)(rand() * ((double)(Width - 1) / RAND_MAX)); x = (int)(rand() * ((double)(Height - 1) / RAND_MAX)); if (BoolMatrix[y][x]) FindAnother = true; else for (i = x - halfSize ; (i <= x + halfSize) && !(progressUpdater && progressUpdater->interrupted()); i++) for (j = y - halfSize ; (j <= y + halfSize) && !(progressUpdater && progressUpdater->interrupted()); j++) if ((i >= 0) && (i < Height) && (j >= 0) && (j < Width)) if (BoolMatrix[j][i]) FindAnother = true; Counter++; } while ((FindAnother && (Counter < 10000) && !(progressUpdater && progressUpdater->interrupted()))); if (Counter >= 10000) { NumBlurs = number; break; } for (i = -1 * halfSize ; (i < NewSize - halfSize) && !(progressUpdater && progressUpdater->interrupted()); i++) { for (j = -1 * halfSize ; (j < NewSize - halfSize) && !(progressUpdater && progressUpdater->interrupted()); j++) { r = sqrt(i * i + j * j); a = atan2(static_cast<double>(i), static_cast<double>(j)); if (r <= Radius) { OldRadius = r; r = (exp(r / s) - 1) / NewfishEyes; k = x + (int)(r * sin(a)); l = y + (int)(r * cos(a)); m = x + i; n = y + j; if ((k >= 0) && (k < Height) && (l >= 0) && (l < Width)) { if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) { Bright = 0; if (OldRadius >= 0.9 * Radius) { if ((a <= 0) && (a > -2.25)) Bright = -80; else if ((a <= -2.25) && (a > -2.5)) Bright = -40; else if ((a <= 0.25) && (a > 0)) Bright = -40; } else if (OldRadius >= 0.8 * Radius) { if ((a <= -0.75) && (a > -1.50)) Bright = -40; else if ((a <= 0.10) && (a > -0.75)) Bright = -30; else if ((a <= -1.50) && (a > -2.35)) Bright = -30; } else if (OldRadius >= 0.7 * Radius) { if ((a <= -0.10) && (a > -2.0)) Bright = -20; else if ((a <= 2.50) && (a > 1.90)) Bright = 60; } else if (OldRadius >= 0.6 * Radius) { if ((a <= -0.50) && (a > -1.75)) Bright = -20; else if ((a <= 0) && (a > -0.25)) Bright = 20; else if ((a <= -2.0) && (a > -2.25)) Bright = 20; } else if (OldRadius >= 0.5 * Radius) { if ((a <= -0.25) && (a > -0.50)) Bright = 30; else if ((a <= -1.75) && (a > -2.0)) Bright = 30; } else if (OldRadius >= 0.4 * Radius) { if ((a <= -0.5) && (a > -1.75)) Bright = 40; } else if (OldRadius >= 0.3 * Radius) { if ((a <= 0) && (a > -2.25)) Bright = 30; } else if (OldRadius >= 0.2 * Radius) { if ((a <= -0.5) && (a > -1.75)) Bright = 20; } BoolMatrix[n][m] = true; QColor originalColor; srcAccessor->moveTo(srcTopLeft.x() + l, srcTopLeft.y() + k); cs->toQColor(srcAccessor->oldRawData(), &originalColor); int newRed = CLAMP(originalColor.red() + Bright, 0, quint8_MAX); int newGreen = CLAMP(originalColor.green() + Bright, 0, quint8_MAX); int newBlue = CLAMP(originalColor.blue() + Bright, 0, quint8_MAX); QColor newColor; newColor.setRgb(newRed, newGreen, newBlue); dstAccessor->moveTo(dstTopLeft.x() + n, dstTopLeft.y() + m); cs->fromQColor(newColor, dstAccessor->rawData()); } } } } } BlurRadius = NewSize / 25 + 1; for (i = -1 * halfSize - BlurRadius ; (i < NewSize - halfSize + BlurRadius) && !(progressUpdater && progressUpdater->interrupted()) ; i++) { for (j = -1 * halfSize - BlurRadius; ((j < NewSize - halfSize + BlurRadius) && !(progressUpdater && progressUpdater->interrupted())); ++j) { r = sqrt(i * i + j * j); if (r <= Radius * 1.1) { R = G = B = 0; BlurPixels = 0; for (k = -1 * BlurRadius; k < BlurRadius + 1; k++) for (l = -1 * BlurRadius; l < BlurRadius + 1; l++) { m = x + i + k; n = y + j + l; if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) { QColor color; dstAccessor->moveTo(dstTopLeft.x() + n, dstTopLeft.y() + m); cs->toQColor(dstAccessor->rawData(), &color); R += color.red(); G += color.green(); B += color.blue(); BlurPixels++; } } m = x + i; n = y + j; if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) { QColor color; color.setRgb((int)(R / BlurPixels), (int)(G / BlurPixels), (int)(B / BlurPixels)); dstAccessor->moveTo(dstTopLeft.x() + n, dstTopLeft.y() + m); cs->fromQColor(color, dstAccessor->rawData()); } } } } if (progressUpdater) progressUpdater->setValue(++count); } FreeBoolArray(BoolMatrix, Width); }
void KisWaveletNoiseReduction::process(KisConstProcessingInformation srcInfo, KisProcessingInformation dstInfo, const QSize& areaSize, const KisFilterConfiguration* config, KoUpdater* progressUpdater ) const { const KisPaintDeviceSP src = srcInfo.paintDevice(); KisPaintDeviceSP dst = dstInfo.paintDevice(); QPoint dstTopLeft = dstInfo.topLeft(); QPoint srcTopLeft = srcInfo.topLeft(); Q_ASSERT(!src.isNull()); Q_ASSERT(!dst.isNull()); // TODO take selections into account float threshold; if (!config) { config = defaultConfiguration(src); } threshold = config->getDouble("threshold", BEST_WAVELET_THRESHOLD_VALUE); qint32 depth = src->colorSpace()->colorChannelCount(); int size; int maxrectsize = qMax(areaSize.width(), areaSize.height()); for (size = 2; size < maxrectsize; size *= 2) ; KisMathToolbox* mathToolbox = KisMathToolboxRegistry::instance()->get(src->colorSpace()->mathToolboxId().id()); QRect srcRect(srcTopLeft, areaSize); if (progressUpdater) { progressUpdater->setRange(0, mathToolbox->fastWaveletTotalSteps(srcRect) * 2 + size*size*depth); } int count = 0; // connect(mathToolbox, SIGNAL(nextStep()), this, SLOT(incProgress())); // dbgFilters << size <<"" << maxrectsize <<"" << srcTopLeft.x() <<"" << srcTopLeft.y(); // dbgFilters <<"Transforming..."; // setProgressStage( i18n("Fast wavelet transformation") ,progress()); KisMathToolbox::KisWavelet* buff = 0; KisMathToolbox::KisWavelet* wav = 0; try { buff = mathToolbox->initWavelet(src, srcRect); } catch (std::bad_alloc) { if (buff) delete buff; return; } try { wav = mathToolbox->fastWaveletTransformation(src, srcRect, buff); } catch (std::bad_alloc) { if (wav) delete wav; return; } // dbgFilters <<"Thresholding..."; float* fin = wav->coeffs + wav->depth * wav->size * wav->size; for (float* it = wav->coeffs + wav->depth; it < fin; it++) { if (*it > threshold) { *it -= threshold; } else if (*it < -threshold) { *it += threshold; } else { *it = 0.; } if (progressUpdater) progressUpdater->setValue(++count); } // dbgFilters <<"Untransforming..."; mathToolbox->fastWaveletUntransformation(dst, QRect(dstTopLeft, areaSize), wav, buff); delete wav; delete buff; // disconnect(mathToolbox, SIGNAL(nextStep()), this, SLOT(incProgress())); }