Ejemplo n.º 1
0
void KisPixelSelection::subtractSelection(KisPixelSelectionSP selection)
{
    QRect r = selection->selectedRect();
    KisHLineIteratorPixel dst = createHLineIterator(r.x(), r.y(), r.width());
    KisHLineConstIteratorPixel src = selection->createHLineConstIterator(r.x(), r.y(), r.width());
    for (int i = 0; i < r.height(); ++i) {
        while (!src.isDone()) {
            if (*dst.rawData() - *src.rawData() > MIN_SELECTED)
                *dst.rawData() = *dst.rawData() - *src.rawData();
            else
                *dst.rawData() = MIN_SELECTED;
            ++src;
            ++dst;
        }
        dst.nextRow();
        src.nextRow();
    }

}
Ejemplo n.º 2
0
void KisTotalRandomColorSource::colorize(KisPaintDeviceSP dev, const QRect& rect)
{
    KoColor kc(dev->colorSpace());

    QColor qc;

    int pixelSize = dev->colorSpace()->pixelSize();

    KisHLineIteratorPixel it = dev->createHLineIterator(rect.x(), rect.y(), rect.width(), 0);
    for (int y = 0; y < rect.height(); y++) {
        while (!it.isDone()) {
            qc.setRgb((int)((255.0*rand()) / RAND_MAX), (int)((255.0*rand()) / RAND_MAX), (int)((255.0*rand()) / RAND_MAX));
            kc.fromQColor(qc);
            memcpy(it.rawData(), kc.data(), pixelSize);
            ++it;
        }
        it.nextRow();
    }

}
Ejemplo n.º 3
0
void KisCurveMagnetic::toGrayScale(const QRect& rect, KisPaintDeviceSP src, GrayMatrix& dst)
{
    int grectx = rect.x();
    int grecty = rect.y();
    int grectw = rect.width();
    int grecth = rect.height();
    QColor c;
    KoColorSpace *cs = src->colorSpace();

    KisHLineIteratorPixel srcIt = src->createHLineIterator(grectx, grecty, grectw);

    for (int row = 0; row < grecth; row++) {
        for (int col = 0; col < grectw; col++) {
            cs->toQColor(srcIt.rawData(), &c);
            dst[col][row] = qGray(c.rgb());
            ++srcIt;
        }
        srcIt.nextRow();
    }
}
Ejemplo n.º 4
0
QRect KisImagePyramid::downsampleByFactor2(const QRect& srcRect,
        KisPaintDevice* src,
        KisPaintDevice* dst)
{
    qint32 srcX, srcY, srcWidth, srcHeight;
    srcRect.getRect(&srcX, &srcY, &srcWidth, &srcHeight);
    alignRectBy2(srcX, srcY, srcWidth, srcHeight);

    qint32 dstX = srcX / 2;
    qint32 dstY = srcY / 2;
    qint32 dstWidth = srcWidth / 2;
    qint32 dstHeight = srcHeight / 2;

    KisHLineConstIteratorPixel srcIt0 = src->createHLineConstIterator(srcX, srcY, srcWidth);
    KisHLineConstIteratorPixel srcIt1 = src->createHLineConstIterator(srcX, srcY + 1, srcWidth);
    KisHLineIteratorPixel dstIt = dst->createHLineIterator(dstX, dstY, dstWidth);

    for (int row = 0; row < dstHeight; ++row) {
        while (!dstIt.isDone()) {
            int srcItConseq = srcIt0.nConseqHPixels();
            int dstItConseq = dstIt.nConseqHPixels();
            int conseqPixels = qMin(srcItConseq, dstItConseq * 2);

            Q_ASSERT(!isOdd(conseqPixels));

            downsamplePixels(srcIt0.rawData(), srcIt1.rawData(),
                             dstIt.rawData(), conseqPixels);

            srcIt0 += conseqPixels;
            srcIt1 += conseqPixels;
            dstIt += conseqPixels / 2;
        }
        srcIt0.nextRow();
        srcIt0.nextRow();
        srcIt1.nextRow();
        srcIt1.nextRow();
        dstIt.nextRow();
    }
    return QRect(dstX, dstY, dstWidth, dstHeight);
}
Ejemplo n.º 5
0
void KisFilterOp::paintAt(const KisPaintInformation& info)
{
    if (!painter()) {
        return;
    }

    KisFilterSP filter = settings->filter();
    if (!filter) {
        return;
    }

    if (!source()) {
        return;
    }

    KisBrushSP brush = m_brush;;
    if (!brush) return;

    KisPaintInformation adjustedInfo = settings->m_optionsWidget->m_sizeOption->apply(info);
    if (! brush->canPaintFor(adjustedInfo))
        return;

    double pScale = KisPaintOp::scaleForPressure(adjustedInfo.pressure());   // TODO: why is there scale and pScale that seems to contains the same things ?
    QPointF hotSpot = brush->hotSpot(pScale, pScale);
    QPointF pt = info.pos() - hotSpot;


    // Split the coordinates into integer plus fractional parts. The integer
    // is where the dab will be positioned and the fractional part determines
    // the sub-pixel positioning.
    qint32 x;
    double xFraction;
    qint32 y;
    double yFraction;

    splitCoordinate(pt.x(), &x, &xFraction);
    splitCoordinate(pt.y(), &y, &yFraction);

    double scale = KisPaintOp::scaleForPressure(adjustedInfo.pressure());

    qint32 maskWidth = brush->maskWidth(scale, 0.0);
    qint32 maskHeight = brush->maskHeight(scale, 0.0);

    // Filter the paint device
    filter->process(KisConstProcessingInformation(source(), QPoint(x, y)),
                    KisProcessingInformation(m_tmpDevice, QPoint(0, 0)),
                    QSize(maskWidth, maskHeight),
                    settings->filterConfig(), 0);

    // Apply the mask on the paint device (filter before mask because edge pixels may be important)

    KisFixedPaintDeviceSP fixedDab = new KisFixedPaintDevice(m_tmpDevice->colorSpace());
    fixedDab->setRect(m_tmpDevice->extent());
    fixedDab->initialize();

    m_tmpDevice->readBytes(fixedDab->data(), fixedDab->bounds());
    brush->mask(fixedDab, scale, scale, 0.0, info, xFraction, yFraction);
    m_tmpDevice->writeBytes(fixedDab->data(), fixedDab->bounds());

    if (!settings->ignoreAlpha()) {
        KisHLineIteratorPixel itTmpDev = m_tmpDevice->createHLineIterator(0, 0, maskWidth);
        KisHLineIteratorPixel itSrc = source()->createHLineIterator(x, y, maskWidth);
        const KoColorSpace* cs = m_tmpDevice->colorSpace();
        for (int y = 0; y < maskHeight; ++y) {
            while (!itTmpDev.isDone()) {
                quint8 alphaTmpDev = cs->alpha(itTmpDev.rawData());
                quint8 alphaSrc = cs->alpha(itSrc.rawData());

                cs->setAlpha(itTmpDev.rawData(), qMin(alphaTmpDev, alphaSrc), 1);
                ++itTmpDev;
                ++itSrc;
            }
            itTmpDev.nextRow();
            itSrc.nextRow();
        }
    }

    // Blit the paint device onto the layer
    QRect dabRect = QRect(0, 0, maskWidth, maskHeight);
    QRect dstRect = QRect(x, y, dabRect.width(), dabRect.height());

    if (painter()->bounds().isValid()) {
        dstRect &= painter()->bounds();
    }
    if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;

    qint32 sx = dstRect.x() - x;
    qint32 sy = dstRect.y() - y;
    qint32 sw = dstRect.width();
    qint32 sh = dstRect.height();

    painter()->bitBlt(dstRect.x(), dstRect.y(), m_tmpDevice, sx, sy, sw, sh);

}
Ejemplo n.º 6
0
void KisDuplicateOp::paintAt(const KisPaintInformation& info)
{
    if (!painter()) return;

    if (!m_duplicateStartIsSet) {
        m_duplicateStartIsSet = true;
        m_duplicateStart = info.pos();
    }

    bool heal = settings->healing();

    if (!source()) return;

    KisBrushSP brush = m_brush;
    if (!brush) return;
    if (! brush->canPaintFor(info))
        return;

    double scale = KisPaintOp::scaleForPressure(info.pressure());
    QPointF hotSpot = brush->hotSpot(scale, scale);
    QPointF pt = info.pos() - hotSpot;

    // Split the coordinates into integer plus fractional parts. The integer
    // is where the dab will be positioned and the fractional part determines
    // the sub-pixel positioning.
    qint32 x;
    double xFraction;
    qint32 y;
    double yFraction;

    splitCoordinate(pt.x(), &x, &xFraction);
    splitCoordinate(pt.y(), &y, &yFraction);
    xFraction = yFraction = 0.0;

    QPointF srcPointF = pt - settings->offset();
    QPoint srcPoint = QPoint(x - static_cast<qint32>(settings->offset().x()),
                             y - static_cast<qint32>(settings->offset().y()));


    qint32 sw = brush->maskWidth(scale, 0.0);
    qint32 sh = brush->maskHeight(scale, 0.0);

    if (srcPoint.x() < 0)
        srcPoint.setX(0);

    if (srcPoint.y() < 0)
        srcPoint.setY(0);
    if (!(m_srcdev && !(*m_srcdev->colorSpace() == *source()->colorSpace()))) {
        m_srcdev = new KisPaintDevice(source()->colorSpace());
    }
    Q_CHECK_PTR(m_srcdev);

    // Perspective correction ?
    KisPainter copyPainter(m_srcdev);
    KisImageSP image = settings->m_image;
    if (settings->perspectiveCorrection() && image && image->perspectiveGrid()->countSubGrids() == 1) {
        Matrix3qreal startM = Matrix3qreal::Identity();
        Matrix3qreal endM = Matrix3qreal::Identity();

        // First look for the grid corresponding to the start point
        KisSubPerspectiveGrid* subGridStart = *image->perspectiveGrid()->begin();
        QRect r = QRect(0, 0, image->width(), image->height());

#if 1
        if (subGridStart) {
            startM = KisPerspectiveMath::computeMatrixTransfoFromPerspective(r, *subGridStart->topLeft(), *subGridStart->topRight(), *subGridStart->bottomLeft(), *subGridStart->bottomRight());
        }
#endif
#if 1
        // Second look for the grid corresponding to the end point
        KisSubPerspectiveGrid* subGridEnd = *image->perspectiveGrid()->begin();
        if (subGridEnd) {
            endM = KisPerspectiveMath::computeMatrixTransfoToPerspective(*subGridEnd->topLeft(), *subGridEnd->topRight(), *subGridEnd->bottomLeft(), *subGridEnd->bottomRight(), r);
        }
#endif

        // Compute the translation in the perspective transformation space:
        QPointF positionStartPaintingT = KisPerspectiveMath::matProd(endM, QPointF(m_duplicateStart));
        QPointF duplicateStartPositionT = KisPerspectiveMath::matProd(endM, QPointF(m_duplicateStart) - QPointF(settings->offset()));
        QPointF translat = duplicateStartPositionT - positionStartPaintingT;
        KisRectIteratorPixel dstIt = m_srcdev->createRectIterator(0, 0, sw, sh);
        KisRandomSubAccessorPixel srcAcc = source()->createRandomSubAccessor();
        //Action
        while (!dstIt.isDone()) {
            if (dstIt.isSelected()) {
                QPointF p =  KisPerspectiveMath::matProd(startM, KisPerspectiveMath::matProd(endM, QPointF(dstIt.x() + x, dstIt.y() + y)) + translat);
                srcAcc.moveTo(p);
                srcAcc.sampledOldRawData(dstIt.rawData());
            }
            ++dstIt;
        }


    } else {
        // Or, copy the source data on the temporary device:
        copyPainter.setCompositeOp(COMPOSITE_COPY);
        copyPainter.bitBlt(0, 0, source(), srcPoint.x(), srcPoint.y(), sw, sh);
        copyPainter.end();
    }

    // heal ?

    if (heal) {
        quint16 dataDevice[4];
        quint16 dataSrcDev[4];
        double* matrix = new double[ 3 * sw * sh ];
        // First divide
        const KoColorSpace* deviceCs = source()->colorSpace();
        KisHLineConstIteratorPixel deviceIt = source()->createHLineConstIterator(x, y, sw);
        KisHLineIteratorPixel srcDevIt = m_srcdev->createHLineIterator(0, 0, sw);
        double* matrixIt = &matrix[0];
        for (int j = 0; j < sh; j++) {
            for (int i = 0; !srcDevIt.isDone(); i++) {
                deviceCs->toLabA16(deviceIt.rawData(), (quint8*)dataDevice, 1);
                deviceCs->toLabA16(srcDevIt.rawData(), (quint8*)dataSrcDev, 1);
                // Division
                for (int k = 0; k < 3; k++) {
                    matrixIt[k] = dataDevice[k] / (double)qMax((int)dataSrcDev [k], 1);
                }
                ++deviceIt;
                ++srcDevIt;
                matrixIt += 3;
            }
            deviceIt.nextRow();
            srcDevIt.nextRow();
        }
        // Minimize energy
        {
            int iter = 0;
            double err;
            double* solution = new double [ 3 * sw * sh ];
            do {
                err = minimizeEnergy(&matrix[0], &solution[0], sw, sh);
                memcpy(&matrix[0], &solution[0], sw * sh * 3 * sizeof(double));
                iter++;
            } while (err < 0.00001 && iter < 100);
            delete [] solution;
        }

        // Finaly multiply
        deviceIt = source()->createHLineIterator(x, y, sw);
        srcDevIt = m_srcdev->createHLineIterator(0, 0, sw);
        matrixIt = &matrix[0];
        for (int j = 0; j < sh; j++) {
            for (int i = 0; !srcDevIt.isDone(); i++) {
                deviceCs->toLabA16(deviceIt.rawData(), (quint8*)dataDevice, 1);
                deviceCs->toLabA16(srcDevIt.rawData(), (quint8*)dataSrcDev, 1);
                // Multiplication
                for (int k = 0; k < 3; k++) {
                    dataSrcDev[k] = (int)CLAMP(matrixIt[k] * qMax((int) dataSrcDev[k], 1), 0, 65535);
                }
                deviceCs->fromLabA16((quint8*)dataSrcDev, srcDevIt.rawData(), 1);
                ++deviceIt;
                ++srcDevIt;
                matrixIt += 3;
            }
            deviceIt.nextRow();
            srcDevIt.nextRow();
        }
        delete [] matrix;
    }

    KisFixedPaintDeviceSP fixedDab = new KisFixedPaintDevice(m_srcdev->colorSpace());
    fixedDab->setRect(QRect(0, 0, sw, sh));
    fixedDab->initialize();

    m_srcdev->readBytes(fixedDab->data(), fixedDab->bounds());
    brush->mask(fixedDab, scale, scale, 0.0, info, xFraction, yFraction);
    m_srcdev->writeBytes(fixedDab->data(), fixedDab->bounds());

    QRect dabRect = QRect(0, 0, brush->maskWidth(scale, 0.0), brush->maskHeight(scale, 0.0));
    QRect dstRect = QRect(x, y, dabRect.width(), dabRect.height());

    if (painter()->bounds().isValid()) {
        dstRect &= painter()->bounds();
    }

    if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;

    qint32 sx = dstRect.x() - x;
    qint32 sy = dstRect.y() - y;
    sw = dstRect.width();
    sh = dstRect.height();

    painter()->bitBlt(dstRect.x(), dstRect.y(), m_srcdev, sx, sy, sw, sh);


}
Ejemplo n.º 7
0
lInterestPoints HarrisPointDetector::computeInterestPoints(KisPaintDeviceSP device, const QRect& rect)
// lHarrisPoints computeHarrisPoints(KisPaintDeviceSP device, QRect rect)
{
    dbgPlugins << "Compute Harris points on the rect :" << rect;
    Q_ASSERT(device->colorSpace()->id() == "GRAYA");
    lInterestPoints points;

    // Compute the derivatives
    KisEightFloatColorSpace* floatCs = new KisEightFloatColorSpace();
    KisPaintDeviceSP infoDevice = new KisPaintDevice(floatCs, "infoDevice");

    float g_var = DERIVATION_SIGMA * DERIVATION_SIGMA ;
    float sqrt2pi = sqrt(2 * M_PI);
    float beta0 = 1 / (sqrt2pi * DERIVATION_SIGMA);

    float beta1 = beta0 * exp(-1 / (2 * g_var));
    float beta2 = beta0 * exp(-4 / (2 * g_var));

    float alpha1 = beta1 / g_var;
    float alpha2 = 2 * beta2 / g_var;



    {
        KisHLineConstIteratorPixel hitDevice = device->createHLineConstIterator(rect.left(), rect.top() + 2, rect.width() - 4);
        KisHLineIteratorPixel hitinfoDevice = infoDevice-> createHLineIterator(rect.left() + 2, 2, rect.width());

        quint8 pixelvalue[5];

        dbgPlugins << " Compute the derivatives";
        dbgPlugins << "  horizontal derivatives";
        /* Horizontal computation of derivatives */
        for (int y = rect.top() + 2; y < rect.bottom() - 2; y++) {
            pixelvalue[LEFTLEFT] = *hitDevice.rawData();
            ++hitDevice;
            pixelvalue[LEFT] = *hitDevice.rawData();
            ++hitDevice;
            pixelvalue[CENTER] = *hitDevice.rawData();
            ++hitDevice;
            pixelvalue[RIGHT] = *hitDevice.rawData();
            ++hitDevice;
            while (!hitDevice.isDone()) {
                pixelvalue[RIGHTRIGHT] = *hitDevice.rawData();
                float* infoValues = reinterpret_cast<float*>(hitinfoDevice.rawData());
                infoValues[INFO_HDIFF] = alpha1 * (pixelvalue[LEFT] - pixelvalue[RIGHT]) + alpha2 * (pixelvalue[LEFTLEFT] - pixelvalue[RIGHTRIGHT]);
                infoValues[INFO_HADD] = beta0 * (pixelvalue[CENTER]) + beta1 * (pixelvalue[LEFT] + pixelvalue[RIGHT]) + beta2 * (pixelvalue[LEFTLEFT] + pixelvalue[RIGHTRIGHT]);
                infoValues[INFO_INTENSITY] = pixelvalue[CENTER];
//                     dbgPlugins << hitDevice.x() <<"" << hitDevice.y() <<"" << infoValues[INFO_HDIFF] <<"" << infoValues[INFO_HADD] <<"" << (int)pixelvalue[CENTER] <<"" << infoValues[INFO_INTENSITY];
                memmove(pixelvalue, pixelvalue + 1, 4*sizeof(quint8));
                ++hitDevice;
                ++hitinfoDevice;
            }
            hitDevice.nextRow();
            hitinfoDevice.nextRow();
        }
    }

    KisTransaction a("", infoDevice);
    {
        KisVLineConstIteratorPixel vitinfoDeviceRead = infoDevice-> createVLineConstIterator(rect.left() + 4, rect.top(), rect.height());
        KisVLineIteratorPixel vitinfoDevice = infoDevice-> createVLineIterator(rect.left() + 4, rect.top() + 2, rect.height() - 2);

        float hdiffValue[5];
        float haddValue[5];
        dbgPlugins << "  vertical derivatives";
        /* Vertical computation of derivatives */
        for (int x = rect.left() + 4; x < rect.right() - 4; x++) {
            const float* infoValue = reinterpret_cast<const float*>(vitinfoDeviceRead.oldRawData());
            hdiffValue[TOPTOP] = infoValue[INFO_HDIFF];
            haddValue[TOPTOP] = infoValue[INFO_HADD];
            ++vitinfoDeviceRead;
            infoValue = reinterpret_cast<const float*>(vitinfoDeviceRead.oldRawData());
            hdiffValue[TOP] = infoValue[INFO_HDIFF];
            haddValue[TOP] = infoValue[INFO_HADD];
            ++vitinfoDeviceRead;
            infoValue = reinterpret_cast<const float*>(vitinfoDeviceRead.oldRawData());
            hdiffValue[CENTER] = infoValue[INFO_HDIFF];
            haddValue[CENTER] = infoValue[INFO_HADD];
            ++vitinfoDeviceRead;
            infoValue = reinterpret_cast<const float*>(vitinfoDeviceRead.oldRawData());
            hdiffValue[RIGHT] = infoValue[INFO_HDIFF];
            haddValue[RIGHT] = infoValue[INFO_HADD];
            ++vitinfoDeviceRead;

            while (!vitinfoDevice.isDone()) {
                infoValue = reinterpret_cast<const float*>(vitinfoDeviceRead.oldRawData());
                hdiffValue[RIGHTRIGHT] = infoValue[INFO_HDIFF];
                haddValue[RIGHTRIGHT] = infoValue[INFO_HADD];

                float c_grdy = beta0 * hdiffValue[ CENTER ] + beta1 * (hdiffValue[ TOP ] + hdiffValue[ BOTTOM ]) + beta2 * (hdiffValue[ TOPTOP ] + hdiffValue[ BOTTOMBOTTOM ]);
                float c_grdx = alpha1 * (haddValue[ TOP ] - haddValue[ BOTTOM ]) + alpha2 * (haddValue[ TOPTOP ] - haddValue[ BOTTOMBOTTOM ]);

                float* infoValueDst = reinterpret_cast<float*>(vitinfoDevice.rawData());
                infoValueDst[ INFO_XX ] = c_grdx * c_grdx;
                infoValueDst[ INFO_YY ] = c_grdy * c_grdy;
                infoValueDst[ INFO_X ] = c_grdx;
                infoValueDst[ INFO_Y ] = c_grdy;
                infoValueDst[ INFO_XY ] = c_grdx * c_grdy;

                memmove(hdiffValue, hdiffValue + 1, 4 * sizeof(float));
                memmove(haddValue , haddValue + 1 , 4 * sizeof(float));
                ++vitinfoDeviceRead;
                ++vitinfoDevice;
            }
            vitinfoDeviceRead.nextCol();
            vitinfoDevice.nextCol();
        }
    }

    // Apply a blur

    // Apply a blur
    KisTransaction("", infoDevice);

#if 1
    {
        KisHLineConstIteratorPixel hitDevice = infoDevice->createHLineConstIterator(rect.left(), rect.top() + 2, rect.width() - 4);
        KisHLineIteratorPixel hitinfoDevice = infoDevice-> createHLineIterator(rect.left() + 2, rect.top() + 2, rect.width() - 4);

        float pixelvalue[6][6];

        dbgPlugins << " Compute the blur";
        dbgPlugins << "  horizontal blur";
        /* Horizontal computation of derivatives */
        for (int y = rect.top() + 2; y < rect.bottom() - 2; y++) {
            memcpy(pixelvalue[LEFTLEFT], hitDevice.rawData(), 6*sizeof(float));
            ++hitDevice;
            memcpy(pixelvalue[LEFT], hitDevice.rawData(), 6*sizeof(float));
            ++hitDevice;
            memcpy(pixelvalue[CENTER], hitDevice.rawData(), 6*sizeof(float));
            ++hitDevice;
            memcpy(pixelvalue[RIGHT], hitDevice.rawData(), 6*sizeof(float));
            ++hitDevice;
            while (!hitDevice.isDone()) {
                memcpy(pixelvalue[RIGHTRIGHT], hitDevice.rawData(), 6*sizeof(float));
                float* infoValues = reinterpret_cast<float*>(hitinfoDevice.rawData());
                for (int i = 0; i < 5; i++) {
                    infoValues[i] = beta0 *  pixelvalue[CENTER][i] + beta1 * (pixelvalue[LEFT][i] + pixelvalue[RIGHT][i]) + beta2 * (pixelvalue[LEFTLEFT][i] + pixelvalue[RIGHTRIGHT][i]);
//                   infoValues[i] =2 *  pixelvalue[CENTER][i] + ( pixelvalue[LEFT][i] + pixelvalue[RIGHT][i] );
                }
//                 memmove(pixelvalue, pixelvalue + 1, 4*sizeof(float[6]));
                for (int i = 0; i < 5; i++) {
                    memcpy(pixelvalue[i], pixelvalue[i+1], 6*sizeof(float));
                }
                ++hitDevice;
                ++hitinfoDevice;
            }
            hitDevice.nextRow();
            hitinfoDevice.nextRow();
        }
    }
    KisTransaction b("", infoDevice);
    {
        KisVLineConstIteratorPixel vitinfoDeviceRead = infoDevice-> createVLineConstIterator(rect.left() + 4, rect.top(), rect.height());
        KisVLineIteratorPixel vitinfoDevice = infoDevice-> createVLineIterator(rect.left() + 4, rect.top() + 2, rect.height() - 4);

        float infoValue[6][6];
        dbgPlugins << "  vertical blur";
        /* Vertical computation of derivatives */
        for (int x = rect.left() + 4; x < rect.right() - 4; x++) {
            memcpy(infoValue[TOPTOP], vitinfoDeviceRead.oldRawData(), 6*sizeof(float));
            ++vitinfoDeviceRead;
            memcpy(infoValue[TOP], vitinfoDeviceRead.oldRawData(), 6*sizeof(float));
            ++vitinfoDeviceRead;
            memcpy(infoValue[CENTER], vitinfoDeviceRead.oldRawData(), 6*sizeof(float));
            ++vitinfoDeviceRead;
            memcpy(infoValue[BOTTOM], vitinfoDeviceRead.oldRawData(), 6*sizeof(float));
            ++vitinfoDeviceRead;
            while (!vitinfoDevice.isDone()) {
                memcpy(infoValue[BOTTOMBOTTOM], vitinfoDeviceRead.oldRawData(), 6*sizeof(float));
                float* dst = reinterpret_cast<float*>(vitinfoDevice.rawData());
                for (int i = 0; i < 5; i++) {
                    dst[i] =  beta0 * infoValue[CENTER][i] + beta1 * (infoValue[BOTTOM][i] + infoValue[TOP][i]) + beta2 * (infoValue[TOPTOP][i] + infoValue[BOTTOMBOTTOM][i]);
//                   dst[i] =  (2*infoValue[CENTER][i] + ( infoValue[BOTTOM][i] + infoValue[TOP][i] )) / 16;
                }
//                 memmove(infoValue, infoValue + 1, 4*sizeof(float[6]));
                for (int i = 0; i < 5; i++) {
                    memcpy(infoValue[i], infoValue[i+1], 6*sizeof(float));
                }
                ++vitinfoDeviceRead;
                ++vitinfoDevice;
            }
            vitinfoDeviceRead.nextCol();
            vitinfoDevice.nextCol();
        }
    }
#endif

#if 0
    KisTransaction("", infoDevice);
    dbgPlugins << " Blur";
    {
        // Compute the blur mask
        KisAutobrushShape* kas = new KisAutobrushCircleShape(5, 5, 2, 2);

        QImage mask;
        kas->createBrush(&mask);
        KisKernelSP kernel = KisKernel::fromQImage(mask);
        // Apply the convolution to xxDevice
        KisConvolutionPainter infoDevicePainter(infoDevice);
        infoDevicePainter.beginTransaction("bouuh");
        infoDevicePainter.applyMatrix(kernel, 2, 2, rect.width() - 4, rect.height() - 4, BORDER_REPEAT);
        delete kas;
    }
#endif
    dbgPlugins << " compute curvatures";
    // Compute the curvatures
    {
        KisRectIteratorPixel vitinfoDeviceRect = infoDevice->createRectIterator(2, 0, rect.width() - 2, rect.height() - 2);
        for (;!vitinfoDeviceRect.isDone(); ++vitinfoDeviceRect) {
            float* infoValue = reinterpret_cast<float*>(vitinfoDeviceRect.rawData());

            float det = infoValue[INFO_XX] * infoValue[INFO_YY] - infoValue[INFO_XY] * infoValue[INFO_XY];
            float trace = infoValue[INFO_XX] + infoValue[INFO_YY];
            float temp = sqrt(trace * trace - 4 * det);

            infoValue[ INFO_HIGH ] = 0.5 * (trace + temp);
            infoValue[ INFO_LOW  ] = 0.5 * (trace - temp);
            if (infoValue[ INFO_HIGH ] < infoValue[ INFO_LOW  ]) {
                float a = infoValue[ INFO_HIGH ];
                infoValue[ INFO_HIGH ] = infoValue[ INFO_LOW ];
                infoValue[ INFO_LOW ] = a;
            }
//                 dbgPlugins << vitinfoDeviceRect.x() <<"" << vitinfoDeviceRect.y() <<"" << infoValue[INFO_XX] <<"" << infoValue[INFO_YY]  <<"" << infoValue[INFO_XY] <<"" << infoValue[INFO_HIGH] <<"" << infoValue[INFO_LOW] <<"" << trace <<"" << temp <<"" << det;
        }
    }
    HarrisPoints zones(5, 5, rect.width(), rect.height(), FEATURES_QUANTITY);
    // Detect Harris Points
    {
        int margin = 8;
        KisHLineIterator hitinfoDevice = infoDevice-> createHLineIterator(margin, margin, rect.width() - 2 * margin);
        for (int y = margin + rect.top(); y < rect.bottom() - margin; y++) {
            for (int x = margin + rect.left(); x < rect.right() - margin; x++, ++hitinfoDevice) {
                float* infoValue = reinterpret_cast<float*>(hitinfoDevice.rawData());
                float low = infoValue[ INFO_LOW ];
//                     dbgPlugins << low;
                if (low > THRESHOLD_LAMBDA) {
                    KisRectIteratorPixel vitinfoDeviceRect = infoDevice->createRectIterator(x - 1, y - 1, 3, 3);
                    bool greater = true;
                    for (;!vitinfoDeviceRect.isDone(); ++vitinfoDeviceRect) {
                        if (reinterpret_cast<float*>(vitinfoDeviceRect.rawData())[ INFO_LOW ] > low) {
                            greater = false;
                            break;
                        }
                    }
                    if (greater) {
//                             dbgPlugins <<"new point";
                        HarrisPoint* hp = new HarrisPoint(x, y, infoValue[INFO_INTENSITY], infoValue[INFO_HIGH], infoValue[INFO_LOW], device);
#if 0
                        points.push_back(hp);
#endif
#if 0
                        if (points.empty()) {
                            points.push_back(hp);
                        } else {
                            if (points.size() >= FEATURES_QUANTITY && hp->low() > static_cast<HarrisPoint*>(points.back())->low()) { // remove last element, the totalNumber stay equal to FEATURES_QUANTITY
                                points.pop_back();
                            }
                            if (points.size() != FEATURES_QUANTITY) {
                                lInterestPoints::iterator it;
                                if (hp->low() < static_cast<HarrisPoint*>(points.back())->low()) {
                                    points.push_back(hp);
                                } else {
                                    // insert the new corner at his right place
                                    bool inserted = false;
                                    for (it = points.begin(); it != points.end(); it++) {
                                        if (hp->low() >= static_cast<HarrisPoint*>(*it)->low()) {
                                            //                                             dbgPlugins <<"insert point";
                                            points.insert(it, hp);
                                            inserted = true;
                                            break;
                                        }
                                    }
                                    if (!inserted) delete hp;
                                }
                            } else { // hp wasn't added to the list, remove it
                                delete hp;
                            }
                        }
#endif
#if 1
                        zones.instertPoint(hp);
#endif
                    }
                }
            }
            hitinfoDevice.nextRow();
        }
    }
    points = zones.points();
    dbgPlugins << "Harris detector has found :" << points.size() << " harris points";

    delete floatCs;
    return points;
}
Ejemplo n.º 8
0
qreal KisFilterOp::paintAt(const KisPaintInformation& info)
{
    if (!painter()) {
        return 1.0;
    }

    if (!m_filter) {
        return 1.0;
    }

    if (!source()) {
        return 1.0;
    }

    KisBrushSP brush = m_brush;;
    if (!brush) return 1.0;

    if (! brush->canPaintFor(info))
        return 1.0;

    qreal scale = KisPaintOp::scaleForPressure(m_sizeOption.apply(info));
    if ((scale * brush->width()) <= 0.01 || (scale * brush->height()) <= 0.01) return spacing(scale);

    setCurrentScale(scale);
    
    QPointF hotSpot = brush->hotSpot(scale, scale);
    QPointF pt = info.pos() - hotSpot;


    // Split the coordinates into integer plus fractional parts. The integer
    // is where the dab will be positioned and the fractional part determines
    // the sub-pixel positioning.
    qint32 x;
    qreal xFraction;
    qint32 y;
    qreal yFraction;

    splitCoordinate(pt.x(), &x, &xFraction);
    splitCoordinate(pt.y(), &y, &yFraction);

    qint32 maskWidth = brush->maskWidth(scale, 0.0);
    qint32 maskHeight = brush->maskHeight(scale, 0.0);

    // Filter the paint device
    m_filter->process(KisConstProcessingInformation(source(), QPoint(x, y)),
                    KisProcessingInformation(m_tmpDevice, QPoint(0, 0)),
                    QSize(maskWidth, maskHeight),
                    m_filterConfiguration, 0);

    // Apply the mask on the paint device (filter before mask because edge pixels may be important)

    KisFixedPaintDeviceSP fixedDab = new KisFixedPaintDevice(m_tmpDevice->colorSpace());
    fixedDab->setRect(m_tmpDevice->extent());
    fixedDab->initialize();

    m_tmpDevice->readBytes(fixedDab->data(), fixedDab->bounds());
    brush->mask(fixedDab, scale, scale, 0.0, info, xFraction, yFraction);
    m_tmpDevice->writeBytes(fixedDab->data(), fixedDab->bounds());

    if (!m_ignoreAlpha) {
        KisHLineIteratorPixel itTmpDev = m_tmpDevice->createHLineIterator(0, 0, maskWidth);
        KisHLineIteratorPixel itSrc = source()->createHLineIterator(x, y, maskWidth);
        const KoColorSpace* cs = m_tmpDevice->colorSpace();
        for (int y = 0; y < maskHeight; ++y) {
            while (!itTmpDev.isDone()) {
                quint8 alphaTmpDev = cs->opacityU8(itTmpDev.rawData());
                quint8 alphaSrc = cs->opacityU8(itSrc.rawData());

                cs->setOpacity(itTmpDev.rawData(), qMin(alphaTmpDev, alphaSrc), 1);
                ++itTmpDev;
                ++itSrc;
            }
            itTmpDev.nextRow();
            itSrc.nextRow();
        }
    }

    // Blit the paint device onto the layer
    QRect dabRect = QRect(0, 0, maskWidth, maskHeight);
    QRect dstRect = QRect(x, y, dabRect.width(), dabRect.height());

    if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return 1.0;

    qint32 sx = dstRect.x() - x;
    qint32 sy = dstRect.y() - y;
    qint32 sw = dstRect.width();
    qint32 sh = dstRect.height();

    painter()->bitBlt(dstRect.x(), dstRect.y(), m_tmpDevice, sx, sy, sw, sh);
    return spacing(scale);
}