File indexing completed on 2024-05-26 04:30:29

0001 /*
0002  *  SPDX-FileCopyrightText: 2018 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "KisFrameSerializerTest.h"
0008 
0009 #include <KisFrameDataSerializer.h>
0010 #include "opengl/kis_texture_tile_info_pool.h"
0011 
0012 #include <testutil.h>
0013 
0014 #include <simpletest.h>
0015 
0016 static const int maxTileSize = 256;
0017 
0018 KisFrameDataSerializer::Frame generateTestFrame(int frameSeed, KisTextureTileInfoPoolSP pool)
0019 {
0020     KisFrameDataSerializer::Frame frame;
0021     frame.pixelSize = 4;
0022 
0023     for (int i = 0; i < qBound(1, frameSeed * 5, 100); i++) {
0024         KisFrameDataSerializer::FrameTile tile(pool);
0025         tile.col = i * 10;
0026         tile.row = i * 20;
0027         tile.rect = QRect(QPoint(i, 2 * i), QSize(qMin(i * 5, maxTileSize), qMin(i * 7, maxTileSize)));
0028         tile.data.allocate(frame.pixelSize);
0029 
0030         const int numPixels = tile.rect.width() * tile.rect.height();
0031         qint32 *dataPtr = reinterpret_cast<qint32*>(tile.data.data());
0032 
0033         for (int j = 0; j < numPixels; j++) {
0034             *dataPtr++ = frameSeed + j;
0035         }
0036 
0037         frame.frameTiles.push_back(std::move(tile));
0038     }
0039 
0040     return frame;
0041 }
0042 
0043 bool verifyTestFrame(int frameSeed, const KisFrameDataSerializer::Frame &frame)
0044 {
0045     KIS_COMPARE_RF(frame.pixelSize, 4);
0046     KIS_COMPARE_RF(int(frame.frameTiles.size()), qBound(1, frameSeed * 5, 100));
0047 
0048     for (int i = 0; i < int(frame.frameTiles.size()); i++) {
0049         const KisFrameDataSerializer::FrameTile &tile = frame.frameTiles[i];
0050 
0051         KIS_COMPARE_RF(tile.col, i * 10);
0052         KIS_COMPARE_RF(tile.row, i * 20);
0053         KIS_COMPARE_RF(tile.rect.x(), i);
0054         KIS_COMPARE_RF(tile.rect.y(), 2 * i);
0055         KIS_COMPARE_RF(tile.rect.size(), QSize(qMin(i * 5, maxTileSize), qMin(i * 7, maxTileSize)));
0056 
0057         const int numPixels = tile.rect.width() * tile.rect.height();
0058         qint32 *dataPtr = reinterpret_cast<qint32*>(tile.data.data());
0059 
0060         for (int j = 0; j < numPixels; j++) {
0061             KIS_COMPARE_RF(*dataPtr++, frameSeed + j);
0062         }
0063     }
0064 
0065     return true;
0066 }
0067 
0068 
0069 
0070 void KisFrameSerializerTest::testFrameDataSerialization()
0071 {
0072     KisTextureTileInfoPoolRegistry poolRegistry;
0073     KisTextureTileInfoPoolSP pool = poolRegistry.getPool(maxTileSize, maxTileSize);
0074 
0075 
0076     KisFrameDataSerializer serializer;
0077 
0078     KisFrameDataSerializer::Frame testFrame1 = generateTestFrame(2, pool);
0079     KisFrameDataSerializer::Frame testFrame2 = generateTestFrame(3, pool);
0080     KisFrameDataSerializer::Frame testFrame3 = generateTestFrame(503, pool);
0081     int testFrameId1 = -1;
0082     int testFrameId2 = -1;
0083     int testFrameId3 = -1;
0084 
0085 
0086 
0087     testFrameId1 = serializer.saveFrame(testFrame1);
0088     QCOMPARE(serializer.hasFrame(testFrameId1), true);
0089     QCOMPARE(serializer.hasFrame(testFrameId2), false);
0090     QCOMPARE(serializer.hasFrame(testFrameId3), false);
0091 
0092     testFrameId2 = serializer.saveFrame(testFrame2);
0093     QCOMPARE(serializer.hasFrame(testFrameId1), true);
0094     QCOMPARE(serializer.hasFrame(testFrameId2), true);
0095     QCOMPARE(serializer.hasFrame(testFrameId3), false);
0096 
0097     testFrameId3 = serializer.saveFrame(testFrame3);
0098     QCOMPARE(serializer.hasFrame(testFrameId1), true);
0099     QCOMPARE(serializer.hasFrame(testFrameId2), true);
0100     QCOMPARE(serializer.hasFrame(testFrameId3), true);
0101 
0102     QVERIFY(verifyTestFrame(2, serializer.loadFrame(testFrameId1, pool)));
0103     QVERIFY(verifyTestFrame(3, serializer.loadFrame(testFrameId2, pool)));
0104     QVERIFY(verifyTestFrame(503, serializer.loadFrame(testFrameId3, pool)));
0105 
0106     serializer.forgetFrame(testFrameId2);
0107     QCOMPARE(serializer.hasFrame(testFrameId1), true);
0108     QCOMPARE(serializer.hasFrame(testFrameId2), false);
0109     QCOMPARE(serializer.hasFrame(testFrameId3), true);
0110 
0111     serializer.forgetFrame(testFrameId3);
0112     QCOMPARE(serializer.hasFrame(testFrameId1), true);
0113     QCOMPARE(serializer.hasFrame(testFrameId2), false);
0114     QCOMPARE(serializer.hasFrame(testFrameId3), false);
0115 
0116     serializer.forgetFrame(testFrameId1);
0117     QCOMPARE(serializer.hasFrame(testFrameId1), false);
0118     QCOMPARE(serializer.hasFrame(testFrameId2), false);
0119     QCOMPARE(serializer.hasFrame(testFrameId3), false);
0120 }
0121 
0122 #include "kis_random_source.h"
0123 
0124 void randomizeFrame(KisFrameDataSerializer::Frame &frame, qreal portion)
0125 {
0126     // randomly reset 50% of the pixels
0127     KisRandomSource rnd(1);
0128     for (KisFrameDataSerializer::FrameTile &tile : frame.frameTiles) {
0129         const int numPixels = tile.rect.width() * tile.rect.height();
0130         qint32 *pixelPtr = reinterpret_cast<qint32*>(tile.data.data());
0131 
0132         for (int j = 0; j < numPixels; j++) {
0133             if (rnd.generateNormalized() < portion) {
0134                 (*pixelPtr) = 0;
0135             }
0136 
0137             pixelPtr++;
0138         }
0139     }
0140 }
0141 
0142 void KisFrameSerializerTest::testFrameUniquenessEstimation()
0143 {
0144     KisTextureTileInfoPoolRegistry poolRegistry;
0145     KisTextureTileInfoPoolSP pool = poolRegistry.getPool(maxTileSize, maxTileSize);
0146 
0147     KisFrameDataSerializer::Frame testFrame1 = generateTestFrame(2, pool);
0148     KisFrameDataSerializer::Frame testFrame2 = generateTestFrame(2, pool);
0149 
0150     boost::optional<qreal> result;
0151 
0152     result = KisFrameDataSerializer::estimateFrameUniqueness(testFrame1, testFrame2, 0.1);
0153     QVERIFY(!!result);
0154     QVERIFY(qFuzzyCompare(*result, 0.0));
0155 
0156     KisFrameDataSerializer::Frame testFrame3 = generateTestFrame(3, pool);
0157 
0158     result = KisFrameDataSerializer::estimateFrameUniqueness(testFrame1, testFrame3, 0.1);
0159     QVERIFY(!result);
0160 
0161     // randomly reset 50% of the pixels
0162     randomizeFrame(testFrame2, 0.5);
0163 
0164     result = KisFrameDataSerializer::estimateFrameUniqueness(testFrame1, testFrame2, 0.01);
0165     QVERIFY(!!result);
0166     QVERIFY(*result >= 0.45);
0167     QVERIFY(*result <= 0.55);
0168 }
0169 
0170 void KisFrameSerializerTest::testFrameArithmetics()
0171 {
0172     KisTextureTileInfoPoolRegistry poolRegistry;
0173     KisTextureTileInfoPoolSP pool = poolRegistry.getPool(maxTileSize, maxTileSize);
0174 
0175     KisFrameDataSerializer::Frame testFrame1 = generateTestFrame(2, pool);
0176     KisFrameDataSerializer::Frame testFrame2 = generateTestFrame(2, pool);
0177     randomizeFrame(testFrame2, 0.2);
0178 
0179     boost::optional<qreal> result =
0180         KisFrameDataSerializer::estimateFrameUniqueness(testFrame1, testFrame2, 0.01);
0181 
0182     QVERIFY(!!result);
0183     QVERIFY(*result >= 0.15);
0184     QVERIFY(*result <= 0.25);
0185 
0186 
0187     {
0188         KisFrameDataSerializer::Frame testFrame3 = generateTestFrame(2, pool);
0189         randomizeFrame(testFrame3, 0.2);
0190 
0191         const bool framesAreSame = KisFrameDataSerializer::subtractFrames(testFrame3, testFrame2);
0192         QVERIFY(framesAreSame);
0193     }
0194 
0195     {
0196         KisFrameDataSerializer::Frame testFrame3 = generateTestFrame(2, pool);
0197         randomizeFrame(testFrame3, 0.2);
0198 
0199         const bool framesAreSame = KisFrameDataSerializer::subtractFrames(testFrame3, testFrame1);
0200         QVERIFY(!framesAreSame);
0201 
0202         KisFrameDataSerializer::addFrames(testFrame3, testFrame1);
0203 
0204         result = KisFrameDataSerializer::estimateFrameUniqueness(testFrame3, testFrame2, 1.0);
0205         QVERIFY(!!result);
0206         QVERIFY(*result == 0.0);
0207     }
0208 }
0209 
0210 SIMPLE_TEST_MAIN(KisFrameSerializerTest)