Qt 4.8
qimagewriter.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
102 #include "qimagewriter.h"
103 
104 #include <qbytearray.h>
105 #include <qfile.h>
106 #include <qfileinfo.h>
107 #include <qimageiohandler.h>
108 #include <qset.h>
109 #include <qvariant.h>
110 
111 // factory loader
112 #include <qcoreapplication.h>
113 #include <private/qfactoryloader_p.h>
114 
115 // image handlers
116 #include <private/qbmphandler_p.h>
117 #include <private/qppmhandler_p.h>
118 #include <private/qxbmhandler_p.h>
119 #include <private/qxpmhandler_p.h>
120 #ifndef QT_NO_IMAGEFORMAT_PNG
121 #include <private/qpnghandler_p.h>
122 #endif
123 #ifndef QT_NO_IMAGEFORMAT_JPEG
124 #include <private/qjpeghandler_p.h>
125 #endif
126 #ifndef QT_NO_IMAGEFORMAT_MNG
127 #include <private/qmnghandler_p.h>
128 #endif
129 #ifndef QT_NO_IMAGEFORMAT_TIFF
130 #include <private/qtiffhandler_p.h>
131 #endif
132 #ifdef QT_BUILTIN_GIF_READER
133 #include <private/qgifhandler_p.h>
134 #endif
135 
137 
138 #ifndef QT_NO_LIBRARY
141 #endif
142 
143 static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
144  const QByteArray &format)
145 {
146  QByteArray form = format.toLower();
149 
150 #ifndef QT_NO_LIBRARY
151  // check if any plugins can write the image
152  QFactoryLoader *l = loader();
155 #endif
156 
157  if (device && format.isEmpty()) {
158  // if there's no format, see if \a device is a file, and if so, find
159  // the file suffix and find support for that format among our plugins.
160  // this allows plugins to override our built-in handlers.
161  if (QFile *file = qobject_cast<QFile *>(device)) {
162  if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) {
163 #ifndef QT_NO_LIBRARY
164  int index = keys.indexOf(QString::fromLatin1(suffix));
165  if (index != -1)
166  suffixPluginIndex = index;
167 #endif
168  }
169  }
170  }
171 
172  QByteArray testFormat = !form.isEmpty() ? form : suffix;
173 
174 #ifndef QT_NO_LIBRARY
175  if (suffixPluginIndex != -1) {
176  // when format is missing, check if we can find a plugin for the
177  // suffix.
179  if (plugin && (plugin->capabilities(device, suffix) & QImageIOPlugin::CanWrite))
180  handler = plugin->create(device, suffix);
181  }
182 #endif // QT_NO_LIBRARY
183 
184  // check if any built-in handlers can write the image
185  if (!handler && !testFormat.isEmpty()) {
186  if (false) {
187 #ifndef QT_NO_IMAGEFORMAT_PNG
188  } else if (testFormat == "png") {
189  handler = new QPngHandler;
190 #endif
191 #ifndef QT_NO_IMAGEFORMAT_JPEG
192  } else if (testFormat == "jpg" || testFormat == "jpeg") {
193  handler = new QJpegHandler;
194 #endif
195 #ifndef QT_NO_IMAGEFORMAT_MNG
196  } else if (testFormat == "mng") {
197  handler = new QMngHandler;
198 #endif
199 #ifndef QT_NO_IMAGEFORMAT_TIFF
200  } else if (testFormat == "tif" || testFormat == "tiff") {
201  handler = new QTiffHandler;
202 #endif
203 #ifdef QT_BUILTIN_GIF_READER
204  } else if (testFormat == "gif") {
205  handler = new QGifHandler;
206 #endif
207 #ifndef QT_NO_IMAGEFORMAT_BMP
208  } else if (testFormat == "bmp") {
209  handler = new QBmpHandler;
210 #endif
211 #ifndef QT_NO_IMAGEFORMAT_XPM
212  } else if (testFormat == "xpm") {
213  handler = new QXpmHandler;
214 #endif
215 #ifndef QT_NO_IMAGEFORMAT_XBM
216  } else if (testFormat == "xbm") {
217  handler = new QXbmHandler;
218  handler->setOption(QImageIOHandler::SubType, testFormat);
219 #endif
220 #ifndef QT_NO_IMAGEFORMAT_PPM
221  } else if (testFormat == "pbm" || testFormat == "pbmraw" || testFormat == "pgm"
222  || testFormat == "pgmraw" || testFormat == "ppm" || testFormat == "ppmraw") {
223  handler = new QPpmHandler;
224  handler->setOption(QImageIOHandler::SubType, testFormat);
225 #endif
226  }
227  }
228 
229 #ifndef QT_NO_LIBRARY
230  if (!testFormat.isEmpty()) {
231  for (int i = 0; i < keys.size(); ++i) {
232  QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
233  if (plugin && (plugin->capabilities(device, testFormat) & QImageIOPlugin::CanWrite)) {
234  delete handler;
235  handler = plugin->create(device, testFormat);
236  break;
237  }
238  }
239  }
240 #endif // QT_NO_LIBRARY
241 
242  if (!handler)
243  return 0;
244 
245  handler->setDevice(device);
246  if (!testFormat.isEmpty())
247  handler->setFormat(testFormat);
248  return handler;
249 }
250 
252 {
253 public:
255 
256  // device
261 
262  // image options
263  int quality;
265  float gamma;
268 
269  // error
272 
274 };
275 
280 {
281  device = 0;
282  deleteDevice = false;
283  handler = 0;
284  quality = -1;
285  compression = 0;
286  gamma = 0.0;
289 
290  q = qq;
291 }
292 
299  : d(new QImageWriterPrivate(this))
300 {
301 }
302 
308  : d(new QImageWriterPrivate(this))
309 {
310  d->device = device;
311  d->format = format;
312 }
313 
321  : d(new QImageWriterPrivate(this))
322 {
323  QFile *file = new QFile(fileName);
324  d->device = file;
325  d->deleteDevice = true;
326  d->format = format;
327 }
328 
333 {
334  if (d->deleteDevice)
335  delete d->device;
336  delete d->handler;
337  delete d;
338 }
339 
352 {
353  d->format = format;
354 }
355 
362 {
363  return d->format;
364 }
365 
380 {
381  if (d->device && d->deleteDevice)
382  delete d->device;
383 
384  d->device = device;
385  d->deleteDevice = false;
386  delete d->handler;
387  d->handler = 0;
388 }
389 
395 {
396  return d->device;
397 }
398 
406 {
407  setDevice(new QFile(fileName));
408  d->deleteDevice = true;
409 }
410 
421 {
422  QFile *file = qobject_cast<QFile *>(d->device);
423  return file ? file->fileName() : QString();
424 }
425 
438 {
439  d->quality = quality;
440 }
441 
448 {
449  return d->quality;
450 }
451 
464 {
466 }
467 
474 {
475  return d->compression;
476 }
477 
489 {
490  d->gamma = gamma;
491 }
492 
498 float QImageWriter::gamma() const
499 {
500  return d->gamma;
501 }
502 
520 {
522 }
523 
537 {
538  return d->description;
539 }
540 
566 {
567  if (!d->description.isEmpty())
568  d->description += QLatin1String("\n\n");
569  d->description += key.simplified() + QLatin1String(": ") + text.simplified();
570 }
571 
579 {
580  if (d->device && !d->handler && (d->handler = createWriteHandlerHelper(d->device, d->format)) == 0) {
583  QLatin1String("Unsupported image format"));
584  return false;
585  }
586  if (d->device && !d->device->isOpen())
588  if (!d->device || !d->device->isWritable()) {
591  QLatin1String("Device not writable"));
592  return false;
593  }
594  return true;
595 }
596 
606 bool QImageWriter::write(const QImage &image)
607 {
608  if (!canWrite())
609  return false;
610 
619 
620  if (!d->handler->write(image))
621  return false;
622  if (QFile *file = qobject_cast<QFile *>(d->device))
623  file->flush();
624  return true;
625 }
626 
633 {
634  return d->imageWriterError;
635 }
636 
643 {
644  return d->errorString;
645 }
646 
668 {
669  if (!d->handler && (d->handler = createWriteHandlerHelper(d->device, d->format)) == 0) {
672  QLatin1String("Unsupported image format"));
673  return false;
674  }
675 
676  return d->handler->supportsOption(option);
677 }
678 
705 {
706  QSet<QByteArray> formats;
707  formats << "bmp";
708 #ifndef QT_NO_IMAGEFORMAT_PPM
709  formats << "ppm";
710 #endif
711 #ifndef QT_NO_IMAGEFORMAT_XBM
712  formats << "xbm";
713 #endif
714 #ifndef QT_NO_IMAGEFORMAT_XPM
715  formats << "xpm";
716 #endif
717 #ifndef QT_NO_IMAGEFORMAT_PNG
718  formats << "png";
719 #endif
720 #ifndef QT_NO_IMAGEFORMAT_JPEG
721  formats << "jpg" << "jpeg";
722 #endif
723 #ifndef QT_NO_IMAGEFORMAT_MNG
724  formats << "mng";
725 #endif
726 #ifndef QT_NO_IMAGEFORMAT_TIFF
727  formats << "tif" << "tiff";
728 #endif
729 #ifdef QT_BUILTIN_GIF_READER
730  formats << "gif";
731 #endif
732 
733 #ifndef QT_NO_LIBRARY
734  QFactoryLoader *l = loader();
735  QStringList keys = l->keys();
736  for (int i = 0; i < keys.count(); ++i) {
737  QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
738  if (plugin && (plugin->capabilities(0, keys.at(i).toLatin1()) & QImageIOPlugin::CanWrite) != 0)
739  formats << keys.at(i).toLatin1();
740  }
741 #endif // QT_NO_LIBRARY
742 
743  QList<QByteArray> sortedFormats;
744  for (QSet<QByteArray>::ConstIterator it = formats.constBegin(); it != formats.constEnd(); ++it)
745  sortedFormats << *it;
746 
747  qSort(sortedFormats);
748  return sortedFormats;
749 }
750 
QImageWriterPrivate * d
Definition: qimagewriter.h:109
T qobject_cast(QObject *object)
Definition: qobject.h:375
double d
Definition: qnumeric_p.h:62
QImageWriterPrivate(QImageWriter *qq)
QString fileName() const
Returns the name set by setFileName() or to the QFile constructors.
Definition: qfile.cpp:470
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
virtual Capabilities capabilities(QIODevice *device, const QByteArray &format) const =0
Returns the capabilities on the plugin, based on the data in device and the format format...
#define QImageIOHandlerFactoryInterface_iid
int suffixPluginIndex
ImageWriterError
This enum describes errors that can occur when writing images with QImageWriter.
Definition: qimagewriter.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QString fileName() const
If the currently assigned device is a QFile, or if setFileName() has been called, this function retur...
bool isWritable() const
Returns true if data can be written to the device; otherwise returns false.
Definition: qiodevice.cpp:558
#define it(className, varName)
bool supportsOption(QImageIOHandler::ImageOption option) const
Returns true if the writer supports option; otherwise returns false.
void setFileName(const QString &fileName)
Sets the file name of QImageWriter to fileName.
const_iterator constEnd() const
Definition: qset.h:171
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QByteArray format() const
Returns the format QImageWriter uses for writing images.
void setQuality(int quality)
This is an image format specific function that sets the quality level of the image to quality...
QByteArray toLower() const
Returns a lowercase copy of the byte array.
#define QT_TRANSLATE_NOOP(scope, x)
Marks the string literal sourceText for dynamic translation in the given context; i...
Definition: qglobal.h:2487
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
T * qobject_cast(QObject *object)
Definition: qobject.h:375
QImageIOHandler * handler
QStringList keys
virtual bool write(const QImage &image)
Writes the image image to the assigned device.
virtual void setOption(ImageOption option, const QVariant &value)
Sets the option option with the value value.
QIODevice * device() const
Returns the device currently assigned to QImageWriter, or 0 if no device has been assigned...
QStringList keys() const
int indexOf(const QRegExp &rx, int from=0) const
Returns the index position of the first exact match of rx in the list, searching forward from index p...
Definition: qstringlist.h:195
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool isOpen() const
Returns true if the device is open; otherwise returns false.
Definition: qiodevice.cpp:530
static bool isEmpty(const char *str)
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
The QImageWriter class provides a format independent interface for writing images to files or other d...
Definition: qimagewriter.h:59
ImageOption
This enum describes the different options supported by QImageIOHandler.
QImageWriter::ImageWriterError imageWriterError
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
QImageWriter * q
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
float gamma() const
Returns the gamma level of the image.
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
QByteArray testFormat
void qSort(RandomAccessIterator start, RandomAccessIterator end)
Definition: qalgorithms.h:177
virtual QImageIOHandler * create(QIODevice *device, const QByteArray &format=QByteArray()) const =0
Creates and returns a QImageIOHandler subclass, with device and format set.
~QImageWriter()
Destructs the QImageWriter object.
void setDevice(QIODevice *device)
Sets QImageWriter&#39;s device to device.
bool canWrite() const
Returns true if QImageWriter can write the image; i.e., the image format is supported and the assigne...
void setGamma(float gamma)
This is an image format specific function that sets the gamma level of the image to gamma...
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,(QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))) static QImageIOHandler *createWriteHandlerHelper(QIODevice *device
void setDevice(QIODevice *device)
Sets the device of the QImageIOHandler to device.
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
The QImageIOPlugin class defines an interface for writing an image format plugin. ...
QString simplified() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end, and that has each sequence o...
Definition: qstring.cpp:4415
The QImageIOHandler class defines the common image I/O interface for all image formats in Qt...
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
QObject * instance(const QString &key) const
QString description() const
Use QImageReader::text() instead.
int key
QByteArray suffix
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
int quality() const
Returns the quality level of the image.
QFactoryLoader * l
const_iterator constBegin() const
Definition: qset.h:168
virtual bool open(OpenMode mode)
Opens the device and sets its OpenMode to mode.
Definition: qiodevice.cpp:570
quint16 index
ImageWriterError error() const
Returns the type of error that last occurred.
void setFormat(const QByteArray &format)
Sets the format QImageWriter will use when writing images, to format.
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
void setText(const QString &key, const QString &text)
Sets the image text associated with the key key to text.
void setDescription(const QString &description)
Use setText() instead.
static QList< QByteArray > supportedImageFormats()
Returns the list of image formats supported by QImageWriter.
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:60
QImageIOHandler * handler
virtual bool supportsOption(ImageOption option) const
Returns true if the QImageIOHandler supports the option option; otherwise returns false...
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
QImageWriter()
Constructs an empty QImageWriter object.
int compression() const
Returns the compression of the image.
bool write(const QImage &image)
Writes the image image to the assigned device or file name.
QString errorString() const
Returns a human readable description of the last error that occurred.
#define text
Definition: qobjectdefs.h:80
void setCompression(int compression)
This is an image format specific function that set the compression of an image.