File indexing completed on 2024-12-22 04:10:28

0001 /*
0002  *  SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_warp_transform_worker_test.h"
0008 
0009 #include <simpletest.h>
0010 #include <testutil.h>
0011 
0012 #include "kis_warptransform_worker.h"
0013 
0014 #include <KoProgressUpdater.h>
0015 
0016 struct WarpTransformWorkerData {
0017 
0018     WarpTransformWorkerData() {
0019         TestUtil::TestProgressBar bar;
0020         KoProgressUpdater pu(&bar);
0021         updater = pu.startSubtask();
0022 
0023         const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
0024         // QImage image(TestUtil::fetchDataFileLazy("test_transform_quality.png"));
0025         QImage image(TestUtil::fetchDataFileLazy("test_transform_quality_second.png"));
0026 
0027         dev = new KisPaintDevice(cs);
0028         dev->convertFromQImage(image, 0);
0029 
0030         alpha = 1.0;
0031 
0032         bounds = dev->exactBounds();
0033 
0034         origPoints << bounds.topLeft();
0035         origPoints << bounds.topRight();
0036         origPoints << bounds.bottomRight();
0037         origPoints << bounds.bottomLeft();
0038 
0039         origPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight());
0040         origPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight()) + QPointF(-20, 0);
0041 
0042 
0043         transfPoints << bounds.topLeft();
0044         transfPoints << bounds.bottomLeft() + 0.6 * (bounds.topRight() - bounds.bottomLeft());
0045         transfPoints << bounds.topLeft() + 0.8 * (bounds.bottomRight() - bounds.topLeft());
0046         transfPoints << bounds.bottomLeft() + QPointF(200, 0);
0047 
0048         transfPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight()) + QPointF(40,20);
0049         transfPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight()) + QPointF(-20, 0) + QPointF(-40,20);
0050     }
0051 
0052 
0053     KisPaintDeviceSP dev;
0054     QVector<QPointF> origPoints;
0055     QVector<QPointF> transfPoints;
0056     qreal alpha;
0057     KoUpdaterPtr updater;
0058     QRectF bounds;
0059 };
0060 
0061 
0062 void KisWarpTransformWorkerTest::test()
0063 {
0064     WarpTransformWorkerData d;
0065     KisPaintDeviceSP srcDev = new KisPaintDevice(*d.dev);
0066 
0067     KisWarpTransformWorker worker(KisWarpTransformWorker::RIGID_TRANSFORM,
0068                                   d.origPoints,
0069                                   d.transfPoints,
0070                                   d.alpha,
0071                                   d.updater);
0072 
0073     QBENCHMARK_ONCE {
0074         worker.run(srcDev, d.dev);
0075     }
0076 
0077     QImage result = d.dev->convertToQImage(0);
0078 
0079     TestUtil::checkQImage(result, "warp_transform_test", "simple", "tr");
0080 }
0081 
0082 void KisWarpTransformWorkerTest::testQImage()
0083 {
0084     TestUtil::TestProgressBar bar;
0085     KoProgressUpdater pu(&bar);
0086     KoUpdaterPtr updater = pu.startSubtask();
0087 
0088 //    QImage image(TestUtil::fetchDataFileLazy("test_transform_quality.png"));
0089     QImage image(TestUtil::fetchDataFileLazy("test_transform_quality_second.png"));
0090     image.convertTo(QImage::Format_ARGB32);
0091 
0092     dbgKrita << ppVar(image.format());
0093 
0094 
0095     QVector<QPointF> origPoints;
0096     QVector<QPointF> transfPoints;
0097     qreal alpha = 1.0;
0098 
0099     QRectF bounds(image.rect());
0100 
0101     origPoints << bounds.topLeft();
0102     origPoints << bounds.topRight();
0103     origPoints << bounds.bottomRight();
0104     origPoints << bounds.bottomLeft();
0105 
0106     origPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight());
0107     origPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight()) + QPointF(-20, 0);
0108 
0109 
0110     transfPoints << bounds.topLeft();
0111     transfPoints << bounds.bottomLeft() + 0.6 * (bounds.topRight() - bounds.bottomLeft());
0112     transfPoints << bounds.topLeft() + 0.8 * (bounds.bottomRight() - bounds.topLeft());
0113     transfPoints << bounds.bottomLeft() + QPointF(200, 0);
0114 
0115     transfPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight()) + QPointF(40,20);
0116     transfPoints << 0.5 * (bounds.bottomLeft() + bounds.bottomRight()) + QPointF(-20, 0) + QPointF(-40,20);
0117 
0118 
0119     QImage result;
0120     QPointF newOffset;
0121 
0122     QBENCHMARK_ONCE {
0123         result = KisWarpTransformWorker::transformQImage(
0124             KisWarpTransformWorker::RIGID_TRANSFORM,
0125             origPoints, transfPoints, alpha,
0126             image, QPointF(), &newOffset);
0127     }
0128 
0129     dbgKrita << ppVar(newOffset);
0130 
0131     TestUtil::checkQImage(result, "warp_transform_test", "qimage", "tr");
0132 }
0133 
0134 #include "kis_four_point_interpolator_forward.h"
0135 
0136 void KisWarpTransformWorkerTest::testForwardInterpolator()
0137 {
0138     QPolygonF src;
0139 
0140     src << QPointF(0, 0);
0141     src << QPointF(100, 0);
0142     src << QPointF(100, 100);
0143     src << QPointF(0, 100);
0144 
0145     QPolygonF dst;
0146 
0147     dst << QPointF(0, 0);
0148     dst << QPointF(100, 10);
0149     dst << QPointF(100, 120);
0150     dst << QPointF(0, 100);
0151 
0152     KisFourPointInterpolatorForward interp(src, dst);
0153 
0154     QCOMPARE(interp.map(QPointF(0,50)), QPointF(0,50));
0155     QCOMPARE(interp.map(QPointF(50,0)), QPointF(50,5));
0156     QCOMPARE(interp.map(QPointF(100,0)), QPointF(100,10));
0157     QCOMPARE(interp.map(QPointF(100,50)), QPointF(100,65));
0158 
0159     QCOMPARE(interp.map(QPointF(100,100)), QPointF(100,120));
0160     QCOMPARE(interp.map(QPointF(50,100)), QPointF(50,110));
0161     QCOMPARE(interp.map(QPointF(50,50)), QPointF(50,57.5));
0162 }
0163 
0164 
0165 #include "kis_four_point_interpolator_backward.h"
0166 
0167 void KisWarpTransformWorkerTest::testBackwardInterpolatorXShear()
0168 {
0169     QPolygonF src;
0170 
0171     src << QPointF(0, 0);
0172     src << QPointF(100, 0);
0173     src << QPointF(100, 100);
0174     src << QPointF(0, 100);
0175 
0176     QPolygonF dst;
0177 
0178     dst << QPointF(0, 0);
0179     dst << QPointF(100, 0);
0180     dst << QPointF(120, 100);
0181     dst << QPointF(10, 100);
0182 
0183     KisFourPointInterpolatorBackward interp(src, dst);
0184 
0185     QCOMPARE(interp.map(QPointF(10,100)), QPointF(0,100));
0186     QCOMPARE(interp.map(QPointF(5,50)), QPointF(0,50));
0187     QCOMPARE(interp.map(QPointF(110,50)), QPointF(100,50));
0188     QCOMPARE(interp.map(QPointF(57.5,50)), QPointF(50,50));
0189 }
0190 
0191 void KisWarpTransformWorkerTest::testBackwardInterpolatorYShear()
0192 {
0193     QPolygonF src;
0194 
0195     src << QPointF(0, 0);
0196     src << QPointF(100, 0);
0197     src << QPointF(100, 100);
0198     src << QPointF(0, 100);
0199 
0200     QPolygonF dst;
0201 
0202     dst << QPointF(0, 0);
0203     dst << QPointF(100, 10);
0204     dst << QPointF(100, 120);
0205     dst << QPointF(0, 100);
0206 
0207     KisFourPointInterpolatorBackward interp(src, dst);
0208 
0209     QCOMPARE(interp.map(QPointF(100,10)), QPointF(100,0));
0210     QCOMPARE(interp.map(QPointF(50,5)), QPointF(50,0));
0211     QCOMPARE(interp.map(QPointF(50,110)), QPointF(50,100));
0212     QCOMPARE(interp.map(QPointF(50,57.5)), QPointF(50,50));
0213 }
0214 
0215 void KisWarpTransformWorkerTest::testBackwardInterpolatorXYShear()
0216 {
0217     QPolygonF src;
0218 
0219     src << QPointF(0, 0);
0220     src << QPointF(100, 0);
0221     src << QPointF(100, 100);
0222     src << QPointF(0, 100);
0223 
0224     QPolygonF dst;
0225 
0226     dst << QPointF(0, 0);
0227     dst << QPointF(100, 10);
0228     dst << QPointF(140, 120);
0229     dst << QPointF(20, 100);
0230 
0231 
0232     KisFourPointInterpolatorBackward interp(src, dst);
0233 
0234     QCOMPARE(interp.map(QPointF(100,10)), QPointF(100,0));
0235     QCOMPARE(interp.map(QPointF(50,5)), QPointF(50,0));
0236     QCOMPARE(interp.map(QPointF(80,110)), QPointF(50,100));
0237     QCOMPARE(interp.map(QPointF(120,65)), QPointF(100,50));
0238     QCOMPARE(interp.map(QPointF(10,50)), QPointF(0,50));
0239 }
0240 
0241 void KisWarpTransformWorkerTest::testBackwardInterpolatorRoundTrip()
0242 {
0243     QPolygonF src;
0244 
0245     src << QPointF(0, 0);
0246     src << QPointF(100, 0);
0247     src << QPointF(100, 100);
0248     src << QPointF(0, 100);
0249 
0250     QPolygonF dst;
0251 
0252     dst << QPointF(100, 100);
0253     dst << QPointF(20, 140);
0254     dst << QPointF(10, 80);
0255     dst << QPointF(15, 5);
0256 
0257     KisFourPointInterpolatorForward f(src, dst);
0258     KisFourPointInterpolatorBackward b(src, dst);
0259 
0260     for (int y = 0; y <= 100; y += 1) {
0261         for (int x = 0; x <= 100; x += 1) {
0262             QPointF pt(x, y);
0263 
0264             QPointF fwdPt = f.map(pt);
0265             QPointF bwdPt = b.map(fwdPt);
0266 
0267             //dbgKrita << "R:" << ppVar(pt) << ppVar(fwdPt) << ppVar(bwdPt) << (bwdPt - pt);
0268             QVERIFY((bwdPt - pt).manhattanLength() < 1e-3);
0269         }
0270     }
0271 }
0272 
0273 #include "kis_grid_interpolation_tools.h"
0274 
0275 void KisWarpTransformWorkerTest::testGridSize()
0276 {
0277     QCOMPARE(GridIterationTools::calcGridDimension(1, 7, 4), 3);
0278     QCOMPARE(GridIterationTools::calcGridDimension(1, 8, 4), 3);
0279     QCOMPARE(GridIterationTools::calcGridDimension(1, 9, 4), 4);
0280     QCOMPARE(GridIterationTools::calcGridDimension(0, 7, 4), 3);
0281     QCOMPARE(GridIterationTools::calcGridDimension(1, 8, 4), 3);
0282     QCOMPARE(GridIterationTools::calcGridDimension(4, 9, 4), 3);
0283     QCOMPARE(GridIterationTools::calcGridDimension(0, 9, 4), 4);
0284     QCOMPARE(GridIterationTools::calcGridDimension(-1, 9, 4), 5);
0285 
0286     QCOMPARE(GridIterationTools::calcGridDimension(0, 300, 8), 39);
0287 }
0288 
0289 void KisWarpTransformWorkerTest::testBackwardInterpolatorExtrapolation()
0290 {
0291     QPolygonF src;
0292 
0293     src << QPointF(0, 0);
0294     src << QPointF(100, 0);
0295     src << QPointF(100, 100);
0296     src << QPointF(0, 100);
0297 
0298     QPolygonF dst(src);
0299     std::rotate(dst.begin(), dst.begin() + 1, dst.end());
0300     KisFourPointInterpolatorBackward interp(src, dst);
0301 
0302     // standard checks
0303     QCOMPARE(interp.map(QPointF(0,0)), QPointF(0,100));
0304     QCOMPARE(interp.map(QPointF(100,0)), QPointF(0,0));
0305     QCOMPARE(interp.map(QPointF(100,100)), QPointF(100,0));
0306     QCOMPARE(interp.map(QPointF(0,100)), QPointF(100,100));
0307 
0308     // extrapolate!
0309     QCOMPARE(interp.map(QPointF(-10,0)), QPointF(0,110));
0310     QCOMPARE(interp.map(QPointF(0,-10)), QPointF(-10,100));
0311     QCOMPARE(interp.map(QPointF(-10,-10)), QPointF(-10,110));
0312 
0313     QCOMPARE(interp.map(QPointF(110,0)), QPointF(0,-10));
0314     QCOMPARE(interp.map(QPointF(100,-10)), QPointF(-10,0));
0315     QCOMPARE(interp.map(QPointF(110,-10)), QPointF(-10,-10));
0316 
0317     QCOMPARE(interp.map(QPointF(110,100)), QPointF(100, -10));
0318     QCOMPARE(interp.map(QPointF(100,110)), QPointF(110, 0));
0319     QCOMPARE(interp.map(QPointF(110,110)), QPointF(110,-10));
0320 
0321     QCOMPARE(interp.map(QPointF(-10,100)), QPointF(100, 110));
0322     QCOMPARE(interp.map(QPointF(0,110)), QPointF(110, 100));
0323     QCOMPARE(interp.map(QPointF(-10,110)), QPointF(110,110));
0324 }
0325 #include "krita_utils.h"
0326 void KisWarpTransformWorkerTest::testNeedChangeRects()
0327 {
0328     WarpTransformWorkerData d;
0329     KisWarpTransformWorker worker(KisWarpTransformWorker::RIGID_TRANSFORM,
0330                                   d.origPoints,
0331                                   d.transfPoints,
0332                                   d.alpha,
0333                                   d.updater);
0334 
0335     QCOMPARE(KisAlgebra2D::sampleRectWithPoints(d.bounds.toAlignedRect()).size(), 9);
0336     QCOMPARE(worker.approxChangeRect(d.bounds.toAlignedRect()), QRect(-44,-44, 982,986));
0337 }
0338 
0339 
0340 SIMPLE_TEST_MAIN(KisWarpTransformWorkerTest)