KisPaintDeviceSP KisShearVisitor::xShear(KisPaintDeviceSP src, qreal shearX, KoUpdater *progress)
{
    KisPaintDeviceSP dst = KisPaintDeviceSP(new KisPaintDevice(src->colorSpace()));
    dst->setX(src->x());
    dst->setY(src->y());

    QRect r = src->exactBounds();

    qreal displacement;
    qint32 displacementInt;
    qreal weight;

    KoMixColorsOp * mixOp = src->colorSpace()->mixColorsOp();

    for (qint32 y = r.top(); y <= r.bottom(); y++) {

        //calculate displacement
        displacement = -y * shearX;

        displacementInt = (qint32)(floor(displacement));
        weight = displacement - displacementInt;

        qint16 pixelWeights[2];

        pixelWeights[0] = static_cast<quint8>(weight * 255 + 0.5);
        pixelWeights[1] = 255 - pixelWeights[0];

        KisHLineConstIteratorPixel srcIt = src->createHLineIterator(r.x(), y, r.width() + 1);
        KisHLineConstIteratorPixel leftSrcIt = src->createHLineIterator(r.x() - 1, y, r.width() + 1);
        KisHLineIteratorPixel dstIt = dst->createHLineIterator(r.x() + displacementInt, y, r.width() + 1);

        while (!srcIt.isDone()) {

            const quint8 *pixelPtrs[2];

            pixelPtrs[0] = leftSrcIt.rawData();
            pixelPtrs[1] = srcIt.rawData();

            mixOp->mixColors(pixelPtrs, pixelWeights, 2, dstIt.rawData());

            ++srcIt;
            ++leftSrcIt;
            ++dstIt;
        }
        progress->setProgress(y);

    }
    return dst;
}
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();
    }

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