Esempio n. 1
0
void KisScanlineFillTest::testFillGeneral(const QVector<KisFillInterval> &initialBackwardIntervals,
                                          const QVector<QColor> &expectedResult,
                                          const QVector<KisFillInterval> &expectedForwardIntervals,
                                          const QVector<KisFillInterval> &expectedBackwardIntervals)
{
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);

    dev->setPixel(1, 0, Qt::white);
    dev->setPixel(2, 0, Qt::white);
    dev->setPixel(5, 0, Qt::white);
    dev->setPixel(8, 0, Qt::white);
    dev->setPixel(17, 0, Qt::white);

    QRect boundingRect(-10, -10, 30, 30);

    KisScanlineFill gc(dev, QPoint(), boundingRect);

    KisFillIntervalMap *backwardMap = gc.testingGetBackwardIntervals();
    Q_FOREACH (const KisFillInterval &i, initialBackwardIntervals) {
        backwardMap->insertInterval(i);
    }
Esempio n. 2
0
void KisFillPainterTest::benchmarkFillPainter(const QPoint &startPoint, bool useCompositioning)
{
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);

    QImage srcImage(TestUtil::fetchDataFileLazy("heavy_labyrinth.png"));
    QVERIFY(!srcImage.isNull());

    QRect imageRect = srcImage.rect();

    dev->convertFromQImage(srcImage, 0, 0, 0);


    QBENCHMARK_ONCE {
        KisFillPainter gc(dev);
        gc.setFillThreshold(THRESHOLD);
        gc.setWidth(imageRect.width());
        gc.setHeight(imageRect.height());
        gc.setPaintColor(KoColor(Qt::red, dev->colorSpace()));
        gc.setUseCompositioning(useCompositioning);
        gc.fillColor(startPoint.x(), startPoint.y(), dev);
    }

    QImage resultImage =
        dev->convertToQImage(0,
                             imageRect.x(), imageRect.y(),
                             imageRect.width(), imageRect.height());

    QString testName = QString("heavy_labyrinth_%1_%2_%3")
        .arg(startPoint.x())
        .arg(startPoint.y())
        .arg(useCompositioning ? "composed" : "direct");


    QVERIFY(TestUtil::checkQImage(resultImage,
                                  "fill_painter",
                                  "general_",
                                  testName));
}
Esempio n. 3
0
void ImageBuilder::createImageFromClipboardDelayed()
{
    DocumentManager::instance()->disconnect(this, SLOT(createImageFromClipboardDelayed()));
    KisConfig cfg;
    cfg.setPasteBehaviour(PASTE_ASSUME_MONITOR);

    QSize sz = KisClipboard::instance()->clipSize();
    KisPaintDeviceSP clipDevice = KisClipboard::instance()->clip(QRect(0, 0, sz.width(), sz.height()), false);
    KisImageWSP image = DocumentManager::instance()->document()->image();
    if (image && image->root() && image->root()->firstChild()) {
        KisLayer * layer = dynamic_cast<KisLayer*>(image->root()->firstChild().data());
        Q_ASSERT(layer);
        layer->setOpacity(OPACITY_OPAQUE_U8);
        QRect r = clipDevice->exactBounds();

        KisPainter painter;
        painter.begin(layer->paintDevice());
        painter.setCompositeOp(COMPOSITE_COPY);
        painter.bitBlt(QPoint(0, 0), clipDevice, r);
        layer->setDirty(QRect(0, 0, sz.width(), sz.height()));
    }
}
Esempio n. 4
0
bool PSDImageData::write(QIODevice *io, KisPaintDeviceSP dev, bool hasAlpha)
{
    // XXX: make the compression settting configurable. For now, always use RLE.
    psdwrite(io, (quint16)Compression::RLE);

    // now write all the channels in display order
    // fill in the channel chooser, in the display order, but store the pixel index as well.
    QRect rc(0, 0, m_header->width, m_header->height);

    const int channelSize = m_header->channelDepth / 8;
    const psd_color_mode colorMode = m_header->colormode;

    QVector<PsdPixelUtils::ChannelWritingInfo> writingInfoList;

    bool writeAlpha = hasAlpha &&
        dev->colorSpace()->channelCount() != dev->colorSpace()->colorChannelCount();

    const int numChannels =
        writeAlpha ?
        dev->colorSpace()->channelCount() :
        dev->colorSpace()->colorChannelCount();

    for (int i = 0; i < numChannels; i++) {
        const int rleOffset = io->pos();

        int channelId = writeAlpha && i == numChannels - 1 ? -1 : i;

        writingInfoList <<
            PsdPixelUtils::ChannelWritingInfo(channelId, -1, rleOffset);

        io->seek(io->pos() + rc.height() * sizeof(quint16));
    }

    PsdPixelUtils::writePixelDataCommon(io, dev, rc,
                                        colorMode, channelSize,
                                        false, false, writingInfoList);
    return true;
}
Esempio n. 5
0
bool PSDImageData::write(QIODevice *io, KisPaintDeviceSP dev)
{
    // XXX: make the compression settting configurable. For now, always use RLE.
    psdwrite(io, (quint16)Compression::RLE);

    // now write all the channels in display order
    // fill in the channel chooser, in the display order, but store the pixel index as well.
    QRect rc(0, 0, m_header->width, m_header->height);
    QVector<quint8* > tmp = dev->readPlanarBytes(0, 0, rc.width(), rc.height());
    // then reorder the planes to fit the psd model -- alpha first, then display order
    QVector<quint8* > planes;
    QList<KoChannelInfo*> origChannels = dev->colorSpace()->channels();

    quint8* alphaPlane = 0;
    foreach(KoChannelInfo *ch, KoChannelInfo::displayOrderSorted(origChannels)) {
        int channelIndex = KoChannelInfo::displayPositionToChannelIndex(ch->displayPosition(), origChannels);
        //qDebug() << ppVar(ch->name()) << ppVar(ch->pos()) << ppVar(ch->displayPosition()) << ppVar(channelIndex);
        if (ch->channelType() == KoChannelInfo::ALPHA) {
            alphaPlane = tmp[channelIndex];
        } else {
            planes.append(tmp[channelIndex]);
        }
    }
void KisScratchPad::fillGradient()
{
    if(!m_paintLayer) return;
    KisPaintDeviceSP paintDevice = m_paintLayer->paintDevice();

    KoAbstractGradient* gradient = m_resourceProvider->currentGradient();
    QRect gradientRect = widgetToDocument().mapRect(rect());

    paintDevice->clear();

    KisGradientPainter painter(paintDevice);

    painter.setGradient(gradient);
    painter.paintGradient(gradientRect.topLeft(),
                          gradientRect.bottomRight(),
                          KisGradientPainter::GradientShapeLinear,
                          KisGradientPainter::GradientRepeatNone,
                          0.2, false,
                          gradientRect.left(), gradientRect.top(),
                          gradientRect.width(), gradientRect.height());

    update();
}
void KisCurveMagnetic::detectEdges(const QRect & rect, KisPaintDeviceSP src, GrayMatrix& dst)
{
    GrayMatrix graysrc(rect.width(), GrayCol(rect.height()));
    GrayMatrix xdeltas(rect.width(), GrayCol(rect.height()));
    GrayMatrix ydeltas(rect.width(), GrayCol(rect.height()));
    GrayMatrix magnitude(rect.width(), GrayCol(rect.height()));
    KisPaintDeviceSP smooth = new KisPaintDevice(src->colorSpace());

    gaussianBlur(rect, src, smooth);
    toGrayScale(rect, smooth, graysrc);
    getDeltas(graysrc, xdeltas, ydeltas);
    getMagnitude(xdeltas, ydeltas, magnitude);
    nonMaxSupp(magnitude, xdeltas, ydeltas, dst);
}
bool KisKraSaveVisitor::savePaintDevice(KisPaintDeviceSP device,
                                        QString location)
{
    // Layer data
    KisConfig cfg;
    m_store->setCompressionEnabled(cfg.compressKra());

    if (m_store->open(location)) {
        if (!device->write(*m_writer)) {
            device->disconnect();
            m_store->close();
            return false;
        }

        m_store->close();
    }
    if (m_store->open(location + ".defaultpixel")) {
        m_store->write((char*)device->defaultPixel(), device->colorSpace()->pixelSize());
        m_store->close();
    }
    m_store->setCompressionEnabled(true);
    return true;
}
void KisFixedPaintDeviceTest::testBltFixed()
{
    QImage image(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa.png");
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisFixedPaintDeviceSP fdev = new KisFixedPaintDevice(cs);
    fdev->convertFromQImage(image, 0);

    // Without opacity
    KisPaintDeviceSP dev = new KisPaintDevice(cs);
    KisPainter gc(dev);
    gc.bltFixed(QPoint(0, 0), fdev, image.rect());

    QImage result = dev->convertToQImage(0, 0, 0, 640, 441);

    QPoint errpoint;

    if (!TestUtil::compareQImages(errpoint, image, result, 1)) {
        fdev->convertToQImage(0).save("kis_fixed_paint_device_test_test_blt_fixed_expected.png");
        result.save("kis_fixed_paint_device_test_test_blt_fixed_result.png");
        QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1());
    }

}
Esempio n. 10
0
void KisOilPaintFilter::OilPaint(const KisPaintDeviceSP src, KisPaintDeviceSP dst, const QPoint& srcTopLeft, const QPoint& dstTopLeft, int w, int h,
                                 int BrushSize, int Smoothness, KoUpdater* progressUpdater) const
{
    if (progressUpdater) {
        progressUpdater->setRange(0, w * h);
    }

    QRect bounds(srcTopLeft.x(), srcTopLeft.y(), w, h);

    KisHLineConstIteratorSP it = src->createHLineConstIteratorNG(srcTopLeft.x(), srcTopLeft.y(), w);
    KisHLineIteratorSP dstIt = dst->createHLineIteratorNG(dstTopLeft.x(), dstTopLeft.y(), w);

    int progress = 0;
    for (qint32 yOffset = 0; yOffset < h; yOffset++) {
        do {  //&& !cancelRequested()) {
                MostFrequentColor(src, dstIt->rawData(), bounds, it->x(), it->y(), BrushSize, Smoothness);
        }  while (it->nextPixel() && dstIt->nextPixel());
        it->nextRow();
        dstIt->nextRow();

        if (progressUpdater) progressUpdater->setValue(progress += w);
    }
}
Esempio n. 11
0
void KisPaintDeviceTest::testRoundtripReadWrite()
{
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);
    QImage image(QString(FILES_DATA_DIR) + QDir::separator() + "tile.png");
    dev->convertFromQImage(image, 0);

    quint8* bytes = new quint8[cs->pixelSize() * image.width() * image.height()];
    memset(bytes, 0, image.width() * image.height() * dev->pixelSize());
    dev->readBytes(bytes, image.rect());

    KisPaintDeviceSP dev2 = new KisPaintDevice(cs);
    dev2->writeBytes(bytes, image.rect());
    QVERIFY(dev2->exactBounds() == image.rect());

    dev2->convertToQImage(0, 0, 0, image.width(), image.height()).save("readwrite.png");


    QPoint pt;
    if (!TestUtil::comparePaintDevices(pt, dev, dev2)) {
        QFAIL(QString("Failed round trip using readBytes and writeBytes, first different pixel: %1,%2 ").arg(pt.x()).arg(pt.y()).toLatin1());
    }
}
Esempio n. 12
0
void KisSelectionTest::testSelectionExactBounds()
{
    QRect referenceImageRect(0,0,1000,1000);
    QRect referenceDeviceRect(10,10,1000,1000);

    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();

    KisImageSP image = new KisImage(0, referenceImageRect.width(),
                                    referenceImageRect.height(),
                                    cs, "stest");

    KisPaintDeviceSP device = new KisPaintDevice(cs);
    device->fill(referenceDeviceRect, KoColor(Qt::white, cs));

    QCOMPARE(device->exactBounds(), referenceDeviceRect);

    KisSelectionSP selection = new KisSelection(device, new KisSelectionDefaultBounds(device, image));

    quint8 defaultPixel = MAX_SELECTED;
    selection->setDefaultPixel(&defaultPixel);

    QCOMPARE(selection->selectedExactRect(), referenceImageRect | referenceDeviceRect);
}
Esempio n. 13
0
void KisBlurFilter::processImpl(KisPaintDeviceSP device,
                                const QRect& rect,
                                const KisFilterConfiguration* config,
                                KoUpdater* progressUpdater
                                ) const
{
    QPoint srcTopLeft = rect.topLeft();
    Q_ASSERT(device != 0);
    if (!config) config = new KisFilterConfiguration(id().id(), 1);

    QVariant value;
    int shape = (config->getProperty("shape", value)) ? value.toInt() : 0;
    uint halfWidth = (config->getProperty("halfWidth", value)) ? value.toUInt() : 5;
    uint width = 2 * halfWidth + 1;
    uint halfHeight = (config->getProperty("halfHeight", value)) ? value.toUInt() : 5;
    uint height = 2 * halfHeight + 1;
    int rotate = (config->getProperty("rotate", value)) ? value.toInt() : 0;
    int strength = 100 - (config->getProperty("strength", value) ? value.toUInt() : 0);

    int hFade = (halfWidth * strength) / 100;
    int vFade = (halfHeight * strength) / 100;

    KisMaskGenerator* kas;
    dbgKrita << width << "" << height << "" << hFade << "" << vFade;
    switch (shape) {
    case 1:
        kas = new KisRectangleMaskGenerator(width, width / height , hFade, vFade, 2);
        break;
    case 0:
    default:
        kas = new KisCircleMaskGenerator(width, width / height, hFade, vFade, 2);
        break;
    }

    QBitArray channelFlags;
    if (config) {
        channelFlags = config->channelFlags();
    } 
    if (channelFlags.isEmpty() || !config) {
        channelFlags = QBitArray(device->colorSpace()->channelCount(), true);
    }

    KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMaskGenerator(kas, rotate * M_PI / 180.0);
    delete kas;
    KisConvolutionPainter painter(device);
    painter.setChannelFlags(channelFlags);
    painter.setProgress(progressUpdater);
    painter.applyMatrix(kernel, device, srcTopLeft, srcTopLeft, rect.size(), BORDER_REPEAT);

}
Esempio n. 14
0
void KisFilterTest::testSingleThreaded()
{
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();

    QImage qimage(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa.png");
    QImage inverted(QString(FILES_DATA_DIR) + QDir::separator() + "inverted_hakonepa.png");
    KisPaintDeviceSP dev = new KisPaintDevice(cs);
    dev->convertFromQImage(qimage, 0, 0, 0);

    KisFilterSP f = KisFilterRegistry::instance()->value("invert");
    Q_ASSERT(f);

    KisFilterConfiguration * kfc = f->defaultConfiguration(0);
    Q_ASSERT(kfc);

    f->process(dev, QRect(QPoint(0,0), qimage.size()), kfc);

    QPoint errpoint;
    if (!TestUtil::compareQImages(errpoint, inverted, dev->convertToQImage(0, 0, 0, qimage.width(), qimage.height()))) {
        dev->convertToQImage(0, 0, 0, qimage.width(), qimage.height()).save("filtertest.png");
        QFAIL(QString("Failed to create inverted image, first different pixel: %1,%2 ").arg(errpoint.x()).arg(errpoint.y()).toLatin1());
    }
}
Esempio n. 15
0
void KisScratchPad::setupScratchPad(KisCanvasResourceProvider* resourceProvider,
                                    const QColor &defaultColor)
{
    m_resourceProvider = resourceProvider;
    KisConfig cfg;
    setDisplayProfile(cfg.displayProfile(QApplication::desktop()->screenNumber(this)));
    connect(m_resourceProvider, SIGNAL(sigDisplayProfileChanged(const KoColorProfile*)),
            SLOT(setDisplayProfile(const KoColorProfile*)));

    connect(m_resourceProvider, SIGNAL(sigOnScreenResolutionChanged(qreal,qreal)),
            SLOT(setOnScreenResolution(qreal,qreal)));

    m_defaultColor = KoColor(defaultColor, KoColorSpaceRegistry::instance()->rgb8());

    KisPaintDeviceSP paintDevice =
        new KisPaintDevice(m_defaultColor.colorSpace(), "scratchpad");

    m_paintLayer = new KisPaintLayer(0, "ScratchPad", OPACITY_OPAQUE_U8, paintDevice);
    m_paintLayer->setGraphListener(m_nodeListener);
    paintDevice->setDefaultBounds(new KisScratchPadDefaultBounds(this));

    fillDefault();
}
    void copyFromDevice(KisViewManager *view, KisPaintDeviceSP device, bool makeSharpClip = false)
    {
        KisImageWSP image = view->image();
        if (!image) return;

        KisSelectionSP selection = view->selection();

        QRect rc = (selection) ? selection->selectedExactRect() : image->bounds();

        KisPaintDeviceSP clip = new KisPaintDevice(device->colorSpace());
        Q_CHECK_PTR(clip);

        const KoColorSpace *cs = clip->colorSpace();

        // TODO if the source is linked... copy from all linked layers?!?

        // Copy image data
        KisPainter::copyAreaOptimized(QPoint(), device, clip, rc);

        if (selection) {
            // Apply selection mask.
            KisPaintDeviceSP selectionProjection = selection->projection();
            KisHLineIteratorSP layerIt = clip->createHLineIteratorNG(0, 0, rc.width());
            KisHLineConstIteratorSP selectionIt = selectionProjection->createHLineIteratorNG(rc.x(), rc.y(), rc.width());

            const KoColorSpace *selCs = selection->projection()->colorSpace();

            for (qint32 y = 0; y < rc.height(); y++) {

                for (qint32 x = 0; x < rc.width(); x++) {

                    /**
                     * Sharp method is an exact reverse of COMPOSITE_OVER
                     * so if you cover the cut/copied piece over its source
                     * you get an exactly the same image without any seams
                     */
                    if (makeSharpClip) {
                        qreal dstAlpha = cs->opacityF(layerIt->rawData());
                        qreal sel = selCs->opacityF(selectionIt->oldRawData());
                        qreal newAlpha = sel * dstAlpha / (1.0 - dstAlpha + sel * dstAlpha);
                        float mask = newAlpha / dstAlpha;

                        cs->applyAlphaNormedFloatMask(layerIt->rawData(), &mask, 1);
                    } else {
                        cs->applyAlphaU8Mask(layerIt->rawData(), selectionIt->oldRawData(), 1);
                    }

                    layerIt->nextPixel();
                    selectionIt->nextPixel();
                }
                layerIt->nextRow();
                selectionIt->nextRow();
            }
        }

        KisClipboard::instance()->setClip(clip, rc.topLeft());
    }
Esempio n. 17
0
// #include <valgrind/callgrind.h>
void KisConvolutionPainterTest::benchmarkConvolution()
{
    QImage referenceImage(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa.png");
    QRect imageRect(QPoint(), referenceImage.size());

    KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8());
    dev->convertFromQImage(referenceImage, 0, 0, 0);

    int diameter = 1;

    for (int i = 0; i < 4; i++) {

        KisCircleMaskGenerator* kas = new KisCircleMaskGenerator(diameter, 1.0, 5, 5, 2, false);
        KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMaskGenerator(kas);

        KisConvolutionPainter gc(dev);

        QTime timer; timer.start();

        // CALLGRIND_START_INSTRUMENTATION;

        gc.beginTransaction();
        gc.applyMatrix(kernel, dev, imageRect.topLeft(), imageRect.topLeft(),
                       imageRect.size());
        gc.deleteTransaction();

        // CALLGRIND_STOP_INSTRUMENTATION;

        dbgKrita << "Diameter:" << diameter << "time:" << timer.elapsed();

        if(diameter < 4) {
            diameter += 2;
        } else {
            diameter += 8;
        }
    }
}
void KisFixedPaintDeviceTest::testBltFixedOpacity()
{
    // blt a semi-transparent image on a white paint device

    QImage image(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa_transparent.png");
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisFixedPaintDeviceSP fdev = new KisFixedPaintDevice(cs);
    fdev->convertFromQImage(image, 0);

    KisPaintDeviceSP dev = new KisPaintDevice(cs);
    dev->fill(0, 0, 640, 441, KoColor(Qt::white, cs).data());
    KisPainter gc(dev);
    gc.bltFixed(QPoint(0, 0), fdev, image.rect());

    QImage result = dev->convertToQImage(0, 0, 0, 640, 441);
    QImage checkResult(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa_transparent_result.png");
    QPoint errpoint;

    if (!TestUtil::compareQImages(errpoint, checkResult, result, 1)) {
        checkResult.save("kis_fixed_paint_device_test_test_blt_fixed_opactiy_expected.png");
        result.save("kis_fixed_paint_device_test_test_blt_fixed_opacity_result.png");
        QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1());
    }
}
Esempio n. 19
0
void KisShapeLayerCanvas::repaint()
{
    QRect r;

    {
        QMutexLocker locker(&m_dirtyRegionMutex);
        r = m_dirtyRegion.boundingRect();
        m_dirtyRegion = QRegion();
    }

    if (r.isEmpty()) return;

    r = r.intersected(m_parentLayer->image()->bounds());
    QImage image(r.width(), r.height(), QImage::Format_ARGB32);
    image.fill(0);
    QPainter p(&image);

    p.setRenderHint(QPainter::Antialiasing);
    p.setRenderHint(QPainter::TextAntialiasing);
    p.translate(-r.x(), -r.y());
    p.setClipRect(r);
#ifdef DEBUG_REPAINT
    QColor color = QColor(random() % 255, random() % 255, random() % 255);
    p.fillRect(r, color);
#endif

    m_shapeManager->paint(p, *m_viewConverter, false);
    p.end();

    KisPaintDeviceSP dev = new KisPaintDevice(m_projection->colorSpace());
    dev->convertFromQImage(image, 0);

    KisPainter::copyAreaOptimized(r.topLeft(), dev, m_projection, QRect(QPoint(), r.size()));

    m_parentLayer->setDirty(r);
}
void KisTransformWorkerTest::testYScaleUp()
{
    TestUtil::TestProgressBar bar;
    KoProgressUpdater pu(&bar);
    KoUpdaterPtr updater = pu.startSubtask();

    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    QImage image(QString(FILES_DATA_DIR) + QDir::separator() + "mirror_source.png");
    KisPaintDeviceSP dev = new KisPaintDevice(cs);
    dev->convertFromQImage(image, "");

    KisFilterStrategy * filter = new KisBoxFilterStrategy();

    KisTransaction t("test", dev);
    KisTransformWorker tw(dev, 1.0, 2.0,
                          0.0, 0.0,
                          0.0, 0.0,
                          0.0,
                          0, 0, updater, filter, true);
    tw.run();
    t.end();
    
    QRect rc = dev->exactBounds();

    QVERIFY(rc.width() == image.width());
    QVERIFY(rc.height() == image.height() * 2);

    QImage result = dev->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height());
    QPoint errpoint;
    image.load(QString(FILES_DATA_DIR) + QDir::separator() + "scaleupy_result.png");
    if (!TestUtil::compareQImages(errpoint, image, result)) {
        image.save("test_y_scaleup_source.png");
        result.save("test_y_scaleup_result.png");
        QFAIL(QString("Failed to scale up the image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toAscii());
    }
}
void KisPerspectiveTransformWorker::run()
{
    KIS_ASSERT_RECOVER_RETURN(m_dev);

    if (m_isIdentity) return;

    KisPaintDeviceSP cloneDevice = new KisPaintDevice(*m_dev.data());

    // Clear the destination device, since all the tiles are already
    // shared with cloneDevice
    m_dev->clear();

    KIS_ASSERT_RECOVER_NOOP(!m_isIdentity);

    KisProgressUpdateHelper progressHelper(m_progressUpdater, 100, m_dstRegion.rectCount());

    KisRandomSubAccessorSP srcAcc = cloneDevice->createRandomSubAccessor();
    KisRandomAccessorSP accessor = m_dev->createRandomAccessorNG(0, 0);

    foreach(const QRect &rect, m_dstRegion.rects()) {
        for (int y = rect.y(); y < rect.y() + rect.height(); ++y) {
            for (int x = rect.x(); x < rect.x() + rect.width(); ++x) {

                QPointF dstPoint(x, y);
                QPointF srcPoint = m_backwardTransform.map(dstPoint);

                if (m_srcRect.contains(srcPoint)) {
                    accessor->moveTo(dstPoint.x(), dstPoint.y());
                    srcAcc->moveTo(srcPoint.x(), srcPoint.y());
                    srcAcc->sampledOldRawData(accessor->rawData());
                }
            }
        }
        progressHelper.step();
    }
}
Esempio n. 22
0
void KisThreadedApplicatorTest::testApplication()
{
    const KoColorSpace * colorSpace = KoColorSpaceRegistry::instance()->rgb8();
    TestJobFactory factory;
    TestUtil::TestProgressBar bar;
    KoProgressUpdater updater(&bar);
    KisPaintDeviceSP test = new KisPaintDevice(colorSpace);

    quint8 *bytes = test->colorSpace()->allocPixelBuffer(1);
    memset(bytes, 128, test->colorSpace()->pixelSize());
    test->fill(0, 0, 1000, 1000, bytes);

    KisThreadedApplicator applicator(test, QRect(0, 0, 1000, 1000), &factory, &updater);
    applicator.execute();

    KisRectConstIteratorPixel it = test->createRectConstIterator(0, 0, 1000, 1000);
    while (!it.isDone()) {
        QCOMPARE((int)it.rawData()[0], (int)255);
        QCOMPARE((int)it.rawData()[1], (int)255);
        QCOMPARE((int)it.rawData()[2], (int)255);
        QCOMPARE((int)it.rawData()[3], (int)255);
        ++it;
    }
}
Esempio n. 23
0
//#define SAVE_OUTPUT_IMAGES
void KisAutoBrushTest::testCopyMasking()
{
    int w = 64;
    int h = 64;
    int x = 0;
    int y = 0;
    QRect rc(x, y, w, h);

    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();

    KoColor black(Qt::black, cs);
    KoColor red(Qt::red, cs);


    KisPaintDeviceSP tempDev = new KisPaintDevice(cs);
    tempDev->fill(0, 0, w, h, red.data());
#ifdef SAVE_OUTPUT_IMAGES
    tempDev->convertToQImage(0).save("tempDev.png");
#endif

    KisCircleMaskGenerator * mask = new KisCircleMaskGenerator(w, 1.0, 0.5, 0.5, 2, true);
    KisAutoBrush brush(mask, 0, 0);

    KisFixedPaintDeviceSP maskDab = new KisFixedPaintDevice(cs);
    brush.mask(maskDab, black, KisDabShape(), KisPaintInformation());
    maskDab->convertTo(KoColorSpaceRegistry::instance()->alpha8());

#ifdef SAVE_OUTPUT_IMAGES
    maskDab->convertToQImage(0, 0, 0, 64, 64).save("maskDab.png");
#endif

    QCOMPARE(tempDev->exactBounds(), rc);
    QCOMPARE(maskDab->bounds(), rc);

    KisFixedPaintDeviceSP dev2fixed = new KisFixedPaintDevice(cs);
    dev2fixed->setRect(rc);
    dev2fixed->initialize();
    tempDev->readBytes(dev2fixed->data(), rc);
    dev2fixed->convertToQImage(0).save("converted-tempDev-to-fixed.png");

    KisPaintDeviceSP dev = new KisPaintDevice(cs);
    KisPainter painter(dev);
    painter.setCompositeOp(COMPOSITE_COPY);
    painter.bltFixedWithFixedSelection(x, y, dev2fixed, maskDab, 0, 0, 0, 0, rc.width(), rc.height());
    //painter.bitBltWithFixedSelection(x, y, tempDev, maskDab, 0, 0, 0, 0, rc.width(), rc.height());

#ifdef SAVE_OUTPUT_IMAGES
    dev->convertToQImage(0).save("final.png");
#endif
}
void KisImportGmicProcessingVisitor::gmicImageToPaintDevice(cimg_library::CImg< float >& srcGmicImage,
                                                            KisPaintDeviceSP dst, KisSelectionSP selection, const QRect &dstRect)
{
        if (selection)
        {
            KisPaintDeviceSP src = new KisPaintDevice(dst->colorSpace());
            KisGmicSimpleConvertor::convertFromGmicFast(srcGmicImage, src, 255.0f);

            KisPainter painter(dst, selection);
            painter.bitBlt(dstRect.topLeft(), src, QRect(QPoint(0,0),dstRect.size()));
        }
        else
        {
            KisGmicSimpleConvertor::convertFromGmicFast(srcGmicImage, dst, 255.0f);
        }
}
void TransformStrokeStrategy::transformAndMergeDevice(const ToolTransformArgs &config,
                                                      KisPaintDeviceSP src,
                                                      KisPaintDeviceSP dst,
                                                      KisProcessingVisitor::ProgressHelper *helper)
{
    KoUpdaterPtr mergeUpdater = src != dst ? helper->updater() : 0;

    KisTransformUtils::transformDevice(config, src, helper);
    if (src != dst) {
        QRect mergeRect = src->extent();
        KisPainter painter(dst);
        painter.setProgress(mergeUpdater);
        painter.bitBlt(mergeRect.topLeft(), src, mergeRect);
        painter.end();
    }
}
Esempio n. 26
0
void testWrappedLineIteratorReadMoreThanBounds(QString testName)
{
    const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = createWrapAroundPaintDevice(cs);
    KisPaintDeviceSP dst = new KisPaintDevice(cs);

    // fill device with a gradient
    QRect bounds = dev->defaultBounds()->bounds();
    for (int y = bounds.y(); y < bounds.y() + bounds.height(); y++) {
        for (int x = bounds.x(); x < bounds.x() + bounds.width(); x++) {
            QColor c((10 * x) % 255, (10 * y) % 255, 0, 255);
            dev->setPixel(x, y, c);
        }
    }

    // test rect doesn't fit the wrap rect in both dimentions
    const QRect &rect(bounds.adjusted(-6,-6,8,8));
    KisRandomAccessorSP dstIt = dst->createRandomAccessorNG(rect.x(), rect.y());
    IteratorSP it = createIterator<IteratorSP>(dev, rect);

    for (int y = rect.y(); y < rect.y() + rect.height(); y++) {
        for (int x = rect.x(); x < rect.x() + rect.width(); x++) {
            quint8 *data = it->rawData();

            QVERIFY(checkConseqPixels<IteratorSP>(it->nConseqPixels(), QPoint(x, y), KisWrappedRect(rect, bounds)));

            dstIt->moveTo(x, y);
            memcpy(dstIt->rawData(), data, cs->pixelSize());

            QVERIFY(checkXY<IteratorSP>(QPoint(it->x(), it->y()), QPoint(x,y)));

            bool stepDone = it->nextPixel();
            QCOMPARE(stepDone, x < rect.x() + rect.width() - 1);
        }
        if (!nextRowGeneral(it, y, rect)) break;
    }

    testName = QString("%1_%2_%3_%4_%5")
        .arg(testName)
        .arg(rect.x())
        .arg(rect.y())
        .arg(rect.width())
        .arg(rect.height());

    QRect rc = rect;
    QImage result = dst->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height());
    QImage ref = dev->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height());

    QVERIFY(TestUtil::checkQImage(result, "paint_device_test", "wrapped_iterators_huge", testName));
}
Esempio n. 27
0
void KisTransactionTest::testUndo()
{
    KisSurrogateUndoAdapter undoAdapter;
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);

    quint8* pixel = new quint8[cs->pixelSize()];
    cs->fromQColor(Qt::white, pixel);
    dev->fill(0, 0, 512, 512, pixel);

    cs->fromQColor(Qt::black, pixel);
    dev->fill(512, 0, 512, 512, pixel);

    QColor c1, c2;
    dev->pixel(5, 5, &c1);
    dev->pixel(517, 5, &c2);

    QVERIFY(c1 == Qt::white);
    QVERIFY(c2 == Qt::black);

    KisTransaction transaction(kundo2_noi18n("mirror"), dev, 0);
    KisTransformWorker::mirrorX(dev);
    transaction.commit(&undoAdapter);

    dev->pixel(5, 5, &c1);
    dev->pixel(517, 5, &c2);

    QVERIFY(c1 == Qt::black);
    QVERIFY(c2 == Qt::white);

    undoAdapter.undo();

    dev->pixel(5, 5, &c1);
    dev->pixel(517, 5, &c2);

    QVERIFY(c1 == Qt::white);
    QVERIFY(c2 == Qt::black);

}
Esempio n. 28
0
void KisPaintDeviceTest::testColorSpaceConversion()
{
    QImage image(QString(FILES_DATA_DIR) + QDir::separator() + "tile.png");
    const KoColorSpace* srcCs = KoColorSpaceRegistry::instance()->rgb8();
    const KoColorSpace* dstCs = KoColorSpaceRegistry::instance()->lab16();
    KisPaintDeviceSP dev = new KisPaintDevice(srcCs);
    dev->convertFromQImage(image, 0);
    dev->move(10, 10);   // Unalign with tile boundaries
    KUndo2Command* cmd = dev->convertTo(dstCs);

    QCOMPARE(dev->exactBounds(), QRect(10, 10, image.width(), image.height()));
    QCOMPARE(dev->pixelSize(), dstCs->pixelSize());
    QVERIFY(*dev->colorSpace() == *dstCs);

    delete cmd;
}
Esempio n. 29
0
void KisOilPaintFilter::processImpl(KisPaintDeviceSP device,
                                    const QRect& applyRect,
                                    const KisFilterConfiguration* config,
                                    KoUpdater* progressUpdater
                                    ) const
{
    QPoint srcTopLeft = applyRect.topLeft();
    Q_ASSERT(!device.isNull());

    qint32 width = applyRect.width();
    qint32 height = applyRect.height();

    //read the filter configuration values from the KisFilterConfiguration object
    quint32 brushSize = config ? config->getInt("brushSize", 1) : 1;
    quint32 smooth = config ? config->getInt("smooth", 30) : 30;

    OilPaint(device, device, srcTopLeft, applyRect.topLeft(), width, height, brushSize, smooth, progressUpdater);
}
Esempio n. 30
0
    KisSelectionSP selectionFromAlphaChannel(KisPaintDeviceSP device,
                                             const QRect &srcRect)
    {
        const KoColorSpace *cs = device->colorSpace();

        KisSelectionSP baseSelection = new KisSelection(new KisSelectionEmptyBounds(0));
        KisPixelSelectionSP selection = baseSelection->pixelSelection();

        KisSequentialConstIterator srcIt(device, srcRect);
        KisSequentialIterator dstIt(selection, srcRect);

        do {
            quint8 *dstPtr = dstIt.rawData();
            const quint8* srcPtr = srcIt.rawDataConst();
            *dstPtr = cs->opacityU8(srcPtr);
        } while(srcIt.nextPixel() && dstIt.nextPixel());

        return baseSelection;
    }