void DImageFilterActionTest::testActions()
{
    QStringList files = QDir(imagePath()).entryList(QDir::Files);
    files.removeOne(originalImage());

    DImg original(imagePath() + originalImage());
    QVERIFY(!original.isNull());

    foreach (const QString& fileName, files)
    {
        DImg ref(imagePath() + fileName);
        QVERIFY(!ref.isNull());
        DImageHistory history = ref.getImageHistory();

        FilterActionFilter filter;
        filter.setFilterActions(history.allActions());
        QVERIFY(filter.isReproducible() || filter.isComplexAction());

        filter.setupFilter(original.copy());
        filter.startFilterDirectly();
        qDebug() << filter.filterActions().size();

        DImg img = filter.getTargetImage();

        QVERIFY(ref.size() == img.size());

        bool isEqual = true;
        DImg diff(ref.width(), ref.height(), ref.sixteenBit());
        diff.fill(DColor(Qt::black));

        for (uint x=0; x<ref.width(); x++)
        {
            for (uint y=0; y<ref.height(); y++)
            {
                DColor cref = ref.getPixelColor(x,y);
                DColor cres = img.getPixelColor(x,y);

                if (cref.red() != cres.red() || cref.green() != cres.green() || cref.blue() != cres.blue())
                {
                    //qDebug() << x << y;
                    diff.setPixelColor(x,y, DColor(Qt::white));
                    isEqual = false;
                }
            }
        }

        if (!isEqual)
        {
            showDiff(original, ref, img, diff);
        }

        QVERIFY(isEqual);
    }
Example #2
0
void EditorTool::slotUpdateSpotInfo(const DColor& col, const QPoint& point)
{
    DColor color = col;
    setToolInfoMessage(i18n("(%1,%2) RGBA:%3,%4,%5,%6",
                            point.x(), point.y(),
                            color.red(), color.green(),
                            color.blue(), color.alpha()));
}
Example #3
0
void SharpenFilter::convolveImageMultithreaded(const Args& prm)
{
    double  maxClamp = m_destImage.sixteenBit() ? 16777215.0 : 65535.0;
    double* k        = 0;
    double  red, green, blue, alpha;
    int     mx, my, sx, sy, mcx, mcy;
    DColor  color;

    for (uint x = prm.start ; runningFlag() && (x < prm.stop) ; ++x)
    {
        k   = prm.normal_kernel;
        red = green = blue = alpha = 0;
        sy  = prm.y - prm.halfKernelWidth;

        for (mcy = 0 ; runningFlag() && (mcy < prm.kernelWidth) ; ++mcy, ++sy)
        {
            my = sy < 0 ? 0 : sy > (int)m_destImage.height() - 1 ? m_destImage.height() - 1 : sy;
            sx = x + (-prm.halfKernelWidth);

            for (mcx = 0 ; runningFlag() && (mcx < prm.kernelWidth) ; ++mcx, ++sx)
            {
                mx     = sx < 0 ? 0 : sx > (int)m_destImage.width() - 1 ? m_destImage.width() - 1 : sx;
                color  = m_orgImage.getPixelColor(mx, my);
                red   += (*k) * (color.red()   * 257.0);
                green += (*k) * (color.green() * 257.0);
                blue  += (*k) * (color.blue()  * 257.0);
                alpha += (*k) * (color.alpha() * 257.0);
                ++k;
            }
        }

        red   =   red < 0.0 ? 0.0 :   red > maxClamp ? maxClamp :   red + 0.5;
        green = green < 0.0 ? 0.0 : green > maxClamp ? maxClamp : green + 0.5;
        blue  =  blue < 0.0 ? 0.0 :  blue > maxClamp ? maxClamp :  blue + 0.5;
        alpha = alpha < 0.0 ? 0.0 : alpha > maxClamp ? maxClamp : alpha + 0.5;

        m_destImage.setPixelColor(x, prm.y, DColor((int)(red  / 257UL), (int)(green / 257UL),
                                                   (int)(blue / 257UL), (int)(alpha / 257UL),
                                                   m_destImage.sixteenBit()));
    }
}
Example #4
0
void HSLFilter::applyHSL(DImg& image)
{
    if (image.isNull())
    {
        return;
    }

    bool   sixteenBit     = image.sixteenBit();
    uint   numberOfPixels = image.numPixels();
    int    progress;
    int    hue, sat, lig;
    double vib = d->settings.vibrance;
    DColor color;

    if (sixteenBit)                   // 16 bits image.
    {
        unsigned short* data = (unsigned short*) image.bits();

        for (uint i=0; runningFlag() && (i<numberOfPixels); ++i)
        {
            color = DColor(data[2], data[1], data[0], 0, sixteenBit);

            // convert RGB to HSL
            color.getHSL(&hue, &sat, &lig);

            // convert HSL to RGB
            color.setHSL(d->htransfer16[hue], vibranceBias(d->stransfer16[sat], hue, vib, sixteenBit), d->ltransfer16[lig], sixteenBit);

            data[2] = color.red();
            data[1] = color.green();
            data[0] = color.blue();

            data += 4;

            progress = (int)(((double)i * 100.0) / numberOfPixels);

            if ( progress%5 == 0 )
            {
                postProgress( progress );
            }
        }
    }
    else                                      // 8 bits image.
    {
        uchar* data = image.bits();

        for (uint i=0; runningFlag() && (i<numberOfPixels); ++i)
        {
            color = DColor(data[2], data[1], data[0], 0, sixteenBit);

            // convert RGB to HSL
            color.getHSL(&hue, &sat, &lig);

            // convert HSL to RGB
            color.setHSL(d->htransfer[hue], vibranceBias(d->stransfer[sat],hue,vib,sixteenBit), d->ltransfer[lig], sixteenBit);

            data[2] = color.red();
            data[1] = color.green();
            data[0] = color.blue();

            data += 4;

            progress = (int)(((double)i * 100.0) / numberOfPixels);

            if ( progress%5 == 0 )
            {
                postProgress( progress );
            }
        }
    }
}
Example #5
0
void CurvesSettings::slotSpotColorChanged(const DColor& color)
{
    DColor sc = color;

    switch (d->curvesBox->picker())
    {
        case CurvesBox::BlackTonal:
        {
            // Black tonal curves point.
            d->curvesBox->curves()->setCurvePoint(LuminosityChannel, 1,
                                                  QPoint(qMax(qMax(sc.red(), sc.green()), sc.blue()), 42 * d->histoSegments / 256));
            d->curvesBox->curves()->setCurvePoint(RedChannel, 1, QPoint(sc.red(), 42 * d->histoSegments / 256));
            d->curvesBox->curves()->setCurvePoint(GreenChannel, 1, QPoint(sc.green(), 42 * d->histoSegments / 256));
            d->curvesBox->curves()->setCurvePoint(BlueChannel, 1, QPoint(sc.blue(), 42 * d->histoSegments / 256));
            d->curvesBox->resetPickers();
            break;
        }

        case CurvesBox::GrayTonal:
        {
            // Gray tonal curves point.
            d->curvesBox->curves()->setCurvePoint(LuminosityChannel, 8,
                                                  QPoint(qMax(qMax(sc.red(), sc.green()), sc.blue()), 128 * d->histoSegments / 256));
            d->curvesBox->curves()->setCurvePoint(RedChannel, 8, QPoint(sc.red(), 128 * d->histoSegments / 256));
            d->curvesBox->curves()->setCurvePoint(GreenChannel, 8, QPoint(sc.green(), 128 * d->histoSegments / 256));
            d->curvesBox->curves()->setCurvePoint(BlueChannel, 8, QPoint(sc.blue(), 128 * d->histoSegments / 256));
            d->curvesBox->resetPickers();
            break;
        }

        case CurvesBox::WhiteTonal:
        {
            // White tonal curves point.
            d->curvesBox->curves()->setCurvePoint(LuminosityChannel, 15,
                                                  QPoint(qMax(qMax(sc.red(), sc.green()), sc.blue()), 213 * d->histoSegments / 256));
            d->curvesBox->curves()->setCurvePoint(RedChannel, 15, QPoint(sc.red(), 213 * d->histoSegments / 256));
            d->curvesBox->curves()->setCurvePoint(GreenChannel, 15, QPoint(sc.green(), 213 * d->histoSegments / 256));
            d->curvesBox->curves()->setCurvePoint(BlueChannel, 15, QPoint(sc.blue(), 213 * d->histoSegments / 256));
            d->curvesBox->resetPickers();
            break;
        }

        default:
        {
            d->curvesBox->setCurveGuide(color);
            return;
        }
    }

    // Calculate Red, green, blue curves.

    for (int i = LuminosityChannel ; i <= BlueChannel ; ++i)
    {
        d->curvesBox->curves()->curvesCalculateCurve(i);
    }

    d->curvesBox->repaint();
    d->curvesBox->resetPickers();

    emit signalSpotColorChanged();
}
Example #6
0
void NRFilter::filterImage()
{
    DColor col;
    int    progress;

    int width  = m_orgImage.width();
    int height = m_orgImage.height();
    float clip = m_orgImage.sixteenBit() ? 65535.0 : 255.0;

    // Allocate buffers.

    for (int c = 0; c < 3; ++c)
    {
        d->fimg[c] = new float[width * height];
    }

    d->buffer[1] = new float[width * height];
    d->buffer[2] = new float[width * height];

    // Read the full image and convert pixel values to float [0,1].

    int j = 0;

    for (int y = 0; runningFlag() && (y < height); ++y)
    {
        for (int x = 0; runningFlag() && (x < width); ++x)
        {
            col           = m_orgImage.getPixelColor(x, y);
            d->fimg[0][j] = col.red()   / clip;
            d->fimg[1][j] = col.green() / clip;
            d->fimg[2][j] = col.blue()  / clip;
            ++j;
        }
    }

    postProgress(10);

    // do colour model conversion sRGB[0,1] -> YCrCb.

    if (runningFlag())
    {
        srgb2ycbcr(d->fimg, width * height);
    }

    postProgress(20);

    // denoise the channels individually

    for (int c = 0; runningFlag() && (c < 3); ++c)
    {
        d->buffer[0] = d->fimg[c];

        if (d->settings.thresholds[c] > 0.0)
        {
            waveletDenoise(d->buffer, width, height, d->settings.thresholds[c], d->settings.softness[c]);

            progress = (int)(30.0 + ((double)c * 60.0) / 4);

            if (progress % 5 == 0)
            {
                postProgress(progress);
            }
        }
    }

    // Retransform the image data to sRGB[0,1].

    if (runningFlag())
    {
        ycbcr2srgb(d->fimg, width * height);
    }

    postProgress(80);

    // clip the values

    for (int c = 0; runningFlag() && (c < 3); ++c)
    {
        for (int i = 0; i < width * height; ++i)
        {
            d->fimg[c][i] = qBound(0.0F, d->fimg[c][i] * clip, clip);
        }
    }

    postProgress(90);

    // Write back the full image and convert pixel values from float [0,1].

    j = 0;

    for (int y = 0; runningFlag() && (y < height); ++y)
    {
        for (int x = 0; x < width; ++x)
        {
            col.setRed((int)(d->fimg[0][j] + 0.5));
            col.setGreen((int)(d->fimg[1][j] + 0.5));
            col.setBlue((int)(d->fimg[2][j] + 0.5));
            col.setAlpha(m_orgImage.getPixelColor(x, y).alpha());
            ++j;

            m_destImage.setPixelColor(x, y, col);
        }
    }

    postProgress(100);

    // Free buffers.

    for (int c = 0; c < 3; ++c)
    {
        delete [] d->fimg[c];
    }

    delete [] d->buffer[1];
    delete [] d->buffer[2];
}