From f1c06d67435d344471f458c5f84821f2dabbc010 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 9 Nov 2018 19:16:47 +0400 Subject: [PATCH] Store StickerData::image in unique_ptr. --- Telegram/SourceFiles/data/data_document.cpp | 63 ++++++++++++------- Telegram/SourceFiles/data/data_document.h | 5 +- .../history/history_media_types.cpp | 28 +++++---- .../inline_bot_layout_internal.cpp | 18 +++--- Telegram/SourceFiles/mediaview.cpp | 11 ++-- Telegram/SourceFiles/window/layer_widget.cpp | 15 ++--- 6 files changed, 79 insertions(+), 61 deletions(-) diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 8c94729e0d..670d6fdc8a 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -41,8 +41,8 @@ Core::MediaActiveCache &ActiveCache() { } int64 ComputeUsage(StickerData *sticker) { - return (sticker != nullptr && !sticker->img->isNull()) - ? sticker->img->width() * sticker->img->height() * 4 + return (sticker != nullptr && sticker->image != nullptr) + ? sticker->image->width() * sticker->image->height() * 4 : 0; } @@ -585,12 +585,9 @@ void DocumentData::unload() { // Forget thumb only when image cache limit exceeds. //thumb->unload(); if (sticker()) { - if (!sticker()->img->isNull()) { + if (sticker()->image) { ActiveCache().decrement(ComputeUsage(sticker())); - - // Should be std::unique_ptr. - delete sticker()->img.get(); - sticker()->img = ImagePtr(); + sticker()->image = nullptr; } } _replyPreview = nullptr; @@ -736,16 +733,17 @@ bool DocumentData::loaded(FilePathResolveType type) const { that->_data = _loader->bytes(); ActiveCache().increment(that->_data.size()); if (that->sticker() - && that->sticker()->img->isNull() + && !that->sticker()->image && !_loader->imageData().isNull()) { - that->sticker()->img = Images::Create( - _data, - _loader->imageFormat(), - _loader->imageData()); + that->sticker()->image = std::make_unique( + std::make_unique( + QString(), + _data, + _loader->imageFormat(), + _loader->imageData())); ActiveCache().increment(ComputeUsage(that->sticker())); } - if (!that->_data.isEmpty() - || (that->sticker() && !that->sticker()->img->isNull())) { + if (!that->_data.isEmpty() || that->getStickerImage()) { ActiveCache().up(that); } @@ -1066,15 +1064,26 @@ void DocumentData::checkSticker() { if (!data) return; automaticLoad(stickerSetOrigin(), nullptr); - if (data->img->isNull() && loaded()) { + if (!data->image && loaded()) { if (_data.isEmpty()) { const auto &loc = location(true); if (loc.accessEnable()) { - data->img = Images::Create(loc.name(), "WEBP"); + data->image = std::make_unique( + std::make_unique( + loc.name(), + QByteArray(), + "WEBP")); loc.accessDisable(); } } else { - data->img = Images::Create(_data, "WEBP"); + auto format = QByteArray("WEBP"); + auto image = App::readImage(_data, &format, false); + data->image = std::make_unique( + std::make_unique( + QString(), + _data, + format, + std::move(image))); } if (const auto usage = ComputeUsage(data)) { ActiveCache().increment(usage); @@ -1091,13 +1100,21 @@ void DocumentData::checkStickerThumb() { } } -ImagePtr DocumentData::getStickerThumb() { - if (hasGoodStickerThumb()) { - return thumb; - } else if (const auto data = sticker()) { - return data->img; +Image *DocumentData::getStickerImage() { + checkSticker(); + if (const auto data = sticker()) { + return data->image.get(); } - return ImagePtr(); + return nullptr; +} + +Image *DocumentData::getStickerThumb() { + if (hasGoodStickerThumb()) { + return thumb->isNull() ? nullptr : thumb.get(); + } else if (const auto data = sticker()) { + return data->image.get(); + } + return nullptr; } Data::FileOrigin DocumentData::stickerSetOrigin() const { diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index 5faf50ede7..fb7ef9f8de 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -47,7 +47,7 @@ struct DocumentAdditionalData { struct StickerData : public DocumentAdditionalData { Data::FileOrigin setOrigin() const; - ImagePtr img; + std::unique_ptr image; QString alt; MTPInputStickerSet set = MTP_inputStickerSetEmpty(); StorageImageLocation loc; // doc thumb location @@ -131,7 +131,8 @@ public: StickerData *sticker() const; void checkSticker(); void checkStickerThumb(); - ImagePtr getStickerThumb(); + Image *getStickerThumb(); + Image *getStickerImage(); Data::FileOrigin stickerSetOrigin() const; Data::FileOrigin stickerOrGifOrigin() const; bool isStickerSetInstalled() const; diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index 577c898675..bbacafff48 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -2998,19 +2998,23 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, T } if (rtl()) usex = width() - usex - usew; - if (selected) { - if (sticker->img->isNull()) { - p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), _data->thumb->pixBlurredColored(item->fullId(), st::msgStickerOverlay, _pixw, _pixh)); - } else { - p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), sticker->img->pixColored(item->fullId(), st::msgStickerOverlay, _pixw, _pixh)); + const auto &pixmap = [&]() -> const QPixmap & { + const auto o = item->fullId(); + const auto w = _pixw; + const auto h = _pixh; + const auto &c = st::msgStickerOverlay; + if (const auto image = _data->getStickerImage()) { + return selected + ? image->pixColored(o, c, w, h) + : image->pix(o, w, h); } - } else { - if (sticker->img->isNull()) { - p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), _data->thumb->pixBlurred(item->fullId(), _pixw, _pixh)); - } else { - p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), sticker->img->pix(item->fullId(), _pixw, _pixh)); - } - } + return selected + ? _data->thumb->pixBlurredColored(o, c, w, h) + : _data->thumb->pixBlurred(o, w, h); + }(); + p.drawPixmap( + QPoint{ usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2 }, + pixmap); if (!inWebPage) { auto fullRight = usex + usew; diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp index 8842aa2ddb..4f20c89c60 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp @@ -445,15 +445,15 @@ QSize Sticker::getThumbSize() const { void Sticker::prepareThumb() const { if (const auto document = getShownDocument()) { document->checkStickerThumb(); - - const auto sticker = document->getStickerThumb(); - if (!_thumbLoaded && !sticker->isNull() && sticker->loaded()) { - const auto thumbSize = getThumbSize(); - _thumb = sticker->pix( - document->stickerSetOrigin(), - thumbSize.width(), - thumbSize.height()); - _thumbLoaded = true; + if (const auto sticker = document->getStickerThumb()) { + if (!_thumbLoaded && sticker->loaded()) { + const auto thumbSize = getThumbSize(); + _thumb = sticker->pix( + document->stickerSetOrigin(), + thumbSize.width(), + thumbSize.height()); + _thumbLoaded = true; + } } } else { const auto origin = fileOrigin(); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index dabf763dd8..fe1d8b6071 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -1617,9 +1617,8 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty } if (_doc) { if (_doc->sticker()) { - _doc->checkSticker(); - if (!_doc->sticker()->img->isNull()) { - _current = _doc->sticker()->img->pix(fileOrigin()); + if (const auto image = _doc->getStickerImage()) { + _current = image->pix(fileOrigin()); } else { _current = _doc->thumb->pixBlurred( fileOrigin(), @@ -2107,7 +2106,7 @@ void MediaView::paintEvent(QPaintEvent *e) { if (imgRect.intersects(r)) { auto rounding = (_doc && _doc->isVideoMessage()) ? ImageRoundRadius::Ellipse : ImageRoundRadius::None; auto toDraw = _current.isNull() ? _gif->current(_gif->width() / cIntRetinaFactor(), _gif->height() / cIntRetinaFactor(), _gif->width() / cIntRetinaFactor(), _gif->height() / cIntRetinaFactor(), rounding, RectPart::AllCorners, ms) : _current; - if (!_gif && (!_doc || !_doc->sticker() || _doc->sticker()->img->isNull()) && toDraw.hasAlpha()) { + if (!_gif && (!_doc || !_doc->getStickerImage()) && toDraw.hasAlpha()) { p.fillRect(imgRect, _transparentBrush); } if (toDraw.width() != _w * cIntRetinaFactor()) { @@ -2719,8 +2718,8 @@ void MediaView::preloadData(int delta) { if (auto photo = base::get_if>(&entity.data)) { (*photo)->download(fileOrigin()); } else if (auto document = base::get_if>(&entity.data)) { - if (auto sticker = (*document)->sticker()) { - sticker->img->load(fileOrigin()); + if (const auto image = (*document)->getStickerImage()) { + image->load(fileOrigin()); } else { (*document)->thumb->load(fileOrigin()); (*document)->automaticLoad(fileOrigin(), entity.item); diff --git a/Telegram/SourceFiles/window/layer_widget.cpp b/Telegram/SourceFiles/window/layer_widget.cpp index 24739ff8b8..77850d4543 100644 --- a/Telegram/SourceFiles/window/layer_widget.cpp +++ b/Telegram/SourceFiles/window/layer_widget.cpp @@ -1009,17 +1009,14 @@ QPixmap MediaPreviewWidget::currentImage() const { if (_document) { if (_document->sticker()) { if (_cacheStatus != CacheLoaded) { - _document->checkSticker(); - if (_document->sticker()->img->isNull()) { - if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) { - QSize s = currentDimensions(); - _cache = _document->thumb->pixBlurred(_origin, s.width(), s.height()); - _cacheStatus = CacheThumbLoaded; - } - } else { + if (const auto image = _document->getStickerImage()) { QSize s = currentDimensions(); - _cache = _document->sticker()->img->pix(_origin, s.width(), s.height()); + _cache = image->pix(_origin, s.width(), s.height()); _cacheStatus = CacheLoaded; + } else if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) { + QSize s = currentDimensions(); + _cache = _document->thumb->pixBlurred(_origin, s.width(), s.height()); + _cacheStatus = CacheThumbLoaded; } } } else {