Details
-
Bug
-
Resolution: Done
-
P4: Low
-
5.4.0
-
None
-
2a28bebdc8548c1171a3f255651edafe685da003
Description
When you use an AnimatedImage element to display a .gif, the current implementation will cache a decoded copy of each frame of the .gif. For larger/longer animated images, this can occupy an absurd amount of memory. For example, to display the attached .gif, Qt allocates over 200MB of memory.
The following (incorrect) patches reduces the amount of memory consumed down to that needed by a single frame:
qtbase:
diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp index 03e46ab..24a8680 100644 --- a/src/gui/image/qgifhandler.cpp +++ b/src/gui/image/qgifhandler.cpp @@ -239,7 +239,7 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, table[1] = &stack[(1 << max_lzw_bits) * 3]; } - image->detach(); + // image->detach(); int bpl = image->bytesPerLine(); unsigned char *bits = image->bits(); diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 4e10b4c..a8aaa2c 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1581,7 +1581,7 @@ uchar *QImage::bits() { if (!d) return 0; - detach(); + // detach(); // In case detach ran out of memory... if (!d) diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 65e7fb0..09f1be4 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -193,7 +193,7 @@ void QRasterPlatformPixmap::fill(const QColor &color) toFormat = QImage::Format_ARGB32_Premultiplied; if (!image.isNull() && qt_depthForFormat(image.format()) == qt_depthForFormat(toFormat)) { - image.detach(); + // image.detach(); image.d->format = toFormat; } else { image = QImage(image.width(), image.height(), toFormat); @@ -338,7 +338,7 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC inPlace = inPlace && sourceImage.isDetached(); image = sourceImage; if (!inPlace) - image.detach(); + // image.detach(); if (image.d) image.d->format = QImage::Format_RGB32; } else if (inPlace && sourceImage.d->convertInPlace(format, flags)) {
qtdeclarative:
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index 342394a..baababc 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -365,7 +365,7 @@ void QQuickAnimatedImage::movieRequestFinished() this, SLOT(playingStatusChanged())); connect(d->_movie, SIGNAL(frameChanged(int)), this, SLOT(movieUpdate())); - d->_movie->setCacheMode(QMovie::CacheAll); + d->_movie->setCacheMode(QMovie::CacheNone); d->status = Ready; emit statusChanged(d->status);
If it is agreed that we should allow AnimatedImage to not cache the decoded version of every frame, I can work on a patch that does that.
Attachments
Issue Links
- relates to
-
QTBUG-46619 Growing memory when AnimatedImage is playing
- Reported
-
QTBUG-55808 AnimatedImage Memory occupancy
- Closed