From c1431e6daa5f0e229c2e79a945f28d00d70b0978 Mon Sep 17 00:00:00 2001 From: aavit Date: Fri, 9 Apr 2010 15:30:04 +0200 Subject: Optimization: Avoid data copy when reading jpegs from memory If the iodevice is actually a qbuffer, avoid read() and just give libjpeg a pointer to the contained data directly. Related to QTBUG-9095. Reviewed-by: Kim --- src/plugins/imageformats/jpeg/qjpeghandler.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 93b7cc6..1c6a289 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include // jpeglib needs this to be pre-included #include @@ -102,6 +103,7 @@ struct my_jpeg_source_mgr : public jpeg_source_mgr { // Nothing dynamic - cannot rely on destruction over longjump QIODevice *device; JOCTET buffer[max_buf]; + const QBuffer *memDevice; public: my_jpeg_source_mgr(QIODevice *device); @@ -117,10 +119,14 @@ static void qt_init_source(j_decompress_ptr) static boolean qt_fill_input_buffer(j_decompress_ptr cinfo) { - int num_read; my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src; + if (src->memDevice) { + src->next_input_byte = (const JOCTET *)src->memDevice->data().constData(); + src->bytes_in_buffer = (size_t)src->memDevice->data().size(); + return true; + } src->next_input_byte = src->buffer; - num_read = src->device->read((char*)src->buffer, max_buf); + int num_read = src->device->read((char*)src->buffer, max_buf); if (num_read <= 0) { // Insert a fake EOI marker - as per jpeglib recommendation src->buffer[0] = (JOCTET) 0xFF; @@ -147,7 +153,7 @@ static void qt_skip_input_data(j_decompress_ptr cinfo, long num_bytes) * any trouble anyway --- large skips are infrequent. */ if (num_bytes > 0) { - while (num_bytes > (long) src->bytes_in_buffer) { + while (num_bytes > (long) src->bytes_in_buffer) { // Should not happen in case of memDevice num_bytes -= (long) src->bytes_in_buffer; (void) qt_fill_input_buffer(cinfo); /* note we assume that qt_fill_input_buffer will never return false, @@ -178,6 +184,7 @@ inline my_jpeg_source_mgr::my_jpeg_source_mgr(QIODevice *device) jpeg_source_mgr::resync_to_restart = jpeg_resync_to_restart; jpeg_source_mgr::term_source = qt_term_source; this->device = device; + memDevice = qobject_cast(device); bytes_in_buffer = 0; next_input_byte = buffer; } -- cgit v0.12