void KisWaveletNoiseReduction::process(KisPaintDeviceSP device,
                                      const QRect& applyRect,
                                      const KisFilterConfiguration* config,
                                      KoUpdater* progressUpdater
                                      ) const
{
    Q_ASSERT(device);
    // TODO take selections into account
    float threshold;

    if (!config) {
        config = defaultConfiguration(device);
    }

    threshold = config->getDouble("threshold", BEST_WAVELET_THRESHOLD_VALUE);

    qint32 depth = device->colorSpace()->colorChannelCount();

    int size;
    int maxrectsize = qMax(applyRect.width(), applyRect.height());
    for (size = 2; size < maxrectsize; size *= 2) ;

    KisMathToolbox* mathToolbox = KisMathToolboxRegistry::instance()->get(device->colorSpace()->mathToolboxId().id());

    if (progressUpdater) {
        progressUpdater->setRange(0, mathToolbox->fastWaveletTotalSteps(applyRect) * 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(device, applyRect);
    } catch (std::bad_alloc) {
        if (buff) delete buff;
        return;
    }
    try {
        wav = mathToolbox->fastWaveletTransformation(device, applyRect, 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(device, applyRect, wav, buff);

    delete wav;
    delete buff;
//     disconnect(mathToolbox, SIGNAL(nextStep()), this, SLOT(incProgress()));
}