diff --git a/libs/image/tests/CMakeLists.txt b/libs/image/tests/CMakeLists.txt index 5a5626300d..87eb8fe297 100644 --- a/libs/image/tests/CMakeLists.txt +++ b/libs/image/tests/CMakeLists.txt @@ -1,239 +1,239 @@ # cmake in some versions for some not yet known reasons fails to run automoc # on random targets (changing target names already has an effect) # As temporary workaround skipping build of tests on these versions for now # See https://mail.kde.org/pipermail/kde-buildsystem/2015-June/010819.html # extend range of affected cmake versions as needed if(NOT ${CMAKE_VERSION} VERSION_LESS 3.1.3 AND NOT ${CMAKE_VERSION} VERSION_GREATER 3.2.3) message(WARNING "Skipping krita/image/tests, CMake in at least versions 3.1.3 - 3.2.3 seems to have a problem with automoc. \n(FRIENDLY REMINDER: PLEASE DON'T BREAK THE TESTS!)") set (HAVE_FAILING_CMAKE TRUE) else() set (HAVE_FAILING_CMAKE FALSE) endif() include_directories( ${CMAKE_SOURCE_DIR}/libs/image/metadata ${CMAKE_BINARY_DIR}/libs/image/ ${CMAKE_SOURCE_DIR}/libs/image/ ${CMAKE_SOURCE_DIR}/libs/image/brushengine ${CMAKE_SOURCE_DIR}/libs/image/tiles3 ${CMAKE_SOURCE_DIR}/libs/image/tiles3/swap ${CMAKE_SOURCE_DIR}/sdk/tests ) include_Directories(SYSTEM ${EIGEN3_INCLUDE_DIR} ) if(HAVE_VC) include_directories(${Vc_INCLUDE_DIR}) endif() include(ECMAddTests) include(KritaAddBrokenUnitTest) macro_add_unittest_definitions() set(KisRandomGeneratorDemoSources kis_random_generator_demo.cpp kimageframe.cpp) ki18n_wrap_ui(KisRandomGeneratorDemoSources kis_random_generator_demo.ui) add_executable(KisRandomGeneratorDemo ${KisRandomGeneratorDemoSources}) target_link_libraries(KisRandomGeneratorDemo kritaimage) ecm_mark_as_test(KisRandomGeneratorDemo) ecm_add_tests( kis_base_node_test.cpp kis_fast_math_test.cpp kis_node_test.cpp kis_node_facade_test.cpp kis_fixed_paint_device_test.cpp kis_layer_test.cpp kis_effect_mask_test.cpp kis_iterator_test.cpp kis_painter_test.cpp kis_selection_test.cpp kis_count_visitor_test.cpp kis_projection_test.cpp kis_properties_configuration_test.cpp kis_transaction_test.cpp kis_pixel_selection_test.cpp kis_group_layer_test.cpp kis_paint_layer_test.cpp kis_adjustment_layer_test.cpp kis_annotation_test.cpp kis_change_profile_visitor_test.cpp kis_clone_layer_test.cpp kis_colorspace_convert_visitor_test.cpp kis_convolution_painter_test.cpp kis_crop_processing_visitor_test.cpp kis_processing_applicator_test.cpp kis_datamanager_test.cpp kis_fill_painter_test.cpp kis_filter_configuration_test.cpp kis_filter_test.cpp kis_filter_processing_information_test.cpp kis_filter_registry_test.cpp kis_filter_strategy_test.cpp kis_gradient_painter_test.cpp kis_image_commands_test.cpp kis_image_test.cpp kis_image_signal_router_test.cpp kis_iterators_ng_test.cpp kis_iterator_benchmark.cpp kis_updater_context_test.cpp kis_simple_update_queue_test.cpp kis_stroke_test.cpp kis_simple_stroke_strategy_test.cpp kis_stroke_strategy_undo_command_based_test.cpp kis_strokes_queue_test.cpp kis_mask_test.cpp kis_math_toolbox_test.cpp kis_name_server_test.cpp kis_node_commands_test.cpp kis_node_graph_listener_test.cpp kis_node_visitor_test.cpp kis_paint_information_test.cpp kis_distance_information_test.cpp kis_paintop_test.cpp kis_pattern_test.cpp kis_selection_mask_test.cpp kis_shared_ptr_test.cpp kis_bsplines_test.cpp kis_warp_transform_worker_test.cpp kis_liquify_transform_worker_test.cpp kis_transparency_mask_test.cpp kis_types_test.cpp kis_vec_test.cpp kis_filter_config_widget_test.cpp kis_mask_generator_test.cpp kis_cubic_curve_test.cpp kis_fixed_point_maths_test.cpp kis_node_query_path_test.cpp kis_filter_weights_buffer_test.cpp kis_filter_weights_applicator_test.cpp kis_fill_interval_test.cpp kis_fill_interval_map_test.cpp kis_scanline_fill_test.cpp kis_psd_layer_style_test.cpp kis_layer_style_projection_plane_test.cpp kis_lod_capable_layer_offset_test.cpp kis_algebra_2d_test.cpp kis_marker_painter_test.cpp kis_lazy_brush_test.cpp kis_colorize_mask_test.cpp kis_mask_similarity_test.cpp KisMaskGeneratorBenchmark.cpp NAME_PREFIX "krita-image-" LINK_LIBRARIES kritaimage Qt5::Test) ecm_add_test(kis_layer_style_filter_environment_test.cpp TEST_NAME kritaimage-layer_style_filter_environment_test LINK_LIBRARIES ${KDE4_KDEUI_LIBS} kritaimage Qt5::Test) ecm_add_test(kis_asl_parser_test.cpp TEST_NAME kritalibpsd-asl_parser_test LINK_LIBRARIES kritapsd kritapigment kritawidgetutils kritacommand Qt5::Xml Qt5::Test) ecm_add_test(KisPerStrokeRandomSourceTest.cpp TEST_NAME KisPerStrokeRandomSourceTest LINK_LIBRARIES kritaimage Qt5::Test) ecm_add_test(KisWatershedWorkerTest.cpp TEST_NAME KisWatershedWorkerTest LINK_LIBRARIES kritaimage Qt5::Test) ecm_add_test(kis_dom_utils_test.cpp TEST_NAME krita-image-KisDomUtilsTest LINK_LIBRARIES kritaimage Qt5::Test) ecm_add_test(kis_transform_worker_test.cpp TEST_NAME krita-image-KisTransformWorkerTest LINK_LIBRARIES kritaimage Qt5::Test) ecm_add_test(kis_perspective_transform_worker_test.cpp TEST_NAME krita-image-KisPerspectiveTransformWorkerTest LINK_LIBRARIES kritaimage Qt5::Test) ecm_add_test(kis_cs_conversion_test.cpp TEST_NAME krita-image-KisCsConversionTest LINK_LIBRARIES kritaimage Qt5::Test) ecm_add_test(kis_processings_test.cpp TEST_NAME krita-image-KisProcessingsTest LINK_LIBRARIES kritaimage Qt5::Test) ecm_add_test(kis_projection_leaf_test.cpp TEST_NAME KisProjectionLeafTest LINK_LIBRARIES kritaimage Qt5::Test) if (NOT HAVE_FAILING_CMAKE) krita_add_broken_unit_test(kis_paint_device_test.cpp TEST_NAME krita-image-KisPaintDeviceTest LINK_LIBRARIES kritaimage kritaodf Qt5::Test) else() message(WARNING "Skipping KisPaintDeviceTest!!!!!!!!!!!!!!") endif() if (NOT HAVE_FAILING_CMAKE) krita_add_broken_unit_test(kis_filter_mask_test.cpp TEST_NAME krita-image-KisFilterMaskTest LINK_LIBRARIES kritaimage Qt5::Test) else() message(WARNING "Skipping KisFilterMaskTest!!!!!!!!!!!!!!") endif() krita_add_broken_unit_test(kis_transform_mask_test.cpp TEST_NAME krita-image-KisTransformMaskTest LINK_LIBRARIES kritaimage Qt5::Test) -krita_add_broken_unit_test(kis_histogram_test.cpp +ecm_add_test(kis_histogram_test.cpp TEST_NAME krita-image-KisHistogramTest LINK_LIBRARIES kritaimage Qt5::Test) krita_add_broken_unit_test(kis_walkers_test.cpp TEST_NAME krita-image-KisWalkersTest LINK_LIBRARIES kritaimage Qt5::Test) #krita_add_broken_unit_test(kis_async_merger_test.cpp # TEST_NAME krita-image-KisAsyncMergerTest # LINK_LIBRARIES kritaimage Qt5::Test) krita_add_broken_unit_test(kis_update_scheduler_test.cpp TEST_NAME krita-image-KisUpdateSchedulerTest LINK_LIBRARIES kritaimage Qt5::Test) krita_add_broken_unit_test(kis_queues_progress_updater_test.cpp TEST_NAME krita-image-KisQueuesProgressUpdaterTest LINK_LIBRARIES kritaimage Qt5::Test) krita_add_broken_unit_test(kis_cage_transform_worker_test.cpp TEST_NAME krita-image-KisCageTransformWorkerTest LINK_LIBRARIES kritaimage Qt5::Test) krita_add_broken_unit_test(kis_meta_data_test.cpp TEST_NAME krita-image-KisMetaDataTest LINK_LIBRARIES kritaimage Qt5::Test) krita_add_broken_unit_test(kis_random_generator_test.cpp TEST_NAME krita-image-KisRandomGeneratorTest LINK_LIBRARIES kritaimage Qt5::Test) krita_add_broken_unit_test(kis_keyframing_test.cpp TEST_NAME krita-image-Keyframing-Test LINK_LIBRARIES kritaimage Qt5::Test) krita_add_broken_unit_test(kis_image_animation_interface_test.cpp TEST_NAME krita-image-ImageAnimationInterface-Test LINK_LIBRARIES ${KDE4_KDEUI_LIBS} kritaimage Qt5::Test) -krita_add_broken_unit_test(kis_onion_skin_compositor_test.cpp +ecm_add_test(kis_onion_skin_compositor_test.cpp TEST_NAME krita-image-OnionSkinCompositor-Test LINK_LIBRARIES ${KDE4_KDEUI_LIBS} kritaimage Qt5::Test) krita_add_broken_unit_test(kis_layer_styles_test.cpp TEST_NAME krita-image-LayerStylesTest LINK_LIBRARIES kritaimage Qt5::Test) diff --git a/libs/image/tests/kis_cage_transform_worker_test.cpp b/libs/image/tests/kis_cage_transform_worker_test.cpp index 8cbbc7a9ed..a00dda8c2c 100644 --- a/libs/image/tests/kis_cage_transform_worker_test.cpp +++ b/libs/image/tests/kis_cage_transform_worker_test.cpp @@ -1,330 +1,330 @@ /* * Copyright (c) 2014 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_cage_transform_worker_test.h" #include #include #include #include "testutil.h" #include #include void testCage(bool clockwise, bool unityTransform, bool benchmarkPrepareOnly = false, int pixelPrecision = 8, bool testQImage = false) { TestUtil::TestProgressBar bar; KoProgressUpdater pu(&bar); KoUpdaterPtr updater = pu.startSubtask(); const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(); QImage image(TestUtil::fetchDataFileLazy("test_cage_transform.png")); KisPaintDeviceSP dev = new KisPaintDevice(cs); dev->convertFromQImage(image, 0); QVector origPoints; QVector transfPoints; QRectF bounds(dev->exactBounds()); origPoints << bounds.topLeft(); origPoints << 0.5 * (bounds.topLeft() + bounds.topRight()); origPoints << 0.5 * (bounds.topLeft() + bounds.bottomRight()); origPoints << 0.5 * (bounds.topRight() + bounds.bottomRight()); origPoints << bounds.bottomRight(); origPoints << bounds.bottomLeft(); if (!clockwise) { std::reverse(origPoints.begin(), origPoints.end()); } if (unityTransform) { transfPoints = origPoints; } else { transfPoints << bounds.topLeft(); transfPoints << 0.5 * (bounds.topLeft() + bounds.topRight()); transfPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight()); transfPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight()) + (bounds.bottomLeft() - bounds.topLeft()); transfPoints << bounds.bottomLeft() + (bounds.bottomLeft() - bounds.topLeft()); transfPoints << bounds.bottomLeft(); if (!clockwise) { std::reverse(transfPoints.begin(), transfPoints.end()); } } KisCageTransformWorker worker(dev, origPoints, updater, pixelPrecision); QImage result; QPointF srcQImageOffset(0, 0); QPointF dstQImageOffset; QBENCHMARK_ONCE { if (!testQImage) { worker.prepareTransform(); if (!benchmarkPrepareOnly) { worker.setTransformedCage(transfPoints); worker.run(); } } else { - QImage srcImage(image); - image = QImage(image.size(), QImage::Format_ARGB32); - QPainter gc(&image); + QImage srcImage = image; + QImage image2 = QImage(image.size(), QImage::Format_ARGB32); + QPainter gc(&image2); gc.drawImage(QPoint(), srcImage); - - image = image.convertToFormat(QImage::Format_ARGB32); + gc.end(); + image = image2; KisCageTransformWorker qimageWorker(image, srcQImageOffset, origPoints, updater, pixelPrecision); qimageWorker.prepareTransform(); qimageWorker.setTransformedCage(transfPoints); result = qimageWorker.runOnQImage(&dstQImageOffset); } } QString testName = QString("%1_%2") .arg(clockwise ? "clk" : "cclk") .arg(unityTransform ? "unity" : "normal"); if (testQImage) { QVERIFY(TestUtil::checkQImage(result, "cage_transform_test", "cage_qimage", testName)); } else if (!benchmarkPrepareOnly && pixelPrecision == 8) { result = dev->convertToQImage(0); QVERIFY(TestUtil::checkQImage(result, "cage_transform_test", "cage", testName)); } } void KisCageTransformWorkerTest::testCageClockwise() { testCage(true, false); } void KisCageTransformWorkerTest::testCageClockwisePrepareOnly() { testCage(true, false, true); } void KisCageTransformWorkerTest::testCageClockwisePixePrecision4() { testCage(true, false, false, 4); } void KisCageTransformWorkerTest::testCageClockwisePixePrecision8QImage() { testCage(true, false, false, 8, true); } void KisCageTransformWorkerTest::testCageCounterclockwise() { testCage(false, false); } void KisCageTransformWorkerTest::testCageClockwiseUnity() { testCage(true, true); } void KisCageTransformWorkerTest::testCageCounterclockwiseUnity() { testCage(false, true); } #include QPointF generatePoint(const QRectF &rc) { qreal cx = qreal(qrand()) / RAND_MAX; qreal cy = qreal(qrand()) / RAND_MAX; QPointF diff = rc.bottomRight() - rc.topLeft(); QPointF pt = rc.topLeft() + QPointF(cx * diff.x(), cy * diff.y()); return pt; } void KisCageTransformWorkerTest::stressTestRandomCages() { TestUtil::TestProgressBar bar; KoProgressUpdater pu(&bar); KoUpdaterPtr updater = pu.startSubtask(); const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(); QImage image(TestUtil::fetchDataFileLazy("test_cage_transform.png")); KisPaintDeviceSP dev = new KisPaintDevice(cs); dev->convertFromQImage(image, 0); const int pixelPrecision = 8; QRectF bounds(dev->exactBounds()); qsrand(1); for (int numPoints = 4; numPoints < 15; numPoints+=5) { for (int j = 0; j < 200; j++) { QVector origPoints; QVector transfPoints; dbgKrita << ppVar(j); for (int i = 0; i < numPoints; i++) { origPoints << generatePoint(bounds); transfPoints << generatePoint(bounds); } // no just hope it doesn't crash ;) KisCageTransformWorker worker(dev, origPoints, updater, pixelPrecision); worker.prepareTransform(); worker.setTransformedCage(transfPoints); worker.run(); } } } #include "kis_green_coordinates_math.h" void KisCageTransformWorkerTest::testUnityGreenCoordinates() { QVector origPoints; QVector transfPoints; QRectF bounds(0,0,300,300); origPoints << bounds.topLeft(); origPoints << 0.5 * (bounds.topLeft() + bounds.topRight()); origPoints << 0.5 * (bounds.topLeft() + bounds.bottomRight()); origPoints << 0.5 * (bounds.topRight() + bounds.bottomRight()); origPoints << bounds.bottomRight(); origPoints << bounds.bottomLeft(); transfPoints = origPoints; QVector points; points << QPointF(10,10); points << QPointF(140,10); points << QPointF(140,140); points << QPointF(10,140); points << QPointF(10,160); points << QPointF(140,160); points << QPointF(140,290); points << QPointF(10,290); points << QPointF(160,160); points << QPointF(290,160); points << QPointF(290,290); points << QPointF(160,290); KisGreenCoordinatesMath cage; cage.precalculateGreenCoordinates(origPoints, points); cage.generateTransformedCageNormals(transfPoints); QVector newPoints; for (int i = 0; i < points.size(); i++) { newPoints << cage.transformedPoint(i, transfPoints); QCOMPARE(points[i], newPoints.last()); } } #include "kis_algebra_2d.h" void KisCageTransformWorkerTest::testTransformAsBase() { QPointF t(1.0, 0.0); QPointF b1(1.0, 0.0); QPointF b2(2.0, 0.0); QPointF result; t = QPointF(1.0, 0.0); b1 = QPointF(1.0, 0.0); b2 = QPointF(2.0, 0.0); result = KisAlgebra2D::transformAsBase(t, b1, b2); QCOMPARE(result, QPointF(2.0, 0.0)); t = QPointF(1.0, 0.0); b1 = QPointF(1.0, 0.0); b2 = QPointF(0.0, 1.0); result = KisAlgebra2D::transformAsBase(t, b1, b2); QCOMPARE(result, QPointF(0.0, 1.0)); t = QPointF(1.0, 0.0); b1 = QPointF(1.0, 0.0); b2 = QPointF(0.0, 2.0); result = KisAlgebra2D::transformAsBase(t, b1, b2); QCOMPARE(result, QPointF(0.0, 2.0)); t = QPointF(0.0, 1.0); b1 = QPointF(1.0, 0.0); b2 = QPointF(2.0, 0.0); result = KisAlgebra2D::transformAsBase(t, b1, b2); QCOMPARE(result, QPointF(0.0, 2.0)); t = QPointF(0.0, 1.0); b1 = QPointF(1.0, 0.0); b2 = QPointF(0.0, 1.0); result = KisAlgebra2D::transformAsBase(t, b1, b2); QCOMPARE(result, QPointF(-1.0, 0.0)); t = QPointF(0.0, 1.0); b1 = QPointF(1.0, 0.0); b2 = QPointF(0.0, 2.0); result = KisAlgebra2D::transformAsBase(t, b1, b2); QCOMPARE(result, QPointF(-2.0, 0.0)); } void KisCageTransformWorkerTest::testAngleBetweenVectors() { QPointF b1(1.0, 0.0); QPointF b2(2.0, 0.0); qreal result; b1 = QPointF(1.0, 0.0); b2 = QPointF(0.0, 1.0); result = KisAlgebra2D::angleBetweenVectors(b1, b2); QCOMPARE(result, M_PI_2); b1 = QPointF(1.0, 0.0); b2 = QPointF(std::sqrt(0.5), std::sqrt(0.5)); result = KisAlgebra2D::angleBetweenVectors(b1, b2); QCOMPARE(result, M_PI / 4); QTransform t; t.rotateRadians(M_PI / 4); QCOMPARE(t.map(b1), b2); } QTEST_MAIN(KisCageTransformWorkerTest) diff --git a/libs/image/tests/kis_histogram_test.cpp b/libs/image/tests/kis_histogram_test.cpp index 3f619776d8..e71f09d1ff 100644 --- a/libs/image/tests/kis_histogram_test.cpp +++ b/libs/image/tests/kis_histogram_test.cpp @@ -1,49 +1,50 @@ /* * Copyright (c) 2007 Boudewijn Rempt boud@valdyas.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_histogram_test.h" #include #include #include #include #include "kis_paint_device.h" #include "kis_histogram.h" #include "kis_paint_layer.h" #include "kis_types.h" +#include "kistest.h" void KisHistogramTest::testCreation() { const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP dev = new KisPaintDevice(cs); QList producers = KoHistogramProducerFactoryRegistry::instance()->keysCompatibleWith(cs); Q_FOREACH (const QString &id, producers) { if (id.contains("YCBCR")) { continue; } KoHistogramProducer *producer = KoHistogramProducerFactoryRegistry::instance()->get(id)->generate(); if (producer) { KisHistogram test(dev, QRect(0, 0, 100, 100), producer, LINEAR); Q_UNUSED(test); } - delete producer; + //delete producer; } } -QTEST_MAIN(KisHistogramTest) +KISTEST_MAIN(KisHistogramTest) diff --git a/libs/image/tests/kis_onion_skin_compositor_test.cpp b/libs/image/tests/kis_onion_skin_compositor_test.cpp index 11e025740a..75bb2b28f1 100644 --- a/libs/image/tests/kis_onion_skin_compositor_test.cpp +++ b/libs/image/tests/kis_onion_skin_compositor_test.cpp @@ -1,191 +1,207 @@ /* * Copyright (c) 2015 Jouni Pentikäinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_onion_skin_compositor_test.h" #include #include "kis_onion_skin_compositor.h" #include "kis_paint_device.h" #include "kis_raster_keyframe_channel.h" #include "kis_image_animation_interface.h" #include "testutil.h" #include "KoColor.h" #include "kis_image_config.h" void KisOnionSkinCompositorTest::testComposite() { KisImageConfig config(false); config.setOnionSkinTintFactor(64); config.setOnionSkinTintColorBackward(Qt::blue); config.setOnionSkinTintColorForward(Qt::red); config.setNumberOfOnionSkins(1); config.setOnionSkinOpacity(-1, 128); config.setOnionSkinOpacity(1, 128); KisOnionSkinCompositor *compositor = KisOnionSkinCompositor::instance(); TestUtil::MaskParent p; KisImageAnimationInterface *i = p.image->animationInterface(); KisPaintDeviceSP paintDevice = p.layer->paintDevice(); + paintDevice->createKeyframeChannel(KoID()); KisKeyframeChannel *keyframes = paintDevice->keyframeChannel(); keyframes->addKeyframe(0); keyframes->addKeyframe(10); keyframes->addKeyframe(20); paintDevice->fill(QRect(0,0,256,512), KoColor(Qt::red, paintDevice->colorSpace())); i->switchCurrentTimeAsync(10); p.image->waitForDone(); paintDevice->fill(QRect(0,0,512,256), KoColor(Qt::green, paintDevice->colorSpace())); i->switchCurrentTimeAsync(20); p.image->waitForDone(); paintDevice->fill(QRect(0,256,512,256), KoColor(Qt::blue, paintDevice->colorSpace())); KisPaintDeviceSP compositeDevice = new KisPaintDevice(p.image->colorSpace()); KisPaintDeviceSP expectedComposite = new KisPaintDevice(p.image->colorSpace()); // Frame 0 i->switchCurrentTimeAsync(0); p.image->waitForDone(); compositor->composite(paintDevice, compositeDevice, QRect(0,0,512,512)); expectedComposite->fill(QRect(256,0,256,256), KoColor(QColor(64, 191, 0, 128), paintDevice->colorSpace())); expectedComposite->fill(QRect(0,0,256,512), KoColor(Qt::red, paintDevice->colorSpace())); QImage result = compositeDevice->createThumbnail(64, 64); QImage expected = expectedComposite->createThumbnail(64, 64); - QVERIFY(result == expected); + QPoint errpoint; + if (!TestUtil::compareQImages(errpoint, result, expected)) { + result.save("result_1.png"); + expected.save("expected_1.png"); + QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1()); + } // Frame 10 i->switchCurrentTimeAsync(10); p.image->waitForDone(); compositor->composite(paintDevice, compositeDevice, QRect(0,0,512,512)); expectedComposite->clear(); expectedComposite->fill(QRect(0,256,256,256), KoColor(QColor(106, 0, 149, 192), paintDevice->colorSpace())); expectedComposite->fill(QRect(256,256,256,256), KoColor(QColor(64, 0, 191, 128), paintDevice->colorSpace())); expectedComposite->fill(QRect(0,0,512,256), KoColor(Qt::green, paintDevice->colorSpace())); result = compositeDevice->createThumbnail(64, 64); expected = expectedComposite->createThumbnail(64, 64); - QVERIFY(result == expected); + if (!TestUtil::compareQImages(errpoint, result, expected)) { + QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1()); + } // Frame 20 i->switchCurrentTimeAsync(20); p.image->waitForDone(); compositor->composite(paintDevice, compositeDevice, QRect(0,0,512,512)); expectedComposite->clear(); expectedComposite->fill(QRect(0,0,512,256), KoColor(QColor(0, 191, 64, 128), paintDevice->colorSpace())); expectedComposite->fill(QRect(0,256,512,256), KoColor(Qt::blue, paintDevice->colorSpace())); result = compositeDevice->createThumbnail(64, 64); expected = expectedComposite->createThumbnail(64, 64); QVERIFY(result == expected); } void KisOnionSkinCompositorTest::testSettings() { KisOnionSkinCompositor *compositor = KisOnionSkinCompositor::instance(); TestUtil::MaskParent p; KisImageAnimationInterface *i = p.image->animationInterface(); KisPaintDeviceSP paintDevice = p.layer->paintDevice(); + paintDevice->createKeyframeChannel(KoID()); KisKeyframeChannel *keyframes = paintDevice->keyframeChannel(); keyframes->addKeyframe(0); keyframes->addKeyframe(1); keyframes->addKeyframe(2); keyframes->addKeyframe(3); paintDevice->fill(QRect(0,0,512,512), KoColor(Qt::red, paintDevice->colorSpace())); i->switchCurrentTimeAsync(2); p.image->waitForDone(); paintDevice->fill(QRect(0,0,512,512), KoColor(Qt::green, paintDevice->colorSpace())); i->switchCurrentTimeAsync(3); p.image->waitForDone(); paintDevice->fill(QRect(0,0,512,512), KoColor(Qt::blue, paintDevice->colorSpace())); i->switchCurrentTimeAsync(1); p.image->waitForDone(); KisImageConfig config(false); config.setOnionSkinOpacity(-1, 32); config.setOnionSkinOpacity(1, 192); config.setOnionSkinOpacity(2, 64); config.setOnionSkinTintFactor(0); KisPaintDeviceSP compositeDevice = new KisPaintDevice(p.image->colorSpace()); KisPaintDeviceSP expectedComposite = new KisPaintDevice(p.image->colorSpace()); config.setNumberOfOnionSkins(1); compositor->configChanged(); expectedComposite->clear(); expectedComposite->fill(QRect(0,0,512,512), KoColor(QColor(10, 245, 0, 200), paintDevice->colorSpace())); QImage expected = expectedComposite->createThumbnail(64, 64); compositor->composite(paintDevice, compositeDevice, QRect(0,0,512,512)); QImage result = compositeDevice->createThumbnail(64, 64); - QVERIFY(result == expected); + QPoint errpoint; + if (!TestUtil::compareQImages(errpoint, result, expected)) { + QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1()); + } config.setNumberOfOnionSkins(2); compositor->configChanged(); expectedComposite->fill(QRect(0,0,512,512), KoColor(QColor(9, 229, 16, 214), paintDevice->colorSpace())); expected = expectedComposite->createThumbnail(64, 64); compositor->composite(paintDevice, compositeDevice, QRect(0,0,512,512)); result = compositeDevice->createThumbnail(64, 64); - QVERIFY(result == expected); + if (!TestUtil::compareQImages(errpoint, result, expected)) { + QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1()); + } // Test tint options config.setNumberOfOnionSkins(1); config.setOnionSkinTintFactor(64); config.setOnionSkinTintColorBackward(Qt::blue); config.setOnionSkinTintColorForward(Qt::red); compositor->configChanged(); compositor->composite(paintDevice, compositeDevice, QRect(0,0,512,512)); result = compositeDevice->createThumbnail(64, 64); expectedComposite->fill(QRect(0,0,512,512), KoColor(QColor(69, 183, 3, 200), paintDevice->colorSpace())); expected = expectedComposite->createThumbnail(64, 64); - QVERIFY(result == expected); + if (!TestUtil::compareQImages(errpoint, result, expected)) { + QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1()); + } } QTEST_MAIN(KisOnionSkinCompositorTest) diff --git a/libs/pigment/KoBasicHistogramProducers.h b/libs/pigment/KoBasicHistogramProducers.h index 3b9e369ecf..3f695ccdb7 100644 --- a/libs/pigment/KoBasicHistogramProducers.h +++ b/libs/pigment/KoBasicHistogramProducers.h @@ -1,262 +1,267 @@ /* * Copyright (c) 2005 Bart Coppens * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _Ko_BASIC_HISTOGRAM_PRODUCERS_ #define _Ko_BASIC_HISTOGRAM_PRODUCERS_ #include "KoHistogramProducer.h" #include #include #include "KoColorSpace.h" #include "KoID.h" #include "kritapigment_export.h" #include "KoColorSpaceRegistry.h" class KRITAPIGMENT_EXPORT KoBasicHistogramProducer : public KoHistogramProducer { public: explicit KoBasicHistogramProducer(const KoID& id, int channelCount, int nrOfBins); explicit KoBasicHistogramProducer(const KoID& id, int nrOfBins, const KoColorSpace *colorSpace); ~KoBasicHistogramProducer() override {} void clear() override; void setView(qreal from, qreal size) override { m_from = from; m_width = size; } const KoID& id() const override { return m_id; } QList channels() override { return m_colorSpace->channels(); } qint32 numberOfBins() override { return m_nrOfBins; } qreal viewFrom() const override { return m_from; } qreal viewWidth() const override { return m_width; } qint32 count() override { return m_count; } qint32 getBinAt(int channel, int position) override { return m_bins.at(externalToInternal(channel)).at(position); } qint32 outOfViewLeft(int channel) override { return m_outLeft.at(externalToInternal(channel)); } qint32 outOfViewRight(int channel) override { return m_outRight.at(externalToInternal(channel)); } protected: /** * The order in which channels() returns is not the same as the internal representation, * that of the pixel internally. This method converts external usage to internal usage. * This method uses some basic assumtpions about the layout of the pixel, so _extremely_ * exotic spaces might want to override this (see makeExternalToInternal source for * those assumptions) **/ virtual int externalToInternal(int ext) { if (channels().count() > 0 && m_external.count() == 0) // Set up the translation table makeExternalToInternal(); return m_external.at(ext); } // not virtual since that is useless: we call it from constructor void makeExternalToInternal(); typedef QVector vBins; QVector m_bins; vBins m_outLeft, m_outRight; qreal m_from, m_width; qint32 m_count; int m_channels, m_nrOfBins; const KoColorSpace *m_colorSpace; KoID m_id; QVector m_external; }; class KRITAPIGMENT_EXPORT KoBasicU8HistogramProducer : public KoBasicHistogramProducer { public: KoBasicU8HistogramProducer(const KoID& id, const KoColorSpace *colorSpace); + ~KoBasicU8HistogramProducer() override {} void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; QString positionToString(qreal pos) const override; qreal maximalZoom() const override { return 1.0; } }; class KRITAPIGMENT_EXPORT KoBasicU16HistogramProducer : public KoBasicHistogramProducer { public: KoBasicU16HistogramProducer(const KoID& id, const KoColorSpace *colorSpace); + ~KoBasicU16HistogramProducer() override {} void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; QString positionToString(qreal pos) const override; qreal maximalZoom() const override; }; class KRITAPIGMENT_EXPORT KoBasicF32HistogramProducer : public KoBasicHistogramProducer { public: KoBasicF32HistogramProducer(const KoID& id, const KoColorSpace *colorSpace); + ~KoBasicF32HistogramProducer() override {} void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; QString positionToString(qreal pos) const override; qreal maximalZoom() const override; }; #ifdef HAVE_OPENEXR class KRITAPIGMENT_EXPORT KoBasicF16HalfHistogramProducer : public KoBasicHistogramProducer { public: KoBasicF16HalfHistogramProducer(const KoID& id, const KoColorSpace *colorSpace); + ~KoBasicF16HalfHistogramProducer() override {} void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; QString positionToString(qreal pos) const override; qreal maximalZoom() const override; }; #endif /** * Parametrized on a specific KoHistogramProducer. Its generated producers * will have the same KoID as the factory's. This is acceptable because we can't mix * Factories with Producers in the code because they are incompatible types, and * in the GUI we actually only need a producer's name, not a factory's. */ template class KoBasicHistogramProducerFactory : public KoHistogramProducerFactory { public: KoBasicHistogramProducerFactory(const KoID& id, const QString& modelId, const QString& depthId ) : KoHistogramProducerFactory(id), m_modelId(modelId), m_depthId(depthId) { } ~KoBasicHistogramProducerFactory() override {} KoHistogramProducer *generate() override { KoHistogramProducer *producer = 0; const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(m_modelId, m_depthId, 0); if (cs) { producer = new T(KoID(id(), name()), cs); } return producer; } bool isCompatibleWith(const KoColorSpace* colorSpace, bool strict = false) const override { if( strict ){ return colorSpace->colorDepthId().id() == m_depthId; } return colorSpace->colorModelId().id() == m_modelId || colorSpace->colorDepthId().id() == m_depthId; } float preferrednessLevelWith(const KoColorSpace* colorSpace) const override { return 0.5 * ( (colorSpace->colorModelId().id() == m_modelId) + (colorSpace->colorDepthId().id() == m_depthId) ); } protected: QString m_modelId, m_depthId; }; /** * This is a Producer (with associated factory) that converts the pixels of the colorspace * to RGB8 with toQColor, and then does its counting on RGB. This is NOT registered with the * Registry, because it isCompatibleWith all colorspaces, and should only be used in extreme * cases (like no other producer being available **/ class KRITAPIGMENT_EXPORT KoGenericRGBHistogramProducer : public KoBasicHistogramProducer { public: KoGenericRGBHistogramProducer(); + ~KoGenericRGBHistogramProducer() override {} void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; QString positionToString(qreal pos) const override; qreal maximalZoom() const override; QList channels() override; protected: QList m_channelsList; }; /** KoGenericRGBHistogramProducer his special Factory that isCompatibleWith everything. */ class KRITAPIGMENT_EXPORT KoGenericRGBHistogramProducerFactory : public KoHistogramProducerFactory { public: KoGenericRGBHistogramProducerFactory(); ~KoGenericRGBHistogramProducerFactory() override {} KoHistogramProducer *generate() override { return new KoGenericRGBHistogramProducer(); } bool isCompatibleWith(const KoColorSpace*, bool strict = false) const override { Q_UNUSED(strict); return true; } float preferrednessLevelWith(const KoColorSpace*) const override { return 0.0; } }; /** * This is a Producer (with associated factory) that converts the pixels of the colorspace * to L*a*b*, and then does its counting. * It isCompatibleWith all colorspaces **/ class KRITAPIGMENT_EXPORT KoGenericLabHistogramProducer : public KoBasicHistogramProducer { public: KoGenericLabHistogramProducer(); ~KoGenericLabHistogramProducer() override; void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace) override; QString positionToString(qreal pos) const override; qreal maximalZoom() const override; QList channels() override; protected: QList m_channelsList; }; /** KoGenericLabHistogramProducer his special Factory that isCompatibleWith everything. */ class /*KRITAPIGMENT_EXPORT*/ KoGenericLabHistogramProducerFactory : public KoHistogramProducerFactory { public: KoGenericLabHistogramProducerFactory(); ~KoGenericLabHistogramProducerFactory() override {} KoHistogramProducer *generate() override { return new KoGenericLabHistogramProducer(); } bool isCompatibleWith(const KoColorSpace*, bool strict = false) const override { Q_UNUSED(strict); return true; } float preferrednessLevelWith(const KoColorSpace*) const override { return 0.0; } }; #endif // _Ko_BASIC_HISTOGRAM_PRODUCERS_ diff --git a/libs/pigment/KoHistogramProducer.h b/libs/pigment/KoHistogramProducer.h index 946d8b43c5..1562e0e3ab 100644 --- a/libs/pigment/KoHistogramProducer.h +++ b/libs/pigment/KoHistogramProducer.h @@ -1,143 +1,143 @@ /* * Copyright (c) 2005 Bart Coppens * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _KO_HISTOGRAM_PRODUCER_ #define _KO_HISTOGRAM_PRODUCER_ #include #include "kritapigment_export.h" #include #include class QString; class KoChannelInfo; class KoColorSpace; /** * This class is an interface used in the generation of a histogram. It is a container of * data, all mathematically interesting things will calculated by an histogram. * * The default view will be the entire range each color can be in. And don't let the * numberOfBins return anything else then 256 unless you have a very good reason for it. * * About the views: a view is a zoom combined with a start level: the entire * range of a channel is 0.0 - 1.0: this is the position. Combined with a zoom, we can * calculate what part of a channel will fall in a bin. This gives us an interface to * that the views that is not dependent of the actual colorspace of the histogram. * The 'size' value is the size, again from 0.0 to 1.0 of the displayed range. * * For comfort of the GUI, and because it is logical, channels are accessed in the order * in which they are found in the channels() method. This is potentially different from * the order in which they are internally ordered! **/ class KRITAPIGMENT_EXPORT KoHistogramProducer { public: KoHistogramProducer() : m_skipTransparent(true), m_skipUnselected(true) {} - virtual ~KoHistogramProducer() {} + virtual ~KoHistogramProducer() { qDebug() << "removing KoHistogramProducer"; } // Methods to change the bins /** Clears the data in this producer, but keeps its other settings */ virtual void clear() = 0; /** * Adds the values from the specified array of pixels to the bins -- does not * reset anything. * * @param pixels A pointer an array of pixeldata in the given colorspace * @param selectionMask a pointer to an array of bytes, where 0 is unselected and 1-255 is degree of selectedness. The array * must be just as long as the array of pixels. * @param nPixels The number of pixels * @param colorSpace the colorspace that can decode the pixel data. */ virtual void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace* colorSpace) = 0; // Methods to set what exactly is being added to the bins virtual void setView(qreal from, qreal width) = 0; virtual void setSkipTransparent(bool set) { m_skipTransparent = set; } virtual void setSkipUnselected(bool set) { m_skipUnselected = set; } // Methods with general information about this specific producer virtual const KoID& id() const = 0; virtual QList channels() = 0; virtual qint32 numberOfBins() = 0; virtual QString positionToString(qreal pos) const = 0; virtual qreal viewFrom() const = 0; virtual qreal viewWidth() const = 0; virtual qreal maximalZoom() const = 0; // Methods to get information on the data we have seen virtual qint32 count() = 0; virtual qint32 getBinAt(qint32 channel, qint32 position) = 0; virtual qint32 outOfViewLeft(qint32 channel) = 0; virtual qint32 outOfViewRight(qint32 channel) = 0; protected: bool m_skipTransparent; bool m_skipUnselected; }; class KRITAPIGMENT_EXPORT KoHistogramProducerFactory { public: explicit KoHistogramProducerFactory(const KoID &id) : m_id(id) {} virtual ~KoHistogramProducerFactory() {} /// Factory method, generates a new KoHistogramProducer virtual KoHistogramProducer *generate() = 0; /// Returns if a colorspace can be used with this producer virtual bool isCompatibleWith(const KoColorSpace* colorSpace, bool strict = false) const = 0; /// Returns a float in the [0.0, 1.0] range, 0.0 means this is a very generic method virtual float preferrednessLevelWith(const KoColorSpace* colorSpace) const = 0; virtual QString id() const { return m_id.id(); } virtual QString name() const { return m_id.name(); } protected: KoID m_id; }; class KRITAPIGMENT_EXPORT KoHistogramProducerFactoryRegistry : public KoGenericRegistry { public: KoHistogramProducerFactoryRegistry(); ~KoHistogramProducerFactoryRegistry() override; static KoHistogramProducerFactoryRegistry* instance(); /// returns a list, sorted by preferrence: higher preferance comes first QList keysCompatibleWith(const KoColorSpace* colorSpace, bool isStrict=false) const; private: KoHistogramProducerFactoryRegistry(const KoHistogramProducerFactoryRegistry&); KoHistogramProducerFactoryRegistry operator=(const KoHistogramProducerFactoryRegistry&); }; #endif // _KO_HISTOGRAM_PRODUCER diff --git a/plugins/filters/tests/data/Blur.cfg b/plugins/filters/tests/data/Blur.cfg deleted file mode 100644 index 962ef855d1..0000000000 --- a/plugins/filters/tests/data/Blur.cfg +++ /dev/null @@ -1,2 +0,0 @@ - -