diff options
-rw-r--r-- | src/declarative/debugger/qdeclarativedebugserver.cpp | 15 | ||||
-rw-r--r-- | src/gui/image/qimagereader.cpp | 5 | ||||
-rw-r--r-- | src/gui/image/qtiffhandler.cpp | 6 | ||||
-rw-r--r-- | src/plugins/imageformats/imageformats.pro | 1 | ||||
-rw-r--r-- | src/plugins/imageformats/tga/main.cpp | 95 | ||||
-rw-r--r-- | src/plugins/imageformats/tga/qtgafile.cpp | 266 | ||||
-rw-r--r-- | src/plugins/imageformats/tga/qtgafile.h | 157 | ||||
-rw-r--r-- | src/plugins/imageformats/tga/qtgahandler.cpp | 122 | ||||
-rw-r--r-- | src/plugins/imageformats/tga/qtgahandler.h | 74 | ||||
-rw-r--r-- | src/plugins/imageformats/tga/tga.pro | 16 | ||||
-rw-r--r-- | tests/auto/qimagereader/images/test-flag-rle.tga | bin | 0 -> 7971 bytes | |||
-rw-r--r-- | tests/auto/qimagereader/images/test-flag.tga | bin | 0 -> 480044 bytes | |||
-rw-r--r-- | tests/auto/qimagereader/qimagereader.pro | 1 | ||||
-rw-r--r-- | tests/auto/qimagereader/qimagereader.qrc | 2 | ||||
-rw-r--r-- | tests/auto/qimagereader/tst_qimagereader.cpp | 51 | ||||
-rw-r--r-- | tools/qmlplugindump/main.cpp | 35 |
16 files changed, 830 insertions, 16 deletions
diff --git a/src/declarative/debugger/qdeclarativedebugserver.cpp b/src/declarative/debugger/qdeclarativedebugserver.cpp index 3e0c326..05f63c7 100644 --- a/src/declarative/debugger/qdeclarativedebugserver.cpp +++ b/src/declarative/debugger/qdeclarativedebugserver.cpp @@ -96,7 +96,7 @@ public: private: // private slot void _q_deliverMessage(const QString &serviceName, const QByteArray &message); - static QDeclarativeDebugServerConnection *loadConnectionPlugin(const QString &pluginName); + static QDeclarativeDebugServerConnection *loadConnectionPlugin(QPluginLoader *loader, const QString &pluginName); }; QDeclarativeDebugServerPrivate::QDeclarativeDebugServerPrivate() : @@ -120,7 +120,7 @@ void QDeclarativeDebugServerPrivate::advertisePlugins() } QDeclarativeDebugServerConnection *QDeclarativeDebugServerPrivate::loadConnectionPlugin( - const QString &pluginName) + QPluginLoader *loader, const QString &pluginName) { #ifndef QT_NO_LIBRARY QStringList pluginCandidates; @@ -137,17 +137,17 @@ QDeclarativeDebugServerConnection *QDeclarativeDebugServerPrivate::loadConnectio } foreach (const QString &pluginPath, pluginCandidates) { - QPluginLoader loader(pluginPath); - if (!loader.load()) { + loader->setFileName(pluginPath); + if (!loader->load()) { continue; } QDeclarativeDebugServerConnection *connection = 0; - if (QObject *instance = loader.instance()) + if (QObject *instance = loader->instance()) connection = qobject_cast<QDeclarativeDebugServerConnection*>(instance); if (connection) return connection; - loader.unload(); + loader->unload(); } #endif return 0; @@ -202,8 +202,9 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() if (ok) { server = new QDeclarativeDebugServer(); + QPluginLoader *loader = new QPluginLoader(server); QDeclarativeDebugServerConnection *connection - = QDeclarativeDebugServerPrivate::loadConnectionPlugin(pluginName); + = QDeclarativeDebugServerPrivate::loadConnectionPlugin(loader, pluginName); if (connection) { server->d_func()->connection = connection; 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..5650be2 --- /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 <QtGui/QImageIOHandler> +#include <QtCore/QDebug> + +#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..885a63c --- /dev/null +++ b/src/plugins/imageformats/tga/qtgafile.cpp @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** 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> +#include <QtCore/QDebug> +#include <QtCore/QDateTime> + +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; + } + int bitsPerPixel = mHeader[PixelDepth]; + bool validDepth = (bitsPerPixel == 16 || bitsPerPixel == 24 || bitsPerPixel == 32); + if (!validDepth) + { + mErrorMessage = QObject::tr("Image dpeth not valid"); + } + int curPos = mDevice->pos(); + int fileBytes = mDevice->size(); + if (!mDevice->seek(fileBytes - FooterSize)) + { + mErrorMessage = QObject::tr("Could not seek to image read footer"); + return; + } + char footer[FooterSize]; + bytes = mDevice->read((char*)footer, FooterSize); + if (bytes != FooterSize) + { + mErrorMessage = QObject::tr("Could not read footer"); + } + if (qstrncmp(&footer[SignatureOffset], "TRUEVISION-XFILE", 16) != 0) + { + mErrorMessage = QObject::tr("Image type (non-TrueVision 2.0) not supported"); + } + if (!mDevice->seek(curPos)) + { + mErrorMessage = QObject::tr("Could not reset to read data"); + } +} + +/*! + \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..264c18b --- /dev/null +++ b/src/plugins/imageformats/tga/qtgafile.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** 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> +#include <QtGui/QImage> + +QT_BEGIN_NAMESPACE + +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 + }; + + enum FooterOffset { + ExtensionOffset = 0, + DeveloperOffset = 4, + SignatureOffset = 8, + FooterSize = 26 + }; + + 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; +} + +QT_END_NAMESPACE + +#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..ddea4f2 --- /dev/null +++ b/src/plugins/imageformats/tga/qtgahandler.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** 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 <QtCore/QVariant> +#include <QtCore/QDebug> +#include <QtGui/QImage> + +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..f0eb2b0 --- /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> + +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 Binary files differnew file mode 100644 index 0000000..c14c712 --- /dev/null +++ b/tests/auto/qimagereader/images/test-flag-rle.tga diff --git a/tests/auto/qimagereader/images/test-flag.tga b/tests/auto/qimagereader/images/test-flag.tga Binary files differnew file mode 100644 index 0000000..c6d0c89 --- /dev/null +++ b/tests/auto/qimagereader/images/test-flag.tga 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..2b867c3 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"); diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 6bef8d4..4f523b9 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -147,6 +147,31 @@ QByteArray convertToId(const QByteArray &cppName) return cppToId.value(cppName, cppName); } +QByteArray convertToId(const QMetaObject *mo) +{ + QByteArray className(mo->className()); + if (!className.isEmpty()) + return convertToId(className); + + // likely a metaobject generated for an extended qml object + if (mo->superClass()) { + className = convertToId(mo->superClass()); + className.append("_extended"); + return className; + } + + static QHash<const QMetaObject *, QByteArray> generatedNames; + className = generatedNames.value(mo); + if (!className.isEmpty()) + return className; + + qWarning() << "Found a QMetaObject without a className, generating a random name"; + className = QByteArray("error-unknown-name-"); + className.append(QByteArray::number(generatedNames.size())); + generatedNames.insert(mo, className); + return className; +} + QSet<const QMetaObject *> collectReachableMetaObjects(const QList<QDeclarativeType *> &skip = QList<QDeclarativeType *>()) { QSet<const QMetaObject *> metas; @@ -241,7 +266,7 @@ public: { qml->writeStartObject("Component"); - QByteArray id = convertToId(meta->className()); + QByteArray id = convertToId(meta); qml->writeScriptBinding(QLatin1String("name"), enquote(id)); for (int index = meta->classInfoCount() - 1 ; index >= 0 ; --index) { @@ -253,7 +278,7 @@ public: } if (meta->superClass()) - qml->writeScriptBinding(QLatin1String("prototype"), enquote(convertToId(meta->superClass()->className()))); + qml->writeScriptBinding(QLatin1String("prototype"), enquote(convertToId(meta->superClass()))); QSet<const QDeclarativeType *> qmlTypes = qmlTypesByCppName.value(meta->className()); if (!qmlTypes.isEmpty()) { @@ -284,7 +309,7 @@ public: if (const QMetaObject *attachedType = (*qmlTypes.begin())->attachedPropertiesType()) { qml->writeScriptBinding(QLatin1String("attachedType"), enquote( - convertToId(attachedType->className()))); + convertToId(attachedType))); } } @@ -624,7 +649,7 @@ int main(int argc, char *argv[]) // put the metaobjects into a map so they are always dumped in the same order QMap<QString, const QMetaObject *> nameToMeta; foreach (const QMetaObject *meta, metas) - nameToMeta.insert(convertToId(meta->className()), meta); + nameToMeta.insert(convertToId(meta), meta); Dumper dumper(&qml); if (relocatable) @@ -641,7 +666,7 @@ int main(int argc, char *argv[]) qml.writeEndObject(); qml.writeEndDocument(); - std::cout << bytes.constData(); + std::cout << bytes.constData() << std::flush; // workaround to avoid crashes on exit QTimer timer; |