From ab09c9dd9a93932feedbc99e9e965be5bc852c02 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 20 Sep 2019 11:20:00 +0200 Subject: Tiff handler: Improve writing performance for some cases For 1 byte deep formats, the writing routine went through the copy-and-convert-in-chunks loop for no reason: no conversion was done or needed. For huge images of some formats, the chunk size computation could fail because of int overflow, resulting in suboptimal chunk sizes. Change-Id: I966351d9a8728987c9e885f4949d98ba94d4ac19 Reviewed-by: Allan Sandfeld Jensen --- src/plugins/imageformats/tiff/qtiffhandler.cpp | 28 ++++++++------------------ 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp index 3d404bd..06a5472 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler.cpp +++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp @@ -607,8 +607,8 @@ bool QTiffHandler::write(const QImage &image) } // try to do the conversion in chunks no greater than 16 MB - int chunks = (width * height / (1024 * 1024 * 16)) + 1; - int chunkHeight = qMax(height / chunks, 1); + const int chunks = int(image.sizeInBytes() / (1024 * 1024 * 16)) + 1; + const int chunkHeight = qMax(height / chunks, 1); int y = 0; while (y < height) { @@ -675,22 +675,10 @@ bool QTiffHandler::write(const QImage &image) } //// write the data - // try to do the conversion in chunks no greater than 16 MB - int chunks = (width * height/ (1024 * 1024 * 16)) + 1; - int chunkHeight = qMax(height / chunks, 1); - - int y = 0; - while (y < height) { - QImage chunk = image.copy(0, y, width, qMin(chunkHeight, height - y)); - - int chunkStart = y; - int chunkEnd = y + chunk.height(); - while (y < chunkEnd) { - if (TIFFWriteScanline(tiff, reinterpret_cast(chunk.scanLine(y - chunkStart)), y) != 1) { - TIFFClose(tiff); - return false; - } - ++y; + for (int y = 0; y < height; ++y) { + if (TIFFWriteScanline(tiff, const_cast(image.scanLine(y)), y) != 1) { + TIFFClose(tiff); + return false; } } TIFFClose(tiff); @@ -748,7 +736,7 @@ bool QTiffHandler::write(const QImage &image) return false; } // try to do the RGB888 conversion in chunks no greater than 16 MB - const int chunks = (width * height * 3 / (1024 * 1024 * 16)) + 1; + const int chunks = int(image.sizeInBytes() / (1024 * 1024 * 16)) + 1; const int chunkHeight = qMax(height / chunks, 1); int y = 0; @@ -780,7 +768,7 @@ bool QTiffHandler::write(const QImage &image) return false; } // try to do the RGBA8888 conversion in chunks no greater than 16 MB - const int chunks = (width * height * 4 / (1024 * 1024 * 16)) + 1; + const int chunks = int(image.sizeInBytes() / (1024 * 1024 * 16)) + 1; const int chunkHeight = qMax(height / chunks, 1); const QImage::Format format = premultiplied ? QImage::Format_RGBA8888_Premultiplied -- cgit v1.2.3