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)