KisPaintDeviceSP TransformStrokeStrategy::getDeviceCache(KisPaintDeviceSP src)
{
    QMutexLocker l(&m_devicesCacheMutex);
    KisPaintDeviceSP cache = m_devicesCacheHash.value(src.data());
    if (!cache) {
        warnKrita << "WARNING: Transform Stroke: the device is absent in cache!";
    }

    return cache;
}
Beispiel #2
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;
}
Beispiel #3
0
void KisFilterWave::processImpl(KisPaintDeviceSP device,
                                const QRect& applyRect,
                                const KisFilterConfiguration* config,
                                KoUpdater* progressUpdater
                                ) const
{
    Q_ASSERT(device.data() != 0);

    int cost = (applyRect.width() * applyRect.height()) / 100;
    if (cost == 0) cost = 1;
    int count = 0;

    QVariant value;
    int horizontalwavelength = (config && config->getProperty("horizontalwavelength", value)) ? value.toInt() : 50;
    int horizontalshift = (config && config->getProperty("horizontalshift", value)) ? value.toInt() : 50;
    int horizontalamplitude = (config && config->getProperty("horizontalamplitude", value)) ? value.toInt() : 4;
    int horizontalshape = (config && config->getProperty("horizontalshape", value)) ? value.toInt() : 0;
    int verticalwavelength = (config && config->getProperty("verticalwavelength", value)) ? value.toInt() : 50;
    int verticalshift = (config && config->getProperty("verticalshift", value)) ? value.toInt() : 50;
    int verticalamplitude = (config && config->getProperty("verticalamplitude", value)) ? value.toInt() : 4;
    int verticalshape = (config && config->getProperty("verticalshape", value)) ? value.toInt() : 0;
    KisSequentialIterator dstIt(device, applyRect);
    KisWaveCurve* verticalcurve;
    if (verticalshape == 1)
        verticalcurve = new KisTriangleWaveCurve(verticalamplitude, verticalwavelength, verticalshift);
    else
        verticalcurve = new KisSinusoidalWaveCurve(verticalamplitude, verticalwavelength, verticalshift);
    KisWaveCurve* horizontalcurve;
    if (horizontalshape == 1)
        horizontalcurve = new KisTriangleWaveCurve(horizontalamplitude, horizontalwavelength, horizontalshift);
    else
        horizontalcurve = new KisSinusoidalWaveCurve(horizontalamplitude, horizontalwavelength, horizontalshift);
    
    KisRandomSubAccessorSP srcRSA = device->createRandomSubAccessor();
    do {
        double xv = horizontalcurve->valueAt(dstIt.y(), dstIt.x());
        double yv = verticalcurve->valueAt(dstIt.x(), dstIt.y());
        srcRSA->moveTo(QPointF(xv, yv));
        srcRSA->sampledOldRawData(dstIt.rawData());
        if (progressUpdater) progressUpdater->setProgress((++count) / cost);
    } while (dstIt.nextPixel());
    delete horizontalcurve;
    delete verticalcurve;
}
Beispiel #4
0
void checkReadWriteRoundTrip(KisPaintDeviceSP dev,
                             const QRect &rc)
{
    KisPaintDeviceSP deviceCopy = new KisPaintDevice(*dev.data());

    QRect readRect(10, 10, 20, 20);
    int bufSize = rc.width() * rc.height() * dev->pixelSize();

    QScopedPointer<quint8> buf1(new quint8[bufSize]);

    deviceCopy->readBytes(buf1.data(), rc);

    deviceCopy->clear();
    QVERIFY(deviceCopy->extent().isEmpty());


    QScopedPointer<quint8> buf2(new quint8[bufSize]);
    deviceCopy->writeBytes(buf1.data(), rc);
    deviceCopy->readBytes(buf2.data(), rc);

    QVERIFY(!memcmp(buf1.data(), buf2.data(), bufSize));
}
void TransformStrokeStrategy::putDeviceCache(KisPaintDeviceSP src, KisPaintDeviceSP cache)
{
    QMutexLocker l(&m_devicesCacheMutex);
    m_devicesCacheHash.insert(src.data(), cache);
}
bool TransformStrokeStrategy::haveDeviceInCache(KisPaintDeviceSP src)
{
    QMutexLocker l(&m_devicesCacheMutex);
    return m_devicesCacheHash.contains(src.data());
}
Beispiel #7
0
void KisFilterFastColorTransfer::processImpl(KisPaintDeviceSP device,
                                             const QRect& applyRect,
                                             const KisFilterConfiguration* config,
                                             KoUpdater* progressUpdater) const
{
    Q_ASSERT(device != 0);

    dbgPlugins << "Start transferring color";

    // Convert ref and src to LAB
    const KoColorSpace* labCS = KoColorSpaceRegistry::instance()->lab16();
    if (!labCS) {
        dbgPlugins << "The LAB colorspace is not available.";
        return;
    }
    
    dbgPlugins << "convert a copy of src to lab";
    const KoColorSpace* oldCS = device->colorSpace();
    KisPaintDeviceSP srcLAB = new KisPaintDevice(*device.data());
    dbgPlugins << "srcLab : " << srcLAB->extent();
    KUndo2Command* cmd = srcLAB->convertTo(labCS, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags());
    delete cmd;

    if (progressUpdater) {
        progressUpdater->setRange(0, 2 * applyRect.width() * applyRect.height());
    }
    int count = 0;

    // Compute the means and sigmas of src
    dbgPlugins << "Compute the means and sigmas of src";
    double meanL_src = 0., meanA_src = 0., meanB_src = 0.;
    double sigmaL_src = 0., sigmaA_src = 0., sigmaB_src = 0.;

    KisSequentialConstIterator srcIt(srcLAB, applyRect);

    do {
        const quint16* data = reinterpret_cast<const quint16*>(srcIt.oldRawData());
        quint32 L = data[0];
        quint32 A = data[1];
        quint32 B = data[2];
        meanL_src += L;
        meanA_src += A;
        meanB_src += B;
        sigmaL_src += L * L;
        sigmaA_src += A * A;
        sigmaB_src += B * B;
        if (progressUpdater) progressUpdater->setValue(++count);
    } while (srcIt.nextPixel() && !(progressUpdater && progressUpdater->interrupted()));
    
    double totalSize = 1. / (applyRect.width() * applyRect.height());
    meanL_src *= totalSize;
    meanA_src *= totalSize;
    meanB_src *= totalSize;
    sigmaL_src *= totalSize;
    sigmaA_src *= totalSize;
    sigmaB_src *= totalSize;
    
    dbgPlugins << totalSize << "" << meanL_src << "" << meanA_src << "" << meanB_src << "" << sigmaL_src << "" << sigmaA_src << "" << sigmaB_src;
    
    double meanL_ref = config->getDouble("meanL");
    double meanA_ref = config->getDouble("meanA");
    double meanB_ref = config->getDouble("meanB");
    double sigmaL_ref = config->getDouble("sigmaL");
    double sigmaA_ref = config->getDouble("sigmaA");
    double sigmaB_ref = config->getDouble("sigmaB");
    
    
    // Transfer colors
    dbgPlugins << "Transfer colors";
    {
        double coefL = sqrt((sigmaL_ref - meanL_ref * meanL_ref) / (sigmaL_src - meanL_src * meanL_src));
        double coefA = sqrt((sigmaA_ref - meanA_ref * meanA_ref) / (sigmaA_src - meanA_src * meanA_src));
        double coefB = sqrt((sigmaB_ref - meanB_ref * meanB_ref) / (sigmaB_src - meanB_src * meanB_src));
        KisHLineConstIteratorSP srcLABIt = srcLAB->createHLineConstIteratorNG(applyRect.x(), applyRect.y(), applyRect.width());
        KisHLineIteratorSP dstIt = device->createHLineIteratorNG(applyRect.x(), applyRect.y(), applyRect.width());
        quint16 labPixel[4];
        for (int y = 0; y < applyRect.height() && !(progressUpdater && progressUpdater->interrupted()); ++y) {
            do {
                const quint16* data = reinterpret_cast<const quint16*>(srcLABIt->oldRawData());
                labPixel[0] = (quint16)CLAMP(((double)data[0] - meanL_src) * coefL + meanL_ref, 0., 65535.);
                labPixel[1] = (quint16)CLAMP(((double)data[1] - meanA_src) * coefA + meanA_ref, 0., 65535.);
                labPixel[2] = (quint16)CLAMP(((double)data[2] - meanB_src) * coefB + meanB_ref, 0., 65535.);
                labPixel[3] = data[3];
                oldCS->fromLabA16(reinterpret_cast<const quint8*>(labPixel), dstIt->rawData(), 1);
                if (progressUpdater) progressUpdater->setValue(++count);
                srcLABIt->nextPixel();
            } while(dstIt->nextPixel());
            dstIt->nextRow();
            srcLABIt->nextRow();
        }

    }
}