From 57d4e5aae33d27f4989c76269f23e837b8dff451 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Tue, 3 Aug 2010 12:06:34 +0200 Subject: Use the fast conversion from RGB888 to RGB32 for Jpeg images The commit 90642dd2b6b14c39cc6178f1161331895809b342 introduce a fast way to convert from RGB888 to RGB32 with SSSE3. This patch uses that function to do the color conversion when decoding jpeg images. The #defines for the SIMD extension have been moved to the common code in order to be able to compile the jpeg handler directly in QtGui or as a plugin. Reviewed-by: Andreas Kling --- src/gui/image/qimage_ssse3.cpp | 3 +-- src/gui/image/qjpeghandler.cpp | 29 ++++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/gui/image/qimage_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp index 1c664f2..cc4ac5e 100644 --- a/src/gui/image/qimage_ssse3.cpp +++ b/src/gui/image/qimage_ssse3.cpp @@ -45,13 +45,12 @@ #ifdef QT_HAVE_SSSE3 -#include QT_BEGIN_NAMESPACE // Convert a scanline of RGB888 (src) to RGB32 (dst) // src must be at least len * 3 bytes // dst must be at least len * 4 bytes -inline void convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len) +Q_GUI_EXPORT void QT_FASTCALL convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len) { quint32 *const end = dst + len; diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 972dd65..0b731cb 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include // jpeglib needs this to be pre-included #include @@ -75,6 +76,19 @@ extern "C" { QT_BEGIN_NAMESPACE +void QT_FASTCALL convert_rgb888_to_rgb32_C(quint32 *dst, const uchar *src, int len) +{ + // Expand 24->32 bpp. + for (int i = 0; i < len; ++i) { + *dst++ = qRgb(src[0], src[1], src[2]); + src += 3; + } +} + +typedef void (QT_FASTCALL *Rgb888ToRgb32Converter)(quint32 *dst, const uchar *src, int len); + +static Rgb888ToRgb32Converter rgb888ToRgb32ConverterPtr = convert_rgb888_to_rgb32_C; + struct my_error_mgr : public jpeg_error_mgr { jmp_buf setjmp_buffer; }; @@ -393,13 +407,9 @@ static bool read_jpeg_image(QImage *outImage, continue; // Haven't reached the starting line yet. if (info->output_components == 3) { - // Expand 24->32 bpp. uchar *in = rows[0] + clip.x() * 3; QRgb *out = (QRgb*)outImage->scanLine(y); - for (int i = 0; i < clip.width(); ++i) { - *out++ = qRgb(in[0], in[1], in[2]); - in += 3; - } + rgb888ToRgb32ConverterPtr(out, in, clip.width()); } else if (info->out_color_space == JCS_CMYK) { // Convert CMYK->RGB. uchar *in = rows[0] + clip.x() * 4; @@ -793,6 +803,15 @@ bool QJpegHandlerPrivate::read(QImage *image) QJpegHandler::QJpegHandler() : d(new QJpegHandlerPrivate(this)) { +#if defined(QT_HAVE_SSSE3) + const uint features = qDetectCPUFeatures(); + + // from qimage_ssse3.cpp + Q_GUI_EXPORT void QT_FASTCALL convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len); + + if (features & SSSE3) + rgb888ToRgb32ConverterPtr = convert_rgb888_to_rgb32_ssse3; +#endif // QT_HAVE_SSSE3 } QJpegHandler::~QJpegHandler() -- cgit v0.12