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