File indexing completed on 2024-05-12 04:19:58
0001 /* 0002 Gwenview: an image viewer 0003 Copyright 2007 Aurélien Gâteau <agateau@kde.org> 0004 0005 This program is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU General Public License 0007 as published by the Free Software Foundation; either version 2 0008 of the License, or (at your option) any later version. 0009 0010 This program is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 GNU General Public License for more details. 0014 0015 You should have received a copy of the GNU General Public License 0016 along with this program; if not, write to the Free Software 0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0018 0019 */ 0020 #include "jpegcontenttest.h" 0021 #include <iostream> 0022 0023 // Qt 0024 #include <QDebug> 0025 #include <QDir> 0026 #include <QFile> 0027 #include <QImage> 0028 #include <QString> 0029 #include <QTest> 0030 0031 // KF 0032 0033 // Local 0034 #include "../lib/jpegcontent.h" 0035 #include "../lib/orientation.h" 0036 #include "testutils.h" 0037 0038 using namespace std; 0039 0040 const char *ORIENT6_FILE = "orient6.jpg"; 0041 const char *ORIENT1_VFLIP_FILE = "orient1_vflip.jpg"; 0042 const char *CUT_FILE = "cut.jpg"; 0043 const char *TMP_FILE = "tmp.jpg"; 0044 const char *THUMBNAIL_FILE = "test_thumbnail.jpg"; 0045 0046 const int ORIENT6_WIDTH = 128; // This size is the size *after* orientation 0047 const int ORIENT6_HEIGHT = 256; // has been applied 0048 const QString ORIENT6_COMMENT = "a comment"; 0049 0050 QTEST_MAIN(JpegContentTest) 0051 0052 void JpegContentTest::initTestCase() 0053 { 0054 bool result; 0055 QFile in(pathForTestFile(ORIENT6_FILE)); 0056 result = in.open(QIODevice::ReadOnly); 0057 QVERIFY(result); 0058 0059 QFileInfo info(in); 0060 int size = info.size() / 2; 0061 0062 char *data = new char[size]; 0063 int readSize = in.read(data, size); 0064 QCOMPARE(size, readSize); 0065 0066 QFile out(CUT_FILE); 0067 result = out.open(QIODevice::WriteOnly); 0068 QVERIFY(result); 0069 0070 int wroteSize = out.write(data, size); 0071 QCOMPARE(size, wroteSize); 0072 delete[] data; 0073 } 0074 0075 void JpegContentTest::cleanupTestCase() 0076 { 0077 QDir::current().remove(CUT_FILE); 0078 } 0079 0080 using MetaInfoMap = QMap<QString, QString>; 0081 0082 #if 0 0083 MetaInfoMap getMetaInfo(const QString& path) 0084 { 0085 KFileMetaInfo fmi(path); 0086 QStringList list = fmi.supportedKeys(); 0087 QStringList::ConstIterator it = list.constBegin(); 0088 MetaInfoMap map; 0089 0090 for (; it != list.constEnd(); ++it) { 0091 KFileMetaInfoItem item = fmi.item(*it); 0092 map[*it] = item.value().toString(); 0093 } 0094 0095 return map; 0096 } 0097 0098 void compareMetaInfo(const QString& path1, const QString& path2, const QStringList& ignoredKeys) 0099 { 0100 MetaInfoMap mim1 = getMetaInfo(path1); 0101 MetaInfoMap mim2 = getMetaInfo(path2); 0102 0103 QCOMPARE(mim1.keys(), mim2.keys()); 0104 QList<QString> keys = mim1.keys(); 0105 QList<QString>::ConstIterator it = keys.constBegin(); 0106 for (; it != keys.constEnd(); ++it) { 0107 QString key = *it; 0108 if (ignoredKeys.contains(key)) continue; 0109 0110 QString msg = 0111 QStringLiteral("Meta info differs for key '%1': v1=%2 v2=%3") 0112 .arg(key) 0113 .arg(mim1[key]) 0114 .arg(mim2[key]); 0115 0116 QVERIFY2(mim1[key] == mim2[key], msg.toUtf8()); 0117 } 0118 } 0119 #endif 0120 0121 void JpegContentTest::testResetOrientation() 0122 { 0123 Gwenview::JpegContent content; 0124 bool result; 0125 0126 // Test resetOrientation without transform 0127 result = content.load(pathForTestFile(ORIENT6_FILE)); 0128 QVERIFY(result); 0129 0130 content.resetOrientation(); 0131 0132 result = content.save(TMP_FILE); 0133 QVERIFY(result); 0134 0135 result = content.load(TMP_FILE); 0136 QVERIFY(result); 0137 QCOMPARE(content.orientation(), Gwenview::NORMAL); 0138 0139 // Test resetOrientation with transform 0140 result = content.load(pathForTestFile(ORIENT6_FILE)); 0141 QVERIFY(result); 0142 0143 content.resetOrientation(); 0144 content.transform(Gwenview::ROT_90); 0145 0146 result = content.save(TMP_FILE); 0147 QVERIFY(result); 0148 0149 result = content.load(TMP_FILE); 0150 QVERIFY(result); 0151 QCOMPARE(content.orientation(), Gwenview::NORMAL); 0152 } 0153 0154 /** 0155 * This function tests JpegContent::transform() by applying a ROT_90 0156 * transformation, saving, reloading and applying a ROT_270 to undo the ROT_90. 0157 * Saving and reloading are necessary because lossless transformation only 0158 * happens in JpegContent::save() 0159 */ 0160 void JpegContentTest::testTransform() 0161 { 0162 bool result; 0163 QImage finalImage, expectedImage; 0164 0165 Gwenview::JpegContent content; 0166 result = content.load(pathForTestFile(ORIENT6_FILE)); 0167 QVERIFY(result); 0168 0169 content.transform(Gwenview::ROT_90); 0170 result = content.save(TMP_FILE); 0171 QVERIFY(result); 0172 0173 result = content.load(TMP_FILE); 0174 QVERIFY(result); 0175 content.transform(Gwenview::ROT_270); 0176 result = content.save(TMP_FILE); 0177 QVERIFY(result); 0178 0179 result = finalImage.load(TMP_FILE); 0180 QVERIFY(result); 0181 0182 result = expectedImage.load(pathForTestFile(ORIENT6_FILE)); 0183 QVERIFY(result); 0184 0185 QCOMPARE(finalImage, expectedImage); 0186 } 0187 0188 void JpegContentTest::testSetComment() 0189 { 0190 QString comment = "test comment"; 0191 Gwenview::JpegContent content; 0192 bool result; 0193 result = content.load(pathForTestFile(ORIENT6_FILE)); 0194 QVERIFY(result); 0195 0196 content.setComment(comment); 0197 QCOMPARE(content.comment(), comment); 0198 result = content.save(TMP_FILE); 0199 QVERIFY(result); 0200 0201 result = content.load(TMP_FILE); 0202 QVERIFY(result); 0203 QCOMPARE(content.comment(), comment); 0204 } 0205 0206 void JpegContentTest::testReadInfo() 0207 { 0208 Gwenview::JpegContent content; 0209 bool result = content.load(pathForTestFile(ORIENT6_FILE)); 0210 QVERIFY(result); 0211 QCOMPARE(int(content.orientation()), 6); 0212 QCOMPARE(content.comment(), ORIENT6_COMMENT); 0213 QCOMPARE(content.size(), QSize(ORIENT6_WIDTH, ORIENT6_HEIGHT)); 0214 } 0215 0216 void JpegContentTest::testThumbnail() 0217 { 0218 Gwenview::JpegContent content; 0219 bool result = content.load(pathForTestFile(ORIENT6_FILE)); 0220 QVERIFY(result); 0221 QImage thumbnail = content.thumbnail(); 0222 result = thumbnail.save(THUMBNAIL_FILE, "JPEG"); 0223 QVERIFY(result); 0224 } 0225 0226 void JpegContentTest::testMultipleRotations() 0227 { 0228 // Test that rotating a file a lot of times does not cause findJxform() to fail 0229 Gwenview::JpegContent content; 0230 bool result = content.load(pathForTestFile(ORIENT6_FILE)); 0231 QVERIFY(result); 0232 result = content.load(pathForTestFile(ORIENT6_FILE)); 0233 QVERIFY(result); 0234 0235 // 12*4 + 1 is the same as 1, since rotating four times brings you back 0236 for (int loop = 0; loop < 12 * 4 + 1; ++loop) { 0237 content.transform(Gwenview::ROT_90); 0238 } 0239 result = content.save(TMP_FILE); 0240 QVERIFY(result); 0241 0242 result = content.load(TMP_FILE); 0243 QVERIFY(result); 0244 0245 QCOMPARE(content.size(), QSize(ORIENT6_HEIGHT, ORIENT6_WIDTH)); 0246 0247 // Check the other meta info are still here 0248 // QStringList ignoredKeys; 0249 // ignoredKeys << "Orientation" << "Comment"; 0250 // compareMetaInfo(pathForTestFile(ORIENT6_FILE), pathForTestFile(ORIENT1_VFLIP_FILE), ignoredKeys); 0251 } 0252 0253 void JpegContentTest::testLoadTruncated() 0254 { 0255 // Test that loading and manipulating a truncated file does not crash 0256 Gwenview::JpegContent content; 0257 bool result = content.load(CUT_FILE); 0258 QVERIFY(result); 0259 QCOMPARE(int(content.orientation()), 6); 0260 QCOMPARE(content.comment(), ORIENT6_COMMENT); 0261 content.transform(Gwenview::VFLIP); 0262 qWarning() << "# Next function should output errors about incomplete image"; 0263 content.save(TMP_FILE); 0264 qWarning() << "#"; 0265 } 0266 0267 void JpegContentTest::testRawData() 0268 { 0269 Gwenview::JpegContent content; 0270 bool result = content.load(pathForTestFile(ORIENT6_FILE)); 0271 QVERIFY(result); 0272 0273 QByteArray fileData; 0274 QFile file(pathForTestFile(ORIENT6_FILE)); 0275 result = file.open(QIODevice::ReadOnly); 0276 QVERIFY(result); 0277 fileData = file.readAll(); 0278 0279 QCOMPARE(content.rawData(), fileData); 0280 } 0281 0282 void JpegContentTest::testSetImage() 0283 { 0284 Gwenview::JpegContent content; 0285 bool result = content.load(pathForTestFile(ORIENT6_FILE)); 0286 QVERIFY(result); 0287 0288 QImage image = QImage(400, 300, QImage::Format_RGB32); 0289 image.fill(Qt::red); 0290 0291 content.setImage(image); 0292 0293 result = content.save(TMP_FILE); 0294 QVERIFY(result); 0295 0296 result = content.load(TMP_FILE); 0297 QVERIFY(result); 0298 0299 QCOMPARE(content.size(), image.size()); 0300 0301 // QStringList ignoredKeys; 0302 // ignoredKeys << "Orientation"; 0303 // compareMetaInfo(pathForTestFile(ORIENT6_FILE), pathForTestFile(TMP_FILE), ignoredKeys); 0304 } 0305 0306 #include "moc_jpegcontenttest.cpp"