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);

}
Exemple #2
0
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()));
}