diff options
Diffstat (limited to 'src/plugins')
-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 |
7 files changed, 731 insertions, 0 deletions
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 |