|
|
|
|
/*
|
|
|
|
|
Gwenview - A simple image viewer for TDE
|
|
|
|
|
Copyright 2000-2004 Aur<EFBFBD>lien G<EFBFBD>teau
|
|
|
|
|
|
|
|
|
|
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 <iostream>
|
|
|
|
|
|
|
|
|
|
// TQt
|
|
|
|
|
#include <tqdir.h>
|
|
|
|
|
#include <tqfile.h>
|
|
|
|
|
#include <tqimage.h>
|
|
|
|
|
#include <tqstring.h>
|
|
|
|
|
|
|
|
|
|
// KDE
|
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
|
#include <tdeaboutdata.h>
|
|
|
|
|
#include <tdecmdlineargs.h>
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
#include <tdefilemetainfo.h>
|
|
|
|
|
|
|
|
|
|
// Local
|
|
|
|
|
#include "imageutils/imageutils.h"
|
|
|
|
|
#include "imageutils/jpegcontent.h"
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
const char* ORIENT6_FILE="orient6.jpg";
|
|
|
|
|
const int ORIENT6_WIDTH=128; // This size is the size *after* orientation
|
|
|
|
|
const int ORIENT6_HEIGHT=256; // has been applied
|
|
|
|
|
const char* CUT_FILE="cut.jpg";
|
|
|
|
|
const TQString ORIENT6_COMMENT="a comment";
|
|
|
|
|
const TQString ORIENT1_VFLIP_FILE="test_orient1_vflip.jpg";
|
|
|
|
|
const char* THUMBNAIL_FILE="test_thumbnail.jpg";
|
|
|
|
|
const char* TMP_FILE="tmp.jpg";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestEnvironment {
|
|
|
|
|
public:
|
|
|
|
|
TestEnvironment() {
|
|
|
|
|
bool result;
|
|
|
|
|
TQFile in(ORIENT6_FILE);
|
|
|
|
|
result=in.open(IO_ReadOnly);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
TQFileInfo info(in);
|
|
|
|
|
int size=info.size()/2;
|
|
|
|
|
|
|
|
|
|
char* data=new char[size];
|
|
|
|
|
int readSize=in.readBlock(data, size);
|
|
|
|
|
Q_ASSERT(size==readSize);
|
|
|
|
|
|
|
|
|
|
TQFile out(CUT_FILE);
|
|
|
|
|
result=out.open(IO_WriteOnly);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
int wroteSize=out.writeBlock(data, size);
|
|
|
|
|
Q_ASSERT(size==wroteSize);
|
|
|
|
|
delete []data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~TestEnvironment() {
|
|
|
|
|
TQDir::current().remove(CUT_FILE);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef TQMap<TQString,TQString> MetaInfoMap;
|
|
|
|
|
|
|
|
|
|
MetaInfoMap getMetaInfo(const TQString& path) {
|
|
|
|
|
KFileMetaInfo fmi(path);
|
|
|
|
|
TQStringList list=fmi.supportedKeys();
|
|
|
|
|
TQStringList::ConstIterator it=list.begin();
|
|
|
|
|
MetaInfoMap map;
|
|
|
|
|
|
|
|
|
|
for ( ; it!=list.end(); ++it) {
|
|
|
|
|
KFileMetaInfoItem item=fmi.item(*it);
|
|
|
|
|
map[*it]=item.string();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void compareMetaInfo(const TQString& path1, const TQString& path2, const TQStringList& ignoredKeys) {
|
|
|
|
|
MetaInfoMap mim1=getMetaInfo(path1);
|
|
|
|
|
MetaInfoMap mim2=getMetaInfo(path2);
|
|
|
|
|
|
|
|
|
|
Q_ASSERT(mim1.keys()==mim2.keys());
|
|
|
|
|
TQValueList<TQString> keys=mim1.keys();
|
|
|
|
|
TQValueList<TQString>::ConstIterator it=keys.begin();
|
|
|
|
|
for ( ; it!=keys.end(); ++it) {
|
|
|
|
|
TQString key=*it;
|
|
|
|
|
if (ignoredKeys.contains(key)) continue;
|
|
|
|
|
|
|
|
|
|
if (mim1[key]!=mim2[key]) {
|
|
|
|
|
kdError() << "Meta info differs. Key:" << key << ", V1:" << mim1[key] << ", V2:" << mim2[key] << endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void testResetOrientation() {
|
|
|
|
|
ImageUtils::JPEGContent content;
|
|
|
|
|
bool result;
|
|
|
|
|
|
|
|
|
|
// Test resetOrientation without transform
|
|
|
|
|
result=content.load(ORIENT6_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
content.resetOrientation();
|
|
|
|
|
|
|
|
|
|
result=content.save(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
result=content.load(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
Q_ASSERT(content.orientation() == ImageUtils::NORMAL);
|
|
|
|
|
|
|
|
|
|
// Test resetOrientation with transform
|
|
|
|
|
result=content.load(ORIENT6_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
content.resetOrientation();
|
|
|
|
|
content.transform(ImageUtils::ROT_90);
|
|
|
|
|
|
|
|
|
|
result=content.save(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
result=content.load(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
Q_ASSERT(content.orientation() == ImageUtils::NORMAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This function tests JPEGContent::transform() by applying a ROT_90
|
|
|
|
|
* transformation, saving, reloading and applying a ROT_270 to undo the ROT_90.
|
|
|
|
|
* Saving and reloading are necessary because lossless transformation only
|
|
|
|
|
* happens in JPEGContent::save()
|
|
|
|
|
*/
|
|
|
|
|
void testTransform() {
|
|
|
|
|
bool result;
|
|
|
|
|
TQImage finalImage, expectedImage;
|
|
|
|
|
|
|
|
|
|
ImageUtils::JPEGContent content;
|
|
|
|
|
result = content.load(ORIENT6_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
content.transform(ImageUtils::ROT_90);
|
|
|
|
|
result = content.save(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
result = content.load(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
content.transform(ImageUtils::ROT_270);
|
|
|
|
|
result = content.save(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
result = finalImage.load(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
result = expectedImage.load(ORIENT6_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
Q_ASSERT(finalImage == expectedImage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void testSetComment() {
|
|
|
|
|
TQString comment = "test comment";
|
|
|
|
|
ImageUtils::JPEGContent content;
|
|
|
|
|
bool result;
|
|
|
|
|
result = content.load(ORIENT6_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
content.setComment(comment);
|
|
|
|
|
Q_ASSERT(content.comment() == comment);
|
|
|
|
|
result = content.save(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
result = content.load(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
Q_ASSERT(content.comment() == comment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
|
TestEnvironment testEnv;
|
|
|
|
|
bool result;
|
|
|
|
|
TDEAboutData aboutData("testjpegcontent", "testjpegcontent", "0");
|
|
|
|
|
TDECmdLineArgs::init( argc, argv, &aboutData );
|
|
|
|
|
TDEApplication tdeapplication;
|
|
|
|
|
|
|
|
|
|
// Reading info
|
|
|
|
|
ImageUtils::JPEGContent content;
|
|
|
|
|
result=content.load(ORIENT6_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
Q_ASSERT(content.orientation() == 6);
|
|
|
|
|
Q_ASSERT(content.comment() == ORIENT6_COMMENT);
|
|
|
|
|
Q_ASSERT(content.size() == TQSize(ORIENT6_WIDTH, ORIENT6_HEIGHT));
|
|
|
|
|
|
|
|
|
|
// thumbnail()
|
|
|
|
|
TQImage thumbnail=content.thumbnail();
|
|
|
|
|
result=thumbnail.save(THUMBNAIL_FILE, "JPEG");
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
testResetOrientation();
|
|
|
|
|
testTransform();
|
|
|
|
|
testSetComment();
|
|
|
|
|
|
|
|
|
|
// Test that rotating a file a lot of times does not cause findJxform() to fail
|
|
|
|
|
result = content.load(ORIENT6_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
// 12*4 + 1 is the same as 1, since rotating four times brings you back
|
|
|
|
|
for(int loop=0; loop< 12*4 + 1; ++loop) {
|
|
|
|
|
content.transform(ImageUtils::ROT_90);
|
|
|
|
|
}
|
|
|
|
|
result = content.save(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
result = content.load(TMP_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
|
|
|
|
|
Q_ASSERT(content.size() == TQSize(ORIENT6_HEIGHT, ORIENT6_WIDTH));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check the other meta info are still here
|
|
|
|
|
TQStringList ignoredKeys;
|
|
|
|
|
ignoredKeys << "Orientation" << "Comment";
|
|
|
|
|
compareMetaInfo(ORIENT6_FILE, ORIENT1_VFLIP_FILE, ignoredKeys);
|
|
|
|
|
|
|
|
|
|
// Test that loading and manipulating a truncated file does not crash
|
|
|
|
|
result=content.load(CUT_FILE);
|
|
|
|
|
Q_ASSERT(result);
|
|
|
|
|
Q_ASSERT(content.orientation() == 6);
|
|
|
|
|
Q_ASSERT(content.comment() == ORIENT6_COMMENT);
|
|
|
|
|
content.transform(ImageUtils::VFLIP);
|
|
|
|
|
kdWarning() << "# Next function should output errors about incomplete image" << endl;
|
|
|
|
|
content.save(TMP_FILE);
|
|
|
|
|
kdWarning() << "#" << endl;
|
|
|
|
|
}
|