summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohn Brooks <john.brooks@dereferenced.net>2012-04-10 22:52:49 -0600
committerQt by Nokia <qt-info@nokia.com>2012-04-12 15:12:20 +0200
commit56ff31f0c17ff7c038028c1af6afb6eab5216bd6 (patch)
tree3cd4b5a4326b792f317241065fe839a9adfa19b3 /src
parent011b88a7b37680288944bde2c4769fd203ee8218 (diff)
Support more scaling factors for JPEG decompression
Since libjpeg 7, decompression scaling factors of [1,16]/8 have been supported. Upscaling is slower, but using the entire range of downscaling factors is significantly faster for sizes between the power-of-two factors. Time to decompress a 5184x3456 image and scale to 1900x1200, slightly less than 3/8ths, changes from 251ms to 203ms. libjpeg versions prior to 7 will round up to the next largest factor they support, and continue to work as before. Change-Id: I00a0655df2ef057e739927a643bfe0b0cabd5602 Reviewed-by: Robin Burchell <robin+qt@viroteck.net> Reviewed-by: aavit <qt_aavit@ovi.com>
Diffstat (limited to 'src')
-rw-r--r--src/gui/image/qjpeghandler.cpp43
1 files changed, 24 insertions, 19 deletions
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index 013a1a83b0..7dcbcf508f 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -45,6 +45,7 @@
#include <qvariant.h>
#include <qvector.h>
#include <qbuffer.h>
+#include <qmath.h>
#include <private/qsimd_p.h>
#include <stdio.h> // jpeglib needs this to be pre-included
@@ -321,27 +322,31 @@ static bool read_jpeg_image(QImage *outImage,
}
// Determine the scale factor to pass to libjpeg for quick downscaling.
- if (!scaledSize.isEmpty()) {
+ if (!scaledSize.isEmpty() && info->image_width && info->image_height) {
if (clipRect.isEmpty()) {
- info->scale_denom =
- qMin(info->image_width / scaledSize.width(),
- info->image_height / scaledSize.height());
- } else {
- info->scale_denom =
- qMin(clipRect.width() / scaledSize.width(),
- clipRect.height() / scaledSize.height());
- }
- if (info->scale_denom < 2) {
- info->scale_denom = 1;
- } else if (info->scale_denom < 4) {
- info->scale_denom = 2;
- } else if (info->scale_denom < 8) {
- info->scale_denom = 4;
- } else {
+ double f = qMin(double(info->image_width) / scaledSize.width(),
+ double(info->image_height) / scaledSize.height());
+
+ // libjpeg supports M/8 scaling with M=[1,16]. All downscaling factors
+ // are a speed improvement, but upscaling during decode is slower.
+ info->scale_num = qBound(1, qCeil(8/f), 8);
info->scale_denom = 8;
- }
- info->scale_num = 1;
- if (!clipRect.isEmpty()) {
+ } else {
+ info->scale_denom = qMin(clipRect.width() / scaledSize.width(),
+ clipRect.height() / scaledSize.height());
+
+ // Only scale by powers of two when clipping so we can
+ // keep the exact pixel boundaries
+ if (info->scale_denom < 2)
+ info->scale_denom = 1;
+ else if (info->scale_denom < 4)
+ info->scale_denom = 2;
+ else if (info->scale_denom < 8)
+ info->scale_denom = 4;
+ else
+ info->scale_denom = 8;
+ info->scale_num = 1;
+
// Correct the scale factor so that we clip accurately.
// It is recommended that the clip rectangle be aligned
// on an 8-pixel boundary for best performance.