diff options
author | John Brooks <john.brooks@dereferenced.net> | 2012-04-10 22:52:49 -0600 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-12 15:12:20 +0200 |
commit | 56ff31f0c17ff7c038028c1af6afb6eab5216bd6 (patch) | |
tree | 3cd4b5a4326b792f317241065fe839a9adfa19b3 /src/gui/image/qjpeghandler.cpp | |
parent | 011b88a7b37680288944bde2c4769fd203ee8218 (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/gui/image/qjpeghandler.cpp')
-rw-r--r-- | src/gui/image/qjpeghandler.cpp | 43 |
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. |