summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSarah Smith <sarah.j.smith@nokia.com>2011-11-14 03:51:50 (GMT)
committerSarah Smith <sarah.j.smith@nokia.com>2011-11-14 03:55:38 (GMT)
commit951a997893407b0a26f21fe0acec4701fa3d4279 (patch)
treeff2967fdd6ba6d6685ebe820fce575c557960860
parent739e705150ad114eb92a1fac34a51d30322ffc31 (diff)
downloadQt-951a997893407b0a26f21fe0acec4701fa3d4279.zip
Qt-951a997893407b0a26f21fe0acec4701fa3d4279.tar.gz
Qt-951a997893407b0a26f21fe0acec4701fa3d4279.tar.bz2
Move tga support from Qt3d to Qt.
Rev-By: Samuel Rodal Fix-for: QTBUG-21955 Part of fix for https://bugreports.qt.nokia.com/browse/QTBUG-21955 Having tga plugin inside a Qt add-on causes packaging problems. There have been many queries over the years for tga support even tho it is a niche image format. It is particularly useful for OpenGL work as a texture format since it is a blittable bitmap, but it is very innefficient compared to png or jpg. For this reason only read support is added, and this is documented. Also add some unit tests. The unit tests are in the qimagereader suite, and this is the right place for them as the other formats are tested there. Noticed that there was an annoying bug with tiff files and chased it down, in the hope of getting a clean test case PASS. Looks as tho there is a bit of work for someone to fix the other FAILs, but the ones for tga are all passing.
-rw-r--r--src/gui/image/qimagereader.cpp5
-rw-r--r--src/gui/image/qtiffhandler.cpp6
-rw-r--r--src/plugins/imageformats/imageformats.pro1
-rw-r--r--src/plugins/imageformats/tga/main.cpp95
-rw-r--r--src/plugins/imageformats/tga/qtgafile.cpp239
-rw-r--r--src/plugins/imageformats/tga/qtgafile.h146
-rw-r--r--src/plugins/imageformats/tga/qtgahandler.cpp123
-rw-r--r--src/plugins/imageformats/tga/qtgahandler.h74
-rw-r--r--src/plugins/imageformats/tga/tga.pro16
-rw-r--r--tests/auto/qimagereader/images/test-flag-rle.tgabin0 -> 7971 bytes
-rw-r--r--tests/auto/qimagereader/images/test-flag.tgabin0 -> 480044 bytes
-rw-r--r--tests/auto/qimagereader/qimagereader.pro1
-rw-r--r--tests/auto/qimagereader/qimagereader.qrc2
-rw-r--r--tests/auto/qimagereader/tst_qimagereader.cpp51
14 files changed, 755 insertions, 4 deletions
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 411e5e9..2b56e49 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -1473,11 +1473,16 @@ QByteArray QImageReader::imageFormat(QIODevice *device)
\row \o XBM \o X11 Bitmap
\row \o XPM \o X11 Pixmap
\row \o SVG \o Scalable Vector Graphics
+ \row \o TGA \o Targa Image Format
\endtable
Reading and writing SVG files is supported through Qt's
\l{QtSvg Module}{SVG Module}.
+ TGA support only extends to reading non-RLE compressed files. In particular
+ calls to \l{http://doc.qt.nokia.com/4.7-snapshot/qimageioplugin.html#capabilities}{capabilities}
+ for the tga plugin returns only QImageIOPlugin::CanRead, not QImageIOPlugin::CanWrite.
+
To configure Qt with GIF support, pass \c -qt-gif to the \c
configure script or check the appropriate option in the graphical
installer.
diff --git a/src/gui/image/qtiffhandler.cpp b/src/gui/image/qtiffhandler.cpp
index 4dc9775..51a500d 100644
--- a/src/gui/image/qtiffhandler.cpp
+++ b/src/gui/image/qtiffhandler.cpp
@@ -158,7 +158,13 @@ bool QTiffHandler::canRead(QIODevice *device)
// current implementation uses TIFFClientOpen which needs to be
// able to seek, so sequential devices are not supported
+ int pos = device->pos();
+ if (pos != 0)
+ device->seek(0); // need the magic from the beginning
QByteArray header = device->peek(4);
+ if (pos != 0)
+ device->seek(pos); // put it back where we found it
+
return header == QByteArray::fromRawData("\x49\x49\x2A\x00", 4)
|| header == QByteArray::fromRawData("\x4D\x4D\x00\x2A", 4);
}
diff --git a/src/plugins/imageformats/imageformats.pro b/src/plugins/imageformats/imageformats.pro
index 5fff2de..54a2795 100644
--- a/src/plugins/imageformats/imageformats.pro
+++ b/src/plugins/imageformats/imageformats.pro
@@ -6,3 +6,4 @@ TEMPLATE = subdirs
contains(QT_CONFIG, svg):SUBDIRS += svg
!contains(QT_CONFIG, no-tiff):!contains(QT_CONFIG, tiff):SUBDIRS += tiff
!contains(QT_CONFIG, no-ico):SUBDIRS += ico
+!contains(QT_CONFIG, no-tga):SUBDIRS += tga
diff --git a/src/plugins/imageformats/tga/main.cpp b/src/plugins/imageformats/tga/main.cpp
new file mode 100644
index 0000000..8b1e070
--- /dev/null
+++ b/src/plugins/imageformats/tga/main.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qimageiohandler.h>
+#include <qdebug.h>
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+
+#ifdef QT_NO_IMAGEFORMAT_TGA
+#undef QT_NO_IMAGEFORMAT_TGA
+#endif
+
+#include "qtgahandler.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTgaPlugin : public QImageIOPlugin
+{
+public:
+ Capabilities capabilities(QIODevice * device, const QByteArray & format) const;
+ QImageIOHandler * create(QIODevice * device, const QByteArray & format = QByteArray()) const;
+ QStringList keys() const;
+};
+
+QImageIOPlugin::Capabilities QTgaPlugin::capabilities(QIODevice *device, const QByteArray &format) const
+{
+ if (format == "tga")
+ return Capabilities(CanRead);
+ if (!format.isEmpty())
+ return 0;
+ if (!device->isOpen())
+ return 0;
+
+ Capabilities cap;
+ if (device->isReadable() && QTgaHandler::canRead(device))
+ cap |= CanRead;
+ return cap;
+}
+
+QImageIOHandler* QTgaPlugin::create(QIODevice *device, const QByteArray &format) const
+{
+ QImageIOHandler *tgaHandler = new QTgaHandler();
+ tgaHandler->setDevice(device);
+ tgaHandler->setFormat(format);
+ return tgaHandler;
+}
+
+QStringList QTgaPlugin::keys() const
+{
+ return QStringList() << QLatin1String("tga");
+}
+
+Q_EXPORT_PLUGIN2(qtga, QTgaPlugin)
+
+QT_END_NAMESPACE
+
+#endif /* QT_NO_IMAGEFORMATPLUGIN */
diff --git a/src/plugins/imageformats/tga/qtgafile.cpp b/src/plugins/imageformats/tga/qtgafile.cpp
new file mode 100644
index 0000000..af7c876
--- /dev/null
+++ b/src/plugins/imageformats/tga/qtgafile.cpp
@@ -0,0 +1,239 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgafile.h"
+
+#include <QtCore/qiodevice.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qdatetime.h>
+
+struct TgaReader
+{
+ virtual ~TgaReader() {}
+ virtual QRgb operator()(QIODevice *s) const = 0;
+};
+
+struct Tga16Reader : public TgaReader
+{
+ ~Tga16Reader() {}
+ QRgb operator()(QIODevice *s) const
+ {
+ char ch1, ch2;
+ if (s->getChar(&ch1) && s->getChar(&ch2)) {
+ quint16 d = (int(ch1) & 0xFF) | ((int(ch2) & 0xFF) << 8);
+ QRgb result = (d & 0x8000) ? 0xFF000000 : 0x00000000;
+ result |= (d & 0x7C00 << 6) | (d & 0x03E0 << 3) | (d & 0x001F);
+ return result;
+ } else {
+ return 0;
+ }
+ }
+};
+
+struct Tga24Reader : public TgaReader
+{
+ QRgb operator()(QIODevice *s) const
+ {
+ char r, g, b;
+ if (s->getChar(&b) && s->getChar(&g) && s->getChar(&r))
+ return qRgb(uchar(r), uchar(g), uchar(b));
+ else
+ return 0;
+ }
+};
+
+struct Tga32Reader : public TgaReader
+{
+ QRgb operator()(QIODevice *s) const
+ {
+ char r, g, b, a;
+ if (s->getChar(&b) && s->getChar(&g) && s->getChar(&r) && s->getChar(&a))
+ return qRgba(uchar(r), uchar(g), uchar(b), uchar(a));
+ else
+ return 0;
+ }
+};
+
+/*!
+ \class QTgaFile
+ \since 4.8
+ \internal
+
+ File data container for a TrueVision Graphics format file.
+
+ Format is as described here:
+ http://local.wasp.uwa.edu.au/~pbourke/dataformats/tga/
+ http://netghost.narod.ru/gff2/graphics/summary/tga.htm
+
+ Usage is:
+ \code
+ QTgaFile tga(myFile);
+ QImage tgaImage;
+ if (tga.isValid())
+ tgaImage = tga.readImage();
+ \endcode
+
+ The class is designed to handle sequential and non-sequential
+ sources, so during construction the mHeader is read. Then during
+ the readImage() call the rest of the data is read.
+
+ After passing myFile to the constructor, if the QIODevice *myFile
+ is read, or has seek() called, the results are undefined - so don't
+ do that.
+*/
+
+/*!
+ Construct a new QTgaFile object getting data from \a device.
+
+ The object does not take ownership of the \a device, but until the
+ object is destroyed do not do any non-const operations, eg seek or
+ read on the device.
+*/
+QTgaFile::QTgaFile(QIODevice *device)
+ : mDevice(device)
+{
+ ::memset(mHeader, 0, HeaderSize);
+ if (!mDevice->isReadable())
+ {
+ mErrorMessage = QObject::tr("Could not read image data");
+ return;
+ }
+ if (mDevice->isSequential())
+ {
+ mErrorMessage = QObject::tr("Sequential device (eg socket) for image read not supported");
+ return;
+ }
+ if (!mDevice->seek(0))
+ {
+ mErrorMessage = QObject::tr("Seek file/device for image read failed");
+ return;
+ }
+ int bytes = device->read((char*)mHeader, HeaderSize);
+ if (bytes != HeaderSize)
+ {
+ mErrorMessage = QObject::tr("Image mHeader read failed");
+ return;
+ }
+ if (mHeader[ImageType] != 2)
+ {
+ // TODO: should support other image types
+ mErrorMessage = QObject::tr("Image type not supported");
+ return;
+ }
+}
+
+/*!
+ \internal
+ Destroy the device, recovering any resources.
+*/
+QTgaFile::~QTgaFile()
+{
+}
+
+/*!
+ \internal
+ Reads an image file from the QTgaFile's device, and returns it.
+
+ This method seeks to the absolute position of the image data in the file,
+ so no assumptions are made about where the devices read pointer is when this
+ method is called. For this reason only random access devices are supported.
+
+ If the constructor completed successfully, such that isValid() returns true,
+ then this method is likely to succeed, unless the file is somehow corrupted.
+
+ In the case that the read fails, the QImage returned will be null, such that
+ QImage::isNull() will be true.
+*/
+QImage QTgaFile::readImage()
+{
+ if (!isValid())
+ return QImage();
+
+ int offset = mHeader[IdLength]; // Mostly always zero
+
+ // Even in TrueColor files a color pallette may be present
+ if (mHeader[ColorMapType] == 1)
+ offset += littleEndianInt(&mHeader[CMapLength]) * littleEndianInt(&mHeader[CMapDepth]);
+
+ mDevice->seek(HeaderSize + offset);
+
+ char dummy;
+ for (int i = 0; i < offset; ++i)
+ mDevice->getChar(&dummy);
+
+ int bitsPerPixel = mHeader[PixelDepth];
+ int imageWidth = width();
+ int imageHeight = height();
+
+ unsigned char desc = mHeader[ImageDescriptor];
+ //unsigned char xCorner = desc & 0x10; // 0 = left, 1 = right
+ unsigned char yCorner = desc & 0x20; // 0 = lower, 1 = upper
+
+ QImage im(imageWidth, imageHeight, QImage::Format_ARGB32);
+ TgaReader *reader = 0;
+ if (bitsPerPixel == 16)
+ reader = new Tga16Reader();
+ else if (bitsPerPixel == 24)
+ reader = new Tga24Reader();
+ else if (bitsPerPixel == 32)
+ reader = new Tga32Reader();
+ TgaReader &read = *reader;
+
+ // For now only deal with yCorner, since no one uses xCorner == 1
+ // Also this is upside down, since Qt has the origin flipped
+ if (yCorner)
+ {
+ for (int y = 0; y < imageHeight; ++y)
+ for (int x = 0; x < imageWidth; ++x)
+ im.setPixel(x, y, read(mDevice));
+ }
+ else
+ {
+ for (int y = imageHeight - 1; y >= 0; --y)
+ for (int x = 0; x < imageWidth; ++x)
+ im.setPixel(x, y, read(mDevice));
+ }
+
+ delete reader;
+
+ // TODO: add processing of TGA extension information - ie TGA 2.0 files
+ return im;
+}
diff --git a/src/plugins/imageformats/tga/qtgafile.h b/src/plugins/imageformats/tga/qtgafile.h
new file mode 100644
index 0000000..034200e
--- /dev/null
+++ b/src/plugins/imageformats/tga/qtgafile.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGAFILE_H
+#define QTGAFILE_H
+
+#include <QtGui/qcolor.h>
+#include <QtGui/qimage.h>
+
+class QIODevice;
+
+class QTgaFile
+{
+public:
+ enum Compression {
+ NoCompression = 0,
+ RleCompression = 1
+ };
+
+ enum HeaderOffset {
+ IdLength = 0, /* 00h Size of Image ID field */
+ ColorMapType = 1, /* 01h Color map type */
+ ImageType = 2, /* 02h Image type code */
+ CMapStart = 3, /* 03h Color map origin */
+ CMapLength = 5, /* 05h Color map length */
+ CMapDepth = 7, /* 07h Depth of color map entries */
+ XOffset = 8, /* 08h X origin of image */
+ YOffset = 10, /* 0Ah Y origin of image */
+ Width = 12, /* 0Ch Width of image */
+ Height = 14, /* 0Eh Height of image */
+ PixelDepth = 16, /* 10h Image pixel size */
+ ImageDescriptor = 17, /* 11h Image descriptor byte */
+ HeaderSize = 18
+ };
+
+ QTgaFile(QIODevice *);
+ ~QTgaFile();
+
+ inline bool isValid() const;
+ inline QString errorMessage() const;
+ QImage readImage();
+ inline int xOffset() const;
+ inline int yOffset() const;
+ inline int width() const;
+ inline int height() const;
+ inline QSize size() const;
+ inline Compression compression() const;
+
+private:
+ static inline quint16 littleEndianInt(const unsigned char *d);
+
+ QString mErrorMessage;
+ unsigned char mHeader[HeaderSize];
+ QIODevice *mDevice;
+};
+
+inline bool QTgaFile::isValid() const
+{
+ return mErrorMessage.isEmpty();
+}
+
+inline QString QTgaFile::errorMessage() const
+{
+ return mErrorMessage;
+}
+
+/*!
+ \internal
+ Returns the integer encoded in the two little endian bytes at \a d.
+*/
+inline quint16 QTgaFile::littleEndianInt(const unsigned char *d)
+{
+ return d[0] + d[1] * 256;
+}
+
+inline int QTgaFile::xOffset() const
+{
+ return littleEndianInt(&mHeader[XOffset]);
+}
+
+inline int QTgaFile::yOffset() const
+{
+ return littleEndianInt(&mHeader[YOffset]);
+}
+
+inline int QTgaFile::width() const
+{
+ return littleEndianInt(&mHeader[Width]);
+}
+
+inline int QTgaFile::height() const
+{
+ return littleEndianInt(&mHeader[Height]);
+}
+
+inline QSize QTgaFile::size() const
+{
+ return QSize(width(), height());
+}
+
+inline QTgaFile::Compression QTgaFile::compression() const
+{
+ // TODO: for now, only handle type 2 files, with no color table
+ // and no compression
+ return NoCompression;
+}
+
+#endif // QTGAFILE_H
diff --git a/src/plugins/imageformats/tga/qtgahandler.cpp b/src/plugins/imageformats/tga/qtgahandler.cpp
new file mode 100644
index 0000000..2464daa
--- /dev/null
+++ b/src/plugins/imageformats/tga/qtgahandler.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgahandler.h"
+#include "qtgafile.h"
+
+#include <qvariant.h>
+#include <qdebug.h>
+#include <qimage.h>
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+QTgaHandler::QTgaHandler()
+ : QImageIOHandler()
+ , tga(0)
+{
+}
+
+QTgaHandler::~QTgaHandler()
+{
+ delete tga;
+}
+
+bool QTgaHandler::canRead() const
+{
+ if (!tga)
+ tga = new QTgaFile(device());
+ if (tga->isValid())
+ {
+ setFormat("tga");
+ return true;
+ }
+ return false;
+}
+
+bool QTgaHandler::canRead(QIODevice *device)
+{
+ if (!device) {
+ qWarning("QTgaHandler::canRead() called with no device");
+ return false;
+ }
+ QTgaFile tga(device);
+ return tga.isValid();
+}
+
+bool QTgaHandler::read(QImage *image)
+{
+ if (!canRead())
+ return false;
+ *image = tga->readImage();
+ return !image->isNull();
+}
+
+QByteArray QTgaHandler::name() const
+{
+ return "tga";
+}
+
+QVariant QTgaHandler::option(ImageOption option) const
+{
+ if (option == Size && canRead()) {
+ return tga->size();
+ } else if (option == CompressionRatio) {
+ return tga->compression();
+ } else if (option == ImageFormat) {
+ return QImage::Format_ARGB32;
+ }
+ return QVariant();
+}
+
+void QTgaHandler::setOption(ImageOption option, const QVariant &value)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(value);
+}
+
+bool QTgaHandler::supportsOption(ImageOption option) const
+{
+ return option == CompressionRatio
+ || option == Size
+ || option == ImageFormat;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/imageformats/tga/qtgahandler.h b/src/plugins/imageformats/tga/qtgahandler.h
new file mode 100644
index 0000000..88e2b94
--- /dev/null
+++ b/src/plugins/imageformats/tga/qtgahandler.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGAHANDLER_H
+#define QTGAHANDLER_H
+
+#include <QtGui/qimageiohandler.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTgaFile;
+
+class QTgaHandler : public QImageIOHandler
+{
+public:
+ QTgaHandler();
+ ~QTgaHandler();
+
+ bool canRead() const;
+ bool read(QImage *image);
+
+ QByteArray name() const;
+
+ static bool canRead(QIODevice *device);
+
+ QVariant option(ImageOption option) const;
+ void setOption(ImageOption option, const QVariant &value);
+ bool supportsOption(ImageOption option) const;
+
+private:
+ mutable QTgaFile *tga;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTGAHANDLER_H
diff --git a/src/plugins/imageformats/tga/tga.pro b/src/plugins/imageformats/tga/tga.pro
new file mode 100644
index 0000000..292d06e
--- /dev/null
+++ b/src/plugins/imageformats/tga/tga.pro
@@ -0,0 +1,16 @@
+TARGET = qtga
+include(../../qpluginbase.pri)
+
+QTDIR_build:REQUIRES = "!contains(QT_CONFIG, no-tga)"
+
+HEADERS += qtgahandler.h \
+ qtgafile.h
+SOURCES += main.cpp \
+ qtgahandler.cpp \
+ qtgafile.cpp
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/imageformats
+target.path += $$[QT_INSTALL_PLUGINS]/imageformats
+INSTALLS += target
+
+symbian: TARGET.UID3=0x20031E99
diff --git a/tests/auto/qimagereader/images/test-flag-rle.tga b/tests/auto/qimagereader/images/test-flag-rle.tga
new file mode 100644
index 0000000..c14c712
--- /dev/null
+++ b/tests/auto/qimagereader/images/test-flag-rle.tga
Binary files differ
diff --git a/tests/auto/qimagereader/images/test-flag.tga b/tests/auto/qimagereader/images/test-flag.tga
new file mode 100644
index 0000000..c6d0c89
--- /dev/null
+++ b/tests/auto/qimagereader/images/test-flag.tga
Binary files differ
diff --git a/tests/auto/qimagereader/qimagereader.pro b/tests/auto/qimagereader/qimagereader.pro
index 827819d..a9bfa1d 100644
--- a/tests/auto/qimagereader/qimagereader.pro
+++ b/tests/auto/qimagereader/qimagereader.pro
@@ -10,6 +10,7 @@ RESOURCES += qimagereader.qrc
!contains(QT_CONFIG, no-mng):DEFINES += QTEST_HAVE_MNG
!contains(QT_CONFIG, no-tiff):DEFINES += QTEST_HAVE_TIFF
!contains(QT_CONFIG, no-svg):DEFINES += QTEST_HAVE_SVG
+!contains(QT_CONFIG, no-tga):DEFINES += QTEST_HAVE_TGA
win32-msvc:QMAKE_CXXFLAGS -= -Zm200
win32-msvc:QMAKE_CXXFLAGS += -Zm800
diff --git a/tests/auto/qimagereader/qimagereader.qrc b/tests/auto/qimagereader/qimagereader.qrc
index 2c70652..03c03d6 100644
--- a/tests/auto/qimagereader/qimagereader.qrc
+++ b/tests/auto/qimagereader/qimagereader.qrc
@@ -67,5 +67,7 @@
<file>images/corrupt.svgz</file>
<file>images/qtbug13653-no_eoi.jpg</file>
<file>images/txts.png</file>
+ <file>images/test-flag.tga</file>
+ <file>images/test-flag-rle.tga</file>
</qresource>
</RCC>
diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp
index 5d958d7..5bf9d19 100644
--- a/tests/auto/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/qimagereader/tst_qimagereader.cpp
@@ -168,6 +168,10 @@ private slots:
void tiffGrayscale();
#endif
+#if defined QTEST_HAVE_TGA
+ void tgaTestImages();
+#endif
+
void autoDetectImageFormat();
void fileNameProbing();
@@ -569,6 +573,10 @@ void tst_QImageReader::imageFormat_data()
QTest::newRow("mng-2") << QString("fire.mng") << QByteArray("mng") << QImage::Format_Invalid;
QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg") << QImage::Format_ARGB32_Premultiplied;
QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz") << QImage::Format_ARGB32_Premultiplied;
+#if defined QTEST_HAVE_TGA
+ QTest::newRow("tga") << QString("test-flag.tga") << QByteArray("tga") << QImage::Format_ARGB32;
+ QTest::newRow("tga-rle") << QString("test-flag-rle.tga") << QByteArray("tga") << QImage::Format_ARGB32;
+#endif
}
void tst_QImageReader::imageFormat()
@@ -578,22 +586,31 @@ void tst_QImageReader::imageFormat()
QFETCH(QImage::Format, imageFormat);
if (QImageReader::imageFormat(prefix + fileName).isEmpty()) {
- if (QByteArray("jpeg") == format)
+ if (QByteArray("jpeg") == format) {
#ifndef QTEST_HAVE_JPEG
return;
#endif // !QTEST_HAVE_JPEG
- if (QByteArray("gif") == format)
+ }
+ if (QByteArray("gif") == format) {
#ifndef QTEST_HAVE_GIF
return;
#endif // !QTEST_HAVE_GIF
- if (QByteArray("mng") == format)
+ }
+ if (QByteArray("mng") == format) {
#ifndef QTEST_HAVE_MNG
return;
#endif // !QTEST_HAVE_MNG
- if (QByteArray("svg") == format || QByteArray("svgz") == format)
+ }
+ if (QByteArray("svg") == format || QByteArray("svgz") == format) {
#ifndef QTEST_HAVE_SVG
return;
#endif // !QTEST_HAVE_SVG
+ }
+ if (QByteArray("tga") == format) {
+#ifndef QTEST_HAVE_TGA
+ return;
+#endif // !QTEST_HAVE_TGA
+ }
QSKIP(("Qt does not support the " + format + " format.").constData(), SkipSingle);
} else {
QCOMPARE(QImageReader::imageFormat(prefix + fileName), format);
@@ -734,6 +751,11 @@ void tst_QImageReader::sizeBeforeRead()
{
QFETCH(QString, fileName);
QFETCH(QByteArray, format);
+
+ if (fileName == QLatin1String("test-flag-rle.tga")) {
+ QSKIP("Qt does not support reading RLE compressed TGA files", SkipSingle);
+ }
+
QImageReader reader(prefix + fileName);
QVERIFY(reader.canRead());
if (format == "mng") {
@@ -1711,6 +1733,27 @@ void tst_QImageReader::tiffGrayscale()
}
#endif
+#if defined QTEST_HAVE_TGA
+void tst_QImageReader::tgaTestImages()
+{
+ QImage tgaTest(prefix + "test-flag.tga");
+
+ // Test image is 400x400 of a "flag" with a blue circle in the middle
+ // and a green square top left, and red rectangle on the bottom so
+ // so we test for pixels in those areas to ensure the image is not
+ // inverted or the palette is not messed up.
+ QVERIFY(!tgaTest.isNull());
+ QCOMPARE(tgaTest.size().width(), 400);
+ QCOMPARE(tgaTest.size().height(), 400);
+ QRgb pixel = tgaTest.pixel(200,200);
+ QCOMPARE(qRgb(0, 0, 255), pixel);
+ pixel = tgaTest.pixel(0, 0);
+ QCOMPARE(qRgb(0, 255, 0), pixel);
+ pixel = tgaTest.pixel(0, 399);
+ QCOMPARE(qRgb(255, 0, 0), pixel);
+}
+#endif
+
void tst_QImageReader::dotsPerMeter_data()
{
QTest::addColumn<QString>("fileName");