void KisClipboardTest::testRoundTrip()
{
    const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);
    KisPaintDeviceSP newDev;
    QPoint errorPoint;

    QRect fillRect(10,10,20,20);
    KoColor pixel(Qt::red, cs);
    dev->fill(fillRect.x(),fillRect.y(),
              fillRect.width(), fillRect.height(), pixel.data());

    QCOMPARE(dev->exactBounds(), fillRect);
    KisClipboard::instance()->setClip(dev, QPoint());
    newDev = KisClipboard::instance()->clip(QPoint());
    QCOMPARE(newDev->exactBounds().size(), fillRect.size());
    newDev->setX(dev->x());
    newDev->setY(dev->y());
    QVERIFY(TestUtil::comparePaintDevices(errorPoint, dev, newDev));

    QPoint offset(100,100);
    dev->setX(offset.x());
    dev->setY(offset.y());

    QCOMPARE(dev->exactBounds(), fillRect.translated(offset));
    KisClipboard::instance()->setClip(dev, QPoint());
    newDev = KisClipboard::instance()->clip(QPoint());
    QCOMPARE(newDev->exactBounds().size(), fillRect.translated(offset).size());
    newDev->setX(dev->x());
    newDev->setY(dev->y());
    QVERIFY(TestUtil::comparePaintDevices(errorPoint, dev, newDev));
}
Example #2
0
void KisPaintDeviceTest::testClear()
{
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);

    QVERIFY(dev->extent() == QRect(2147483647, 2147483647, 0, 0));
    QVERIFY(dev->exactBounds() == QRect(2147483647, 2147483647, 0, 0));

    dev->clear();

    QVERIFY(dev->extent() == QRect(2147483647, 2147483647, 0, 0));
    QVERIFY(dev->exactBounds() == QRect(2147483647, 2147483647, 0, 0));

    dev->clear(QRect(100, 100, 100, 100));

    // XXX: This is strange!
    QVERIFY(dev->extent() == QRect(64, 64, 192, 192));
    QVERIFY(dev->exactBounds() == QRect(64, 64, 192, 192));

    dev->clear();

    QVERIFY(dev->extent() == QRect(2147483647, 2147483647, 0, 0));
    QVERIFY(dev->exactBounds() == QRect(2147483647, 2147483647, 0, 0));

}
Example #3
0
    QVector<QPoint> splitIntoConnectedComponents(KisPaintDeviceSP dev,
                                                 const QRect &boundingRect)
{
    QVector<QPoint> points;
    const KoColorSpace *cs = dev->colorSpace();

    const QRect rect = dev->exactBounds() & boundingRect;
    if (rect.isEmpty()) return points;

    /**
     * Please note that since we modify the device inside
     * clearNonZeroComponent() call, we must use a *writable*
     * iterator, for not ending up with a lazy copied old version of a
     * device.
     */
    KisSequentialIterator dstIt(dev, rect);

    do {
        if (cs->opacityU8(dstIt.rawData()) > 0) {
            const QPoint pt(dstIt.x(), dstIt.y());
            points << pt;

            KisScanlineFill fill(dev, pt, rect);
            fill.clearNonZeroComponent();
        }
    } while (dstIt.nextPixel());

    return points;
}
void KisPasteNewActionFactory::run(KisViewManager *viewManager)
{
    Q_UNUSED(viewManager);

    KisPaintDeviceSP clip = KisClipboard::instance()->clip(QRect(), true);
    if (!clip) return;

    QRect rect = clip->exactBounds();
    if (rect.isEmpty()) return;

    KisDocument *doc = KisPart::instance()->createDocument();

    KisImageSP image = new KisImage(doc->createUndoStore(),
                                    rect.width(),
                                    rect.height(),
                                    clip->colorSpace(),
                                    i18n("Pasted"));
    KisPaintLayerSP layer =
        new KisPaintLayer(image.data(), clip->objectName(),
                          OPACITY_OPAQUE_U8, clip->colorSpace());

    KisPainter::copyAreaOptimized(QPoint(), clip, layer->paintDevice(), rect);

    image->addNode(layer.data(), image->rootLayer());
    doc->setCurrentImage(image);
    KisPart::instance()->addDocument(doc);

    KisMainWindow *win = viewManager->mainWindow();
    win->addViewAndNotifyLoadingCompleted(doc);
}
void KisGmicSimpleConvertor::convertToGmicImage(KisPaintDeviceSP dev, gmic_image< float >& gmicImage)
{
    const KoColorSpace *rgbaFloat32bitcolorSpace = KoColorSpaceRegistry::instance()->colorSpace(RGBAColorModelID.id(),
                                                                                                Float32BitsColorDepthID.id(),
                                                                                                KoColorSpaceRegistry::instance()->rgb8()->profile());

    Q_CHECK_PTR(rgbaFloat32bitcolorSpace);
    dev->convertTo(rgbaFloat32bitcolorSpace);

    QRect rc = dev->exactBounds();
    m_planarBytes = dev->readPlanarBytes(rc.x(), rc.y(), rc.width(), rc.height());
    setChannelSize(rc.width() * rc.height());

    int greenOffset = gmicImage._width * gmicImage._height;
    int blueOffset = greenOffset * 2;
    int alphaOffset = greenOffset * 3;
    quint8 * redChannelBytes   = m_planarBytes.at(KoRgbF32Traits::red_pos);
    quint8 * greenChannelBytes = m_planarBytes.at(KoRgbF32Traits::green_pos);
    quint8 * blueChannelBytes  = m_planarBytes.at(KoRgbF32Traits::blue_pos);
    quint8 * alphaChannelBytes = m_planarBytes.at(KoRgbF32Traits::alpha_pos);

    unsigned int channelSize = sizeof(float);

    memcpy(gmicImage._data                  ,redChannelBytes    ,gmicImage._width * gmicImage._height * channelSize);
    memcpy(gmicImage._data + greenOffset    ,greenChannelBytes  ,gmicImage._width * gmicImage._height * channelSize);
    memcpy(gmicImage._data + blueOffset     ,blueChannelBytes   ,gmicImage._width * gmicImage._height * channelSize);
    memcpy(gmicImage._data + alphaOffset    ,alphaChannelBytes  ,gmicImage._width * gmicImage._height * channelSize);
}
Example #6
0
void KisPaintDeviceTest::testMakeClone()
{
    QImage image(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa.png");

    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP srcDev = new KisPaintDevice(cs);
    srcDev->convertFromQImage(image, 0);
    srcDev->move(10,10);

    const KoColorSpace * weirdCS = KoColorSpaceRegistry::instance()->lab16();
    KisPaintDeviceSP dstDev = new KisPaintDevice(weirdCS);
    dstDev->move(1000,1000);

    QVERIFY(!dstDev->fastBitBltPossible(srcDev));

    QRect cloneRect(100,100,200,200);
    QPoint errpoint;

    dstDev->makeCloneFrom(srcDev, cloneRect);

    QVERIFY(*dstDev->colorSpace() == *srcDev->colorSpace());
    QCOMPARE(dstDev->pixelSize(), srcDev->pixelSize());
    QCOMPARE(dstDev->x(), srcDev->x());
    QCOMPARE(dstDev->y(), srcDev->y());
    QCOMPARE(dstDev->exactBounds(), cloneRect);

    QImage srcImage = srcDev->convertToQImage(0, cloneRect.x(), cloneRect.y(),
                                              cloneRect.width(), cloneRect.height());
    QImage dstImage = dstDev->convertToQImage(0, cloneRect.x(), cloneRect.y(),
                                              cloneRect.width(), cloneRect.height());
    if (!TestUtil::compareQImages(errpoint, dstImage, srcImage)) {
        QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1());
    }
}
void KisTransformWorkerTest::testIdentity()
{
    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, 1.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());

    QImage result = dev->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height());
    QPoint errpoint;
    if (!TestUtil::compareQImages(errpoint, image, result)) {
        image.save("test_identity_source.png");
        result.save("test_identity_result.png");
        QFAIL(QString("Failed to apply identity transformation to image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toAscii());
    }
}
void KisPasteNewActionFactory::run(KisView2 *view)
{
    Q_UNUSED(view);

    KisPaintDeviceSP clip = KisClipboard::instance()->clip(QRect(), true);
    if (!clip) return;

    QRect rect = clip->exactBounds();
    if (rect.isEmpty()) return;

    KisDoc2 *doc = new KisDoc2();
    if (!doc) return;

    KisImageSP image = new KisImage(doc->createUndoStore(),
                                    rect.width(),
                                    rect.height(),
                                    clip->colorSpace(),
                                    i18n("Pasted"));
    KisPaintLayerSP layer =
        new KisPaintLayer(image.data(), clip->objectName(),
                          OPACITY_OPAQUE_U8, clip->colorSpace());

    KisPainter p(layer->paintDevice());
    p.setCompositeOp(COMPOSITE_COPY);
    p.bitBlt(0, 0, clip, rect.x(), rect.y(), rect.width(), rect.height());
    p.end();

    image->addNode(layer.data(), image->rootLayer());
    doc->setCurrentImage(image);

    KoMainWindow *win = doc->documentPart()->createMainWindow();
    win->show();
    win->setRootDocument(doc);
}
void KisShearVisitor::shear(KisPaintDeviceSP dev, qreal angleX, qreal angleY, KoUpdater *progress)
{
    const qreal pi = 3.1415926535897932385;
    qreal thetaX = angleX * pi / 180;
    qreal shearX = tan(thetaX);
    qreal thetaY = angleY * pi / 180;
    qreal shearY = tan(thetaY);

    QRect r = dev->exactBounds();
    progress->setRange(0, r.height() + r.width());

    KisPaintDeviceSP sheared;
    sheared = xShear(dev, shearX, progress);

    sheared = yShear(sheared, shearY, progress);
    dev->clear();

    KisPainter p2(dev);
    r = sheared->extent();

    p2.bitBlt(r.x(), r.y(), sheared, r.x(), r.y(), r.width(), r.height());
    p2.end();

    progress->setProgress(progress->maximum());
}
Example #10
0
void KisSmallTilesFilter::processImpl(KisPaintDeviceSP device,
                                      const QRect& /*applyRect*/,
                                      const KisFilterConfiguration* config,
                                      KoUpdater* progressUpdater
                                      ) const
{
    Q_ASSERT(!device.isNull());

    //read the filter configuration values from the KisFilterConfiguration object
    quint32 numberOfTiles = config->getInt("numberOfTiles", 2);

    QRect srcRect = device->exactBounds();

    int w = static_cast<int>(srcRect.width() / numberOfTiles);
    int h = static_cast<int>(srcRect.height() / numberOfTiles);

    KisPaintDeviceSP tile = device->createThumbnailDevice(srcRect.width() / numberOfTiles, srcRect.height() / numberOfTiles);
    if (tile.isNull()) return;

    KisPainter gc(device);
    gc.setCompositeOp(COMPOSITE_COPY);

    if (progressUpdater) {
        progressUpdater->setRange(0, numberOfTiles);
    }

    for (uint y = 0; y < numberOfTiles; ++y) {
        for (uint x = 0; x < numberOfTiles; ++x) {
            gc.bitBlt(w * x, h * y, tile, 0, 0, w, h);
        }
        if (progressUpdater) progressUpdater->setValue(y);
    }
    gc.end();
}
void KisPerspectiveTransformWorker::runPartialDst(KisPaintDeviceSP srcDev,
                                                  KisPaintDeviceSP dstDev,
                                                  const QRect &dstRect)
{
    if (m_isIdentity) {
        KisPainter::copyAreaOptimizedOldData(dstRect.topLeft(), srcDev, dstDev, dstRect);
        return;
    }

    QRectF srcClipRect = srcDev->exactBounds();
    if (srcClipRect.isEmpty()) return;

    KisProgressUpdateHelper progressHelper(m_progressUpdater, 100, dstRect.height());

    KisRandomSubAccessorSP srcAcc = srcDev->createRandomSubAccessor();
    KisRandomAccessorSP accessor = dstDev->createRandomAccessorNG(dstRect.x(), dstRect.y());

    for (int y = dstRect.y(); y < dstRect.y() + dstRect.height(); ++y) {
        for (int x = dstRect.x(); x < dstRect.x() + dstRect.width(); ++x) {

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

            if (srcClipRect.contains(srcPoint)) {
                accessor->moveTo(dstPoint.x(), dstPoint.y());
                srcAcc->moveTo(srcPoint.x(), srcPoint.y());
                srcAcc->sampledOldRawData(accessor->rawData());
            }
        }
        progressHelper.step();
    }

}
Example #12
0
void testWrappedLineIterator(QString testName, const QRect &rect)
{
    testName = QString("%1_%2_%3_%4_%5")
        .arg(testName)
        .arg(rect.x())
        .arg(rect.y())
        .arg(rect.width())
        .arg(rect.height());

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

    // test rect fits the wrap rect in both dimensions
    IteratorSP it = createIterator<IteratorSP>(dev, rect);

    int y = 0;
    do {
        int x = 0;
        do {
            quint8 *data = it->rawData();

            data[0] = 10 * x;
            data[1] = 10 * y;
            data[2] = 0;
            data[3] = 255;

            x++;
        } while (it->nextPixel());
    } while (nextRowGeneral(it, ++y, rect));

    QRect rc = dev->defaultBounds()->bounds() | dev->exactBounds();
    QImage result = dev->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height());

    QVERIFY(TestUtil::checkQImage(result, "paint_device_test", "wrapped_iterators", testName));
}
void KisConvolutionPainterTest::testGaussianBase(KisPaintDeviceSP dev, bool useFftw, const QString &prefix)
{
   QBitArray channelFlags =
       KoColorSpaceRegistry::instance()->rgb8()->channelFlags(true, true);

   KisPainter gc(dev);


   qreal horizontalRadius = 5, verticalRadius = 5;

   for(int i = 0; i < 3 ; i++, horizontalRadius+=5, verticalRadius+=5)
   {
       QTime timer;
       timer.start();

       gc.beginTransaction();

       if (( horizontalRadius > 0 ) && ( verticalRadius > 0 )) {
           KisPaintDeviceSP interm = new KisPaintDevice(dev->colorSpace());

           KisConvolutionKernelSP kernelHoriz = KisGaussianKernel::createHorizontalKernel(horizontalRadius);
           KisConvolutionKernelSP kernelVertical = KisGaussianKernel::createVerticalKernel(verticalRadius);

           const QRect applyRect = dev->exactBounds();

           KisConvolutionPainter::TestingEnginePreference enginePreference =
               useFftw ?
               KisConvolutionPainter::FFTW :
               KisConvolutionPainter::SPATIAL;

           KisConvolutionPainter horizPainter(interm, enginePreference);
           horizPainter.setChannelFlags(channelFlags);
           horizPainter.applyMatrix(kernelHoriz, dev,
                                    applyRect.topLeft() - QPoint(0, verticalRadius),
                                    applyRect.topLeft() - QPoint(0, verticalRadius),
                                    applyRect.size() + QSize(0, 2 * verticalRadius),
                                    BORDER_REPEAT);

           KisConvolutionPainter verticalPainter(dev, enginePreference);
           verticalPainter.setChannelFlags(channelFlags);
           verticalPainter.applyMatrix(kernelVertical, interm,
                                       applyRect.topLeft(),
                                       applyRect.topLeft(),
                                       applyRect.size(), BORDER_REPEAT);

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

           QString engine = useFftw ? "fftw" : "spatial";
           QString testCaseName = QString("test_gaussian_%1_%2_%3.png").arg(horizontalRadius).arg(verticalRadius).arg(engine);

           TestUtil::checkQImage(result,
                                 "convolution_painter_test",
                                 QString("gaussian_") + prefix,
                                 testCaseName);

           gc.revertTransaction();
       }
       dbgKrita << "Elapsed time:" << timer.elapsed() << "ms";
    }
}
Example #14
0
void KisPaintDeviceTest::testCrop()
{
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);
    quint8* pixel = new quint8[cs->pixelSize()];
    cs->fromQColor(Qt::white, pixel);
    dev->fill(-14, 8, 433, 512, pixel);

    QVERIFY(dev->exactBounds() == QRect(-14, 8, 433, 512));

    // Crop inside
    dev->crop(50, 50, 150, 150);
    QVERIFY(dev->exactBounds() == QRect(50, 50, 150, 150));

    // Crop outside, pd should not grow
    dev->crop(0, 0, 1000, 1000);
    QVERIFY(dev->exactBounds() == QRect(50, 50, 150, 150));
}
Example #15
0
void KisPaintDeviceTest::testExactBoundsWeirdNullAlphaCase()
{
    const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);

    QVERIFY(dev->exactBounds().isEmpty());

    dev->fill(QRect(10,10,10,10), KoColor(Qt::white, cs));

    QCOMPARE(dev->exactBounds(), QRect(10,10,10,10));

    const quint8 weirdPixelData[4] = {0,10,0,0};
    KoColor weirdColor(weirdPixelData, cs);
    dev->setPixel(6,6,weirdColor);

    // such weird pixels should not change our opinion about
    // device's size
    QCOMPARE(dev->exactBounds(), QRect(10,10,10,10));
}
Example #16
0
KisImageBuilder_Result CSVSaver::getLayer(CSVLayerRecord* layer, KisDocument* exportDoc, KisKeyframeSP keyframe, const QString &path, int frame, int idx)
{
    //render to the temp layer
    KisImageWSP image = exportDoc->image();
    KisPaintDeviceSP device = image->rootLayer()->firstChild()->projection();

    layer->channel->fetchFrame(keyframe, device);
    QRect bounds = device->exactBounds();

    if (bounds.isEmpty()) {
        layer->last = "";                   //empty frame
        return KisImageBuilder_RESULT_OK;
    }
    layer->last = QString("frame%1-%2.png").arg(idx + 1,5,10,QChar('0')).arg(frame,5,10,QChar('0'));

    QString filename = path;
    filename.append(layer->last);

    //save to PNG

    KisSequentialConstIterator it(device, image->bounds());
    const KoColorSpace* cs = device->colorSpace();

    bool isThereAlpha = false;
    do {
        if (cs->opacityU8(it.oldRawData()) != OPACITY_OPAQUE_U8) {
            isThereAlpha = true;
            break;
        }
    } while (it.nextPixel());

    if (!KisPNGConverter::isColorSpaceSupported(cs)) {
        device = new KisPaintDevice(*device.data());
        KUndo2Command *cmd= device->convertTo(KoColorSpaceRegistry::instance()->rgb8());
        delete cmd;
    }
    KisPNGOptions options;

    options.alpha = isThereAlpha;
    options.interlace = false;
    options.compression = 8;
    options.tryToSaveAsIndexed = false;
    options.transparencyFillColor = QColor(0,0,0);
    options.saveSRGBProfile = true;                 //TVPaint can use only sRGB
    options.forceSRGB = false;

    KisPNGConverter kpc(exportDoc);

    KisImageBuilder_Result result = kpc.buildFile(QUrl::fromLocalFile(filename), image->bounds(),
                                                  image->xRes(), image->yRes(), device,
                                                  image->beginAnnotations(), image->endAnnotations(),
                                                  options, (KisMetaData::Store* )0 );

    return result;
}
Example #17
0
void KisKraLoaderTest::testLoadAnimated()
{
    KisDocument *doc = KisPart::instance()->createDocument();
    doc->loadNativeFormat(QString(FILES_DATA_DIR) + QDir::separator() + "load_test_animation.kra");
    KisImageSP image = doc->image();

    KisNodeSP node1 = image->root()->firstChild();
    KisNodeSP node2 = node1->nextSibling();

    QVERIFY(node1->inherits("KisPaintLayer"));
    QVERIFY(node2->inherits("KisPaintLayer"));

    KisPaintLayerSP layer1 = qobject_cast<KisPaintLayer*>(node1.data());
    KisPaintLayerSP layer2 = qobject_cast<KisPaintLayer*>(node2.data());
    KisKeyframeChannel *channel1 = layer1->getKeyframeChannel(KisKeyframeChannel::Content.id());
    KisKeyframeChannel *channel2 = layer2->getKeyframeChannel(KisKeyframeChannel::Content.id());

    QCOMPARE(channel1->keyframeCount(), 3);
    QCOMPARE(channel2->keyframeCount(), 1);

    QCOMPARE(image->animationInterface()->framerate(), 17);
    QCOMPARE(image->animationInterface()->fullClipRange(), KisTimeRange::fromTime(15, 45));
    QCOMPARE(image->animationInterface()->currentTime(), 19);

    KisPaintDeviceSP dev = layer1->paintDevice();

    const KoColorSpace *cs = dev->colorSpace();
    KoColor transparent(Qt::transparent, cs);
    KoColor white(Qt::white, cs);
    KoColor red(Qt::red, cs);

    image->animationInterface()->switchCurrentTimeAsync(0);
    image->waitForDone();

    QCOMPARE(dev->exactBounds(), QRect(506, 378, 198, 198));
    QCOMPARE(dev->x(), -26);
    QCOMPARE(dev->y(), -128);
    QCOMPARE(dev->defaultPixel(), transparent);

    image->animationInterface()->switchCurrentTimeAsync(20);
    image->waitForDone();

    QCOMPARE(dev->nonDefaultPixelArea(), QRect(615, 416, 129, 129));
    QCOMPARE(dev->x(), 502);
    QCOMPARE(dev->y(), 224);
    QCOMPARE(dev->defaultPixel(), white);

    image->animationInterface()->switchCurrentTimeAsync(30);
    image->waitForDone();

    QCOMPARE(dev->nonDefaultPixelArea(), QRect(729, 452, 45, 44));
    QCOMPARE(dev->x(), 645);
    QCOMPARE(dev->y(), -10);
    QCOMPARE(dev->defaultPixel(), red);
}
Example #18
0
void KisPaintDeviceTest::testMoveWrapAround()
{
    const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = createWrapAroundPaintDevice(cs);

    KoColor c1(Qt::red, cs);
    KoColor c2(Qt::green, cs);

    dev->setPixel(3, 3, c1);
    dev->setPixel(18, 18, c2);

    // QRect rc = dev->defaultBounds()->bounds();

    //dev->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height()).save("move0.png");
    QCOMPARE(dev->exactBounds(), QRect(3,3,16,16));
    dev->move(QPoint(10,10));
    QCOMPARE(dev->exactBounds(), QRect(8,8,6,6));
    //dev->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height()).save("move1.png");

}
void KisSmallTilesFilter::process(KisConstProcessingInformation srcInfo,
                                  KisProcessingInformation dstInfo,
                                  const QSize& size,
                                  const KisFilterConfiguration* config,
                                  KoUpdater* progressUpdater
                                 ) const
{
    const KisPaintDeviceSP src = srcInfo.paintDevice();
    KisPaintDeviceSP dst = dstInfo.paintDevice();
    QPoint dstTopLeft = dstInfo.topLeft();
    QPoint srcTopLeft = srcInfo.topLeft();
    Q_ASSERT(!src.isNull());
    Q_ASSERT(!dst.isNull());

    //read the filter configuration values from the KisFilterConfiguration object
    quint32 numberOfTiles = config->getInt("numberOfTiles", 2);

    QRect srcRect = src->exactBounds();

    int w = static_cast<int>(srcRect.width() / numberOfTiles);
    int h = static_cast<int>(srcRect.height() / numberOfTiles);

    KisPaintDeviceSP tile = KisPaintDeviceSP(0);
    if (srcInfo.selection()) {
        KisPaintDeviceSP tmp = new KisPaintDevice(src->colorSpace());
        KisPainter gc(tmp);
        gc.setCompositeOp(COMPOSITE_COPY);
        gc.bitBlt(0, 0, src, srcTopLeft.x(), srcTopLeft.y(), size.width(), size.height());
        tile = tmp->createThumbnailDevice(srcRect.width() / numberOfTiles, srcRect.height() / numberOfTiles);
    } else {
        tile = src->createThumbnailDevice(srcRect.width() / numberOfTiles, srcRect.height() / numberOfTiles);
    }
    if (tile.isNull()) return;

    KisPainter gc(dst);
    gc.setCompositeOp(COMPOSITE_COPY);

    if (progressUpdater) {
        progressUpdater->setRange(0, numberOfTiles);
    }

    if (srcInfo.selection()) {
        gc.setSelection(srcInfo.selection());
    }

    for (uint y = 0; y < numberOfTiles; ++y) {
        for (uint x = 0; x < numberOfTiles; ++x) {
            gc.bitBlt(w * x, h * y, tile, 0, 0, w, h);
        }
        if (progressUpdater) progressUpdater->setValue(y);
    }
    gc.end();
}
Example #20
0
void KisPaintDeviceTest::benchmarkExactBoundsNullDefaultPixel()
{
    const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);

    QVERIFY(dev->exactBounds().isEmpty());

    QRect fillRect(60,60, 1930, 1930);

    dev->fill(fillRect, KoColor(Qt::white, cs));

    QRect measuredRect;

    QBENCHMARK {
        // invalidate the cache
        dev->setDirty();
        measuredRect = dev->exactBounds();
    }

    QCOMPARE(measuredRect, fillRect);
}
Example #21
0
void KisPaintDeviceTest::testGeometry()
{
    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);

    QCOMPARE(dev->exactBounds(), QRect(0, 0, 512, 512));
    QCOMPARE(dev->extent(), QRect(0, 0, 512, 512));

    dev->move(10, 10);

    QCOMPARE(dev->exactBounds(), QRect(10, 10, 512, 512));
    QCOMPARE(dev->extent(), QRect(10, 10, 512, 512));

    dev->crop(50, 50, 50, 50);
    QCOMPARE(dev->exactBounds(), QRect(50, 50, 50, 50));
    QCOMPARE(dev->extent(), QRect(10, 10, 128, 128));

    QColor c;

    dev->clear(QRect(50, 50, 50, 50));
    dev->pixel(80, 80, &c);
    QVERIFY(c.alpha() == OPACITY_TRANSPARENT_U8);

    dev->fill(0, 0, 512, 512, pixel);
    dev->pixel(80, 80, &c);
    QVERIFY(c == Qt::white);
    QVERIFY(c.alpha() == OPACITY_OPAQUE_U8);

    dev->clear();
    dev->pixel(80, 80, &c);
    QVERIFY(c.alpha() == OPACITY_TRANSPARENT_U8);

    QVERIFY(dev->extent().isEmpty());
    QVERIFY(dev->exactBounds().isEmpty());

}
Example #22
0
KisLevelConfigWidget::KisLevelConfigWidget(QWidget * parent, KisPaintDeviceSP dev)
        : KisConfigWidget(parent)
{
    m_page.setupUi(this);

    m_page.ingradient->enableGamma(true);
    m_page.blackspin->setValue(0);
    m_page.whitespin->setValue(255);
    m_page.gammaspin->setValue(1.0);
    m_page.ingradient->slotModifyGamma(1.0);
    m_page.outblackspin->setValue(0);
    m_page.outwhitespin->setValue(255);

    connect(m_page.blackspin, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged()));
    connect(m_page.whitespin, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged()));
    connect(m_page.ingradient, SIGNAL(sigModifiedGamma(double)), SIGNAL(sigConfigurationItemChanged()));

    connect(m_page.blackspin, SIGNAL(valueChanged(int)), m_page.ingradient, SLOT(slotModifyBlack(int)));
    connect(m_page.whitespin, SIGNAL(valueChanged(int)), m_page.ingradient, SLOT(slotModifyWhite(int)));
    connect(m_page.gammaspin, SIGNAL(valueChanged(double)), m_page.ingradient, SLOT(slotModifyGamma(double)));

    connect(m_page.blackspin, SIGNAL(valueChanged(int)), this, SLOT(slotModifyInWhiteLimit(int)));
    connect(m_page.whitespin, SIGNAL(valueChanged(int)), this, SLOT(slotModifyInBlackLimit(int)));

    connect(m_page.ingradient, SIGNAL(sigModifiedBlack(int)), m_page.blackspin, SLOT(setValue(int)));
    connect(m_page.ingradient, SIGNAL(sigModifiedWhite(int)), m_page.whitespin, SLOT(setValue(int)));
    connect(m_page.ingradient, SIGNAL(sigModifiedGamma(double)), m_page.gammaspin, SLOT(setValue(double)));


    connect(m_page.outblackspin, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged()));
    connect(m_page.outwhitespin, SIGNAL(valueChanged(int)), SIGNAL(sigConfigurationItemChanged()));

    connect(m_page.outblackspin, SIGNAL(valueChanged(int)), m_page.outgradient, SLOT(slotModifyBlack(int)));
    connect(m_page.outwhitespin, SIGNAL(valueChanged(int)), m_page.outgradient, SLOT(slotModifyWhite(int)));

    connect(m_page.outblackspin, SIGNAL(valueChanged(int)), this, SLOT(slotModifyOutWhiteLimit(int)));
    connect(m_page.outwhitespin, SIGNAL(valueChanged(int)), this, SLOT(slotModifyOutBlackLimit(int)));

    connect(m_page.outgradient, SIGNAL(sigModifiedBlack(int)), m_page.outblackspin, SLOT(setValue(int)));
    connect(m_page.outgradient, SIGNAL(sigModifiedWhite(int)), m_page.outwhitespin, SLOT(setValue(int)));

    connect(m_page.butauto, SIGNAL(clicked(bool)), this, SLOT(slotAutoLevel(void)));

    connect((QObject*)(m_page.chkLogarithmic), SIGNAL(toggled(bool)), this, SLOT(slotDrawHistogram(bool)));

    KoHistogramProducer *producer = new KoGenericLabHistogramProducer();
    m_histogram.reset( new KisHistogram(dev, dev->exactBounds(), producer, LINEAR) );
    m_histlog = false;
    m_page.histview->resize(288,100);
    slotDrawHistogram();

}
void KisTransformWorkerTest::testXScaleDown()
{
    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, 0.123, 1.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() == qRound(image.width() * 0.123));
    QVERIFY(rc.height() == image.height() - 1); // the height is reduced by 1 because in the source image
                                                // at the bottom line most pixels (except 1 or 2) are
                                                // entirely transparent.
                                                // when scaling down the image by ~ 1/10, the few non-tranparent
                                                // pixels disappear when "mixed" with the transparent ones
                                                // around

//    KisTransaction t2("test", dev);
//    KisRandomAccessorSP ac = dev->createRandomAccessorNG(rc.x(), rc.y());
//    for(int x = rc.x(); x < rc.width(); ++x) {
//        for(int y = rc.y(); y < rc.height(); ++y) {
//            ac->moveTo(x, y);
//            cs->setOpacity(ac->rawData(), 0.5, 1);
//        }
//    }
//    t2.end();

    QImage result = dev->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height());
    QPoint errpoint;
    image.load(QString(FILES_DATA_DIR) + QDir::separator() + "scaledownx_result.png");
    if (!TestUtil::compareQImages(errpoint, image, result)) {
        image.save("scaledownx_source.png");
        result.save("scaledownx_result.png");
        QFAIL(QString("Failed to scale down the image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toAscii());
    }
}
Example #24
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
}
KisPaintDeviceSP KisShearVisitor::yShear(KisPaintDeviceSP src, qreal shearY, KoUpdater *progress)
{
    int start = progress->progress();

    KisPaintDeviceSP dst = KisPaintDeviceSP(new KisPaintDevice(src->colorSpace()));
    KoMixColorsOp * mixOp = src->colorSpace()->mixColorsOp();

    dst->setX(src->x());
    dst->setY(src->y());

    QRect r = src->exactBounds();

    qreal displacement;
    qint32 displacementInt;
    qreal weight;

    for (qint32 x = r.left(); x <= r.right(); x++) {

        //calculate displacement
        displacement = x * shearY;

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

        qint16 pixelWeights[2];

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

        KisVLineConstIteratorPixel srcIt = src->createVLineIterator(x, r.y(), r.height() + 1);
        KisVLineIteratorPixel leftSrcIt = src->createVLineIterator(x, r.y() - 1, r.height() + 1);
        KisVLineIteratorPixel dstIt = dst->createVLineIterator(x, r.y() + displacementInt, r.height() + 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(start + x);
    }
    return dst;
}
Example #26
0
void KisPaintDeviceTest::testCaching()
{
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP dev = new KisPaintDevice(cs);

    quint8* whitePixel = new quint8[cs->pixelSize()];
    cs->fromQColor(Qt::white, whitePixel);

    quint8* blackPixel = new quint8[cs->pixelSize()];
    cs->fromQColor(Qt::black, blackPixel);

    dev->fill(0, 0, 512, 512, whitePixel);
    QImage thumb1 = dev->createThumbnail(50, 50);
    QRect exactBounds1 = dev->exactBounds();

    dev->fill(0, 0, 768, 768, blackPixel);
    QImage thumb2 = dev->createThumbnail(50, 50);
    QRect exactBounds2 = dev->exactBounds();

    dev->move(10, 10);
    QImage thumb3 = dev->createThumbnail(50, 50);
    QRect exactBounds3 = dev->exactBounds();

    dev->crop(50, 50, 50, 50);
    QImage thumb4 = dev->createThumbnail(50, 50);
    QRect exactBounds4 = dev->exactBounds();

    QVERIFY(thumb1 != thumb2);
    QVERIFY(thumb2 == thumb3); // Cache miss, but image is the same
    QVERIFY(thumb3 != thumb4);
    QVERIFY(thumb4 != thumb1);

    QCOMPARE(exactBounds1, QRect(0,0,512,512));
    QCOMPARE(exactBounds2, QRect(0,0,768,768));
    QCOMPARE(exactBounds3, QRect(10,10,768,768));
    QCOMPARE(exactBounds4, QRect(50,50,50,50));
}
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;
}
Example #28
0
void KisPaintDeviceTest::testSharedDataManager()
{
    QRect fillRect(0,0,100,100);
    quint8 fillPixel[4]={255,255,255,255};
    QRect clearRect(10,10,20,20);
    QImage srcImage;
    QImage dstImage;

    const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP srcDevice = new KisPaintDevice(cs);

    srcDevice->setX(10);
    srcDevice->setY(20);

    srcDevice->fill(fillRect.left(), fillRect.top(),
                 fillRect.width(), fillRect.height(),fillPixel);

    KisPaintDeviceSP dstDevice = new KisPaintDevice(srcDevice->dataManager(), srcDevice);


    QVERIFY(srcDevice->extent() == dstDevice->extent());
    QVERIFY(srcDevice->exactBounds() == dstDevice->exactBounds());
    QVERIFY(srcDevice->defaultBounds() == dstDevice->defaultBounds());
    QVERIFY(srcDevice->x() == dstDevice->x());
    QVERIFY(srcDevice->y() == dstDevice->y());

    srcImage = srcDevice->convertToQImage(0);
    dstImage = dstDevice->convertToQImage(0);
    QVERIFY(srcImage == dstImage);

    srcDevice->clear(clearRect);

    srcImage = srcDevice->convertToQImage(0);
    dstImage = dstDevice->convertToQImage(0);
    QVERIFY(srcImage == dstImage);
}
Example #29
0
void KisPaintDeviceTest::testTranslate()
{
    QRect fillRect(0,0,64,64);
    quint8 fillPixel[4]={255,255,255,255};

    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisPaintDeviceSP device = new KisPaintDevice(cs);

    device->fill(fillRect.left(), fillRect.top(),
                 fillRect.width(), fillRect.height(),fillPixel);

    device->setX(-10);
    device->setY(10);
    QCOMPARE(device->exactBounds(), QRect(-10,10,64,64));
    QCOMPARE(device->extent(), QRect(-10,10,64,64));
}
Example #30
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;
}