diff options
author | Andy Maloney <asmaloney@gmail.com> | 2015-01-02 09:48:44 -0500 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2015-01-09 10:36:08 +0100 |
commit | 163af2cf53d3441b453744b99254c07a175af5de (patch) | |
tree | 43f126bf95d3c776041c1c5df5d15666fa3bdaed /src | |
parent | fc5e6b37a1c49d150886543f87d6fc1817060534 (diff) |
Add OptimizedWrite & ProgressiveScanWrite options to QImageIOHandler and use for JPEG writing
Exposes two options from libjpeg: the optimize option and progressive scan option.
These are both lossless operations, so they do not change the image's quality.
Using these switches can result in smaller jpeg files.
Task-number: QTBUG-20075
Change-Id: I8d0bd6a712b8a365265b7bd517e136b0755b90cb
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Reviewed-by: aavit <eirik.aavitsland@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/image/qimageiohandler.cpp | 6 | ||||
-rw-r--r-- | src/gui/image/qimageiohandler.h | 4 | ||||
-rw-r--r-- | src/gui/image/qimagewriter.cpp | 65 | ||||
-rw-r--r-- | src/gui/image/qimagewriter.h | 6 | ||||
-rw-r--r-- | src/gui/image/qjpeghandler.cpp | 28 |
5 files changed, 104 insertions, 5 deletions
diff --git a/src/gui/image/qimageiohandler.cpp b/src/gui/image/qimageiohandler.cpp index 1ecf445d57..7e7f3295e9 100644 --- a/src/gui/image/qimageiohandler.cpp +++ b/src/gui/image/qimageiohandler.cpp @@ -153,6 +153,12 @@ \value SupportedSubTypes Image formats that support different saving variants should return a list of supported variant names (QList<QByteArray>) in this option. + + \value OptimizedWrite. A handler which supports this option + is expected to turn on optimization flags when writing. + + \value ProgressiveScanWrite. A handler which supports + this option is expected to write the image as a progressive scan image. */ /*! diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h index 3b3c410e0c..1c906436fe 100644 --- a/src/gui/image/qimageiohandler.h +++ b/src/gui/image/qimageiohandler.h @@ -84,7 +84,9 @@ public: Animation, BackgroundColor, ImageFormat, - SupportedSubTypes + SupportedSubTypes, + OptimizedWrite, + ProgressiveScanWrite }; virtual QVariant option(ImageOption option) const; virtual void setOption(ImageOption option, const QVariant &value); diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index fa261df1a5..0e03c9b215 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -252,6 +252,8 @@ public: QString description; QString text; QByteArray subType; + bool optimizedWrite; + bool progressiveScanWrite; // error QImageWriter::ImageWriterError imageWriterError; @@ -271,6 +273,8 @@ QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq) quality = -1; compression = 0; gamma = 0.0; + optimizedWrite = false; + progressiveScanWrite = false; imageWriterError = QImageWriter::UnknownError; errorString = QImageWriter::tr("Unknown error"); @@ -555,6 +559,63 @@ QList<QByteArray> QImageWriter::supportedSubTypes() const } /*! + \since 5.5 + + This is an image format-specific function which sets the \a optimize flags when + writing images. For image formats that do not support setting an \a optimize flag, + this value is ignored. + + The default is false. + + \sa optimizedWrite() +*/ +void QImageWriter::setOptimizedWrite(bool optimize) +{ + d->optimizedWrite = optimize; +} + +/*! + \since 5.5 + + Returns whether optimization has been turned on for writing the image. + + \sa setOptimizedWrite() +*/ +bool QImageWriter::optimizedWrite() const +{ + return d->optimizedWrite; +} + +/*! + \since 5.5 + + This is an image format-specific function which turns on \a progressive scanning + when writing images. For image formats that do not support setting a \a progressive + scan flag, this value is ignored. + + The default is false. + + \sa progressiveScanWrite() +*/ + +void QImageWriter::setProgressiveScanWrite(bool progressive) +{ + d->progressiveScanWrite = progressive; +} + +/*! + \since 5.5 + + Returns whether the image should be written as a progressive image. + + \sa setProgressiveScanWrite() +*/ +bool QImageWriter::progressiveScanWrite() const +{ + return d->progressiveScanWrite; +} + +/*! \obsolete Use setText() instead. @@ -657,6 +718,10 @@ bool QImageWriter::write(const QImage &image) d->handler->setOption(QImageIOHandler::Description, d->description); if (!d->subType.isEmpty() && d->handler->supportsOption(QImageIOHandler::SubType)) d->handler->setOption(QImageIOHandler::SubType, d->subType); + if (d->handler->supportsOption(QImageIOHandler::OptimizedWrite)) + d->handler->setOption(QImageIOHandler::OptimizedWrite, d->optimizedWrite); + if (d->handler->supportsOption(QImageIOHandler::ProgressiveScanWrite)) + d->handler->setOption(QImageIOHandler::ProgressiveScanWrite, d->progressiveScanWrite); if (!d->handler->write(image)) return false; diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h index f458a259aa..e070d3b3d6 100644 --- a/src/gui/image/qimagewriter.h +++ b/src/gui/image/qimagewriter.h @@ -83,6 +83,12 @@ public: QByteArray subType() const; QList<QByteArray> supportedSubTypes() const; + void setOptimizedWrite(bool optimize); + bool optimizedWrite() const; + + void setProgressiveScanWrite(bool progressive); + bool progressiveScanWrite() const; + // Obsolete as of 4.1 void setDescription(const QString &description); QString description() const; diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index ae30de634a..7b669b1181 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -538,7 +538,7 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt } } -static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description) +static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive) { bool success = false; const QVector<QRgb> cmap = image.colorTable(); @@ -607,6 +607,11 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in cinfo.Y_density = (image.dotsPerMeterY()+50) / 100; } + if (optimize) + cinfo.optimize_coding = true; + + if (progressive) + jpeg_simple_progression(&cinfo); int quality = sourceQuality >= 0 ? qMin(int(sourceQuality),100) : 75; jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); @@ -729,7 +734,7 @@ public: }; QJpegHandlerPrivate(QJpegHandler *qq) - : quality(75), exifOrientation(1), iod_src(0), state(Ready), q(qq) + : quality(75), exifOrientation(1), iod_src(0), state(Ready), optimize(false), progressive(false), q(qq) {} ~QJpegHandlerPrivate() @@ -762,6 +767,9 @@ public: State state; + bool optimize; + bool progressive; + QJpegHandler *q; }; @@ -1066,7 +1074,7 @@ bool QJpegHandler::read(QImage *image) bool QJpegHandler::write(const QImage &image) { - return write_jpeg_image(image, device(), d->quality, d->description); + return write_jpeg_image(image, device(), d->quality, d->description, d->optimize, d->progressive); } bool QJpegHandler::supportsOption(ImageOption option) const @@ -1077,7 +1085,9 @@ bool QJpegHandler::supportsOption(ImageOption option) const || option == ClipRect || option == Description || option == Size - || option == ImageFormat; + || option == ImageFormat + || option == OptimizedWrite + || option == ProgressiveScanWrite; } QVariant QJpegHandler::option(ImageOption option) const @@ -1100,6 +1110,10 @@ QVariant QJpegHandler::option(ImageOption option) const case ImageFormat: d->readJpegHeader(device()); return d->format; + case OptimizedWrite: + return d->optimize; + case ProgressiveScanWrite: + return d->progressive; default: break; } @@ -1125,6 +1139,12 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value) case Description: d->description = value.toString(); break; + case OptimizedWrite: + d->optimize = value.toBool(); + break; + case ProgressiveScanWrite: + d->progressive = value.toBool(); + break; default: break; } |