Simplify Image, remove ImageSource.

This commit is contained in:
John Preston 2020-05-29 19:10:25 +04:00
parent d0c78eaddd
commit 36fbdfb380
49 changed files with 306 additions and 512 deletions

View File

@ -935,8 +935,6 @@ PRIVATE
ui/image/image_location.h ui/image/image_location.h
ui/image/image_location_factory.cpp ui/image/image_location_factory.cpp
ui/image/image_location_factory.h ui/image/image_location_factory.h
ui/image/image_source.cpp
ui/image/image_source.h
ui/widgets/continuous_sliders.cpp ui/widgets/continuous_sliders.cpp
ui/widgets/continuous_sliders.h ui/widgets/continuous_sliders.h
ui/widgets/discrete_sliders.cpp ui/widgets/discrete_sliders.cpp

View File

@ -659,7 +659,7 @@ bool BackgroundPreviewBox::setScaledFromThumb() {
: _media : _media
? _media->thumbnail() ? _media->thumbnail()
: nullptr; : nullptr;
if (!thumbnail || !thumbnail->loaded()) { if (!thumbnail) {
return false; return false;
} else if (_paper.isPattern() && _paper.document() != nullptr) { } else if (_paper.isPattern() && _paper.document() != nullptr) {
return false; return false;

View File

@ -979,7 +979,6 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) {
(width() - st::confirmInvitePhotoSize) / 2, (width() - st::confirmInvitePhotoSize) / 2,
st::confirmInvitePhotoTop, st::confirmInvitePhotoTop,
image->pixCircled( image->pixCircled(
Data::FileOrigin(),
st::confirmInvitePhotoSize, st::confirmInvitePhotoSize,
st::confirmInvitePhotoSize)); st::confirmInvitePhotoSize));
} }

View File

@ -132,7 +132,7 @@ EditCaptionBox::EditCaptionBox(
| Images::Option::RoundedBottomLeft | Images::Option::RoundedBottomLeft
| Images::Option::RoundedBottomRight; | Images::Option::RoundedBottomRight;
_thumb = App::pixmapFromImageInPlace(Images::prepare( _thumb = App::pixmapFromImageInPlace(Images::prepare(
image->pix(_msgId).toImage(), image->original(),
_thumbw * cIntRetinaFactor(), _thumbw * cIntRetinaFactor(),
0, 0,
options, options,
@ -180,7 +180,6 @@ EditCaptionBox::EditCaptionBox(
const auto options = Images::Option::Smooth const auto options = Images::Option::Smooth
| Images::Option::Blurred; | Images::Option::Blurred;
_thumb = image->pixNoCache( _thumb = image->pixNoCache(
_msgId,
maxW * cIntRetinaFactor(), maxW * cIntRetinaFactor(),
maxH * cIntRetinaFactor(), maxH * cIntRetinaFactor(),
options, options,
@ -206,7 +205,6 @@ EditCaptionBox::EditCaptionBox(
? Images::Option::Blurred ? Images::Option::Blurred
: Images::Option(0)); : Images::Option(0));
_thumb = use->pixNoCache( _thumb = use->pixNoCache(
_msgId,
maxW * cIntRetinaFactor(), maxW * cIntRetinaFactor(),
maxH * cIntRetinaFactor(), maxH * cIntRetinaFactor(),
options, options,
@ -282,7 +280,7 @@ EditCaptionBox::EditCaptionBox(
_thumbnailImageLoaded = _photoMedia _thumbnailImageLoaded = _photoMedia
? (_photoMedia->image(Data::PhotoSize::Large) != nullptr) ? (_photoMedia->image(Data::PhotoSize::Large) != nullptr)
: _thumbnailImage : _thumbnailImage
? _thumbnailImage->loaded() ? true
: _documentMedia : _documentMedia
? !_documentMedia->owner()->hasThumbnail() ? !_documentMedia->owner()->hasThumbnail()
: true; : true;
@ -299,7 +297,7 @@ EditCaptionBox::EditCaptionBox(
&& _documentMedia->owner()->hasThumbnail()) { && _documentMedia->owner()->hasThumbnail()) {
_thumbnailImage = _documentMedia->thumbnail(); _thumbnailImage = _documentMedia->thumbnail();
} }
if (_thumbnailImage && _thumbnailImage->loaded()) { if (_thumbnailImage) {
_thumbnailImageLoaded = !_photoMedia _thumbnailImageLoaded = !_photoMedia
|| _photoMedia->image(PhotoSize::Large); || _photoMedia->image(PhotoSize::Large);
if (_thumbnailImageLoaded) { if (_thumbnailImageLoaded) {

View File

@ -665,7 +665,7 @@ void StickerSetBox::Inner::paintSticker(
p.drawPixmapLeft( p.drawPixmapLeft(
ppos, ppos,
width(), width(),
image->pix(document->stickerSetOrigin(), w, h)); image->pix(w, h));
} }
} }

View File

@ -940,7 +940,7 @@ void StickersBox::Inner::paintRowThumbnail(
left + (st::contactsPhotoSize - row->pixw) / 2, left + (st::contactsPhotoSize - row->pixw) / 2,
st::contactsPadding.top() + (st::contactsPhotoSize - row->pixh) / 2, st::contactsPadding.top() + (st::contactsPhotoSize - row->pixh) / 2,
width(), width(),
thumb->pix(origin, row->pixw, row->pixh)); thumb->pix(row->pixw, row->pixh));
} else if (row->lottie->ready()) { } else if (row->lottie->ready()) {
const auto frame = row->lottie->frame(); const auto frame = row->lottie->frame();
const auto size = frame.size() / cIntRetinaFactor(); const auto size = frame.size() / cIntRetinaFactor();

View File

@ -539,17 +539,13 @@ void Panel::refreshUserPhoto() {
if (isNewBigPhoto) { if (isNewBigPhoto) {
_userPhotoId = _photo->owner()->id; _userPhotoId = _photo->owner()->id;
_userPhotoFull = true; _userPhotoFull = true;
createUserpicCache( createUserpicCache(_photo->image(Data::PhotoSize::Large));
_photo->image(Data::PhotoSize::Large),
_user->userpicPhotoOrigin());
} else if (_userPhoto.isNull()) { } else if (_userPhoto.isNull()) {
createUserpicCache( createUserpicCache(_userpic ? _userpic->image() : nullptr);
_userpic ? _userpic->image() : nullptr,
_user->userpicOrigin());
} }
} }
void Panel::createUserpicCache(Image *image, Data::FileOrigin origin) { void Panel::createUserpicCache(Image *image) {
auto size = st::callWidth * cIntRetinaFactor(); auto size = st::callWidth * cIntRetinaFactor();
auto options = _useTransparency ? (Images::Option::RoundedLarge | Images::Option::RoundedTopLeft | Images::Option::RoundedTopRight | Images::Option::Smooth) : Images::Option::None; auto options = _useTransparency ? (Images::Option::RoundedLarge | Images::Option::RoundedTopLeft | Images::Option::RoundedTopRight | Images::Option::Smooth) : Images::Option::None;
if (image) { if (image) {
@ -563,7 +559,6 @@ void Panel::createUserpicCache(Image *image, Data::FileOrigin origin) {
width = size; width = size;
} }
_userPhoto = image->pixNoCache( _userPhoto = image->pixNoCache(
origin,
width, width,
height, height,
options, options,

View File

@ -101,7 +101,7 @@ private:
void processUserPhoto(); void processUserPhoto();
void refreshUserPhoto(); void refreshUserPhoto();
bool isGoodUserPhoto(PhotoData *photo); bool isGoodUserPhoto(PhotoData *photo);
void createUserpicCache(Image *image, Data::FileOrigin origin); void createUserpicCache(Image *image);
QRect signalBarsRect() const; QRect signalBarsRect() const;
void paintSignalBarsBg(Painter &p); void paintSignalBarsBg(Painter &p);

View File

@ -685,7 +685,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
} }
} else if (const auto image = media->getStickerSmall()) { } else if (const auto image = media->getStickerSmall()) {
QPoint ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2); QPoint ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2);
p.drawPixmapLeft(ppos, width(), image->pix(document->stickerSetOrigin(), w, h)); p.drawPixmapLeft(ppos, width(), image->pix(w, h));
} }
} }
} }

View File

@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lottie/lottie_common.h" #include "lottie/lottie_common.h"
#include "ui/emoji_config.h" #include "ui/emoji_config.h"
#include "ui/text/text_isolated_emoji.h" #include "ui/text/text_isolated_emoji.h"
#include "ui/image/image_source.h" #include "ui/image/image.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "data/data_session.h" #include "data/data_session.h"
@ -310,9 +310,7 @@ std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
if (const auto strong = i->second.lock()) { if (const auto strong = i->second.lock()) {
if (!strong->image) { if (!strong->image) {
strong->load = nullptr; strong->load = nullptr;
strong->image.emplace( strong->image.emplace(std::move(image));
std::make_unique<Images::ImageSource>(
std::move(image)));
_session->downloaderTaskFinished().notify(); _session->downloaderTaskFinished().notify();
} }
} }

View File

@ -788,8 +788,8 @@ void StickersListWidget::Footer::paintSetIcon(
|| (!icon.lottie->ready() && !icon.savedFrame.isNull())) { || (!icon.lottie->ready() && !icon.savedFrame.isNull())) {
const auto pixmap = !icon.savedFrame.isNull() const auto pixmap = !icon.savedFrame.isNull()
? icon.savedFrame ? icon.savedFrame
: (!icon.lottie && thumb && thumb->loaded()) : (!icon.lottie && thumb)
? thumb->pix(origin, icon.pixw, icon.pixh) ? thumb->pix(icon.pixw, icon.pixh)
: QPixmap(); : QPixmap();
if (pixmap.isNull()) { if (pixmap.isNull()) {
return; return;
@ -1866,9 +1866,8 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section,
const auto image = media->getStickerSmall(); const auto image = media->getStickerSmall();
const auto pixmap = !sticker.savedFrame.isNull() const auto pixmap = !sticker.savedFrame.isNull()
? sticker.savedFrame ? sticker.savedFrame
: (image && image->loaded()) : image
? image->pixSingle( ? image->pixSingle(
document->stickerSetOrigin(),
w, w,
h, h,
w, w,

View File

@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "storage/file_download.h" #include "storage/file_download.h"
#include "ui/image/image_source.h" #include "ui/image/image.h"
#include "app.h" #include "app.h"
namespace Stickers { namespace Stickers {
@ -30,8 +30,7 @@ void SetThumbnailView::set(
if (image.isNull()) { if (image.isNull()) {
_content = std::move(content); _content = std::move(content);
} else { } else {
_image = std::make_unique<Image>( _image = std::make_unique<Image>(std::move(image));
std::make_unique<Images::ImageSource>(std::move(image)));
} }
session->downloaderTaskFinished().notify(); session->downloaderTaskFinished().notify();
} }

View File

@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h" #include "data/data_session.h"
#include "storage/cache/storage_cache_database.h" #include "storage/cache/storage_cache_database.h"
#include "storage/file_download.h" #include "storage/file_download.h"
#include "ui/image/image_source.h" #include "ui/image/image.h"
#include "main/main_session.h" #include "main/main_session.h"
#include <compare> #include <compare>
@ -21,8 +21,7 @@ namespace Data {
void CloudImageView::set( void CloudImageView::set(
not_null<Main::Session*> session, not_null<Main::Session*> session,
QImage image) { QImage image) {
_image = std::make_unique<Image>( _image.emplace(std::move(image));
std::make_unique<Images::ImageSource>(std::move(image)));
session->downloaderTaskFinished().notify(); session->downloaderTaskFinished().notify();
} }
@ -34,8 +33,8 @@ CloudImage::CloudImage(
update(session, data); update(session, data);
} }
Image *CloudImageView::image() const { Image *CloudImageView::image() {
return _image.get(); return _image ? &*_image : nullptr;
} }
void CloudImage::set( void CloudImage::set(

View File

@ -8,10 +8,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "base/flags.h" #include "base/flags.h"
#include "ui/image/image.h"
#include "ui/image/image_location.h" #include "ui/image/image_location.h"
class FileLoader; class FileLoader;
class Image;
namespace Storage { namespace Storage {
namespace Cache { namespace Cache {
@ -44,10 +44,10 @@ class CloudImageView final {
public: public:
void set(not_null<Main::Session*> session, QImage image); void set(not_null<Main::Session*> session, QImage image);
[[nodiscard]] Image *image() const; [[nodiscard]] Image *image();
private: private:
std::unique_ptr<Image> _image; std::optional<Image> _image;
}; };

View File

@ -34,7 +34,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/cache/storage_cache_database.h" #include "storage/cache/storage_cache_database.h"
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "ui/text/text_utilities.h" #include "ui/text/text_utilities.h"
#include "base/base_file_utilities.h" #include "base/base_file_utilities.h"
#include "mainwindow.h" #include "mainwindow.h"

View File

@ -19,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h" #include "history/history.h"
#include "window/themes/window_theme_preview.h" #include "window/themes/window_theme_preview.h"
#include "storage/file_download.h" #include "storage/file_download.h"
#include "ui/image/image_source.h" #include "ui/image/image.h"
#include "facades.h" #include "facades.h"
#include "app.h" #include "app.h"
@ -165,8 +165,7 @@ void DocumentMedia::setGoodThumbnail(QImage thumbnail) {
if (!(_flags & Flag::GoodThumbnailWanted)) { if (!(_flags & Flag::GoodThumbnailWanted)) {
return; return;
} }
_goodThumbnail = std::make_unique<Image>( _goodThumbnail = std::make_unique<Image>(std::move(thumbnail));
std::make_unique<Images::ImageSource>(std::move(thumbnail)));
_owner->session().downloaderTaskFinished().notify(); _owner->session().downloaderTaskFinished().notify();
} }
@ -174,8 +173,7 @@ Image *DocumentMedia::thumbnailInline() const {
if (!_inlineThumbnail) { if (!_inlineThumbnail) {
auto image = Images::FromInlineBytes(_owner->inlineThumbnailBytes()); auto image = Images::FromInlineBytes(_owner->inlineThumbnailBytes());
if (!image.isNull()) { if (!image.isNull()) {
_inlineThumbnail = std::make_unique<Image>( _inlineThumbnail = std::make_unique<Image>(std::move(image));
std::make_unique<Images::ImageSource>(std::move(image)));
} }
} }
return _inlineThumbnail.get(); return _inlineThumbnail.get();
@ -200,8 +198,7 @@ QSize DocumentMedia::thumbnailSize() const {
} }
void DocumentMedia::setThumbnail(QImage thumbnail) { void DocumentMedia::setThumbnail(QImage thumbnail) {
_thumbnail = std::make_unique<Image>( _thumbnail = std::make_unique<Image>(std::move(thumbnail));
std::make_unique<Images::ImageSource>(std::move(thumbnail)));
_owner->session().downloaderTaskFinished().notify(); _owner->session().downloaderTaskFinished().notify();
} }
@ -232,7 +229,6 @@ void DocumentMedia::checkStickerLarge() {
if (!data) { if (!data) {
return; return;
} }
automaticLoad(_owner->stickerSetOrigin(), nullptr); automaticLoad(_owner->stickerSetOrigin(), nullptr);
if (data->animated || !loaded()) { if (data->animated || !loaded()) {
return; return;
@ -240,13 +236,11 @@ void DocumentMedia::checkStickerLarge() {
if (_bytes.isEmpty()) { if (_bytes.isEmpty()) {
const auto &loc = _owner->location(true); const auto &loc = _owner->location(true);
if (loc.accessEnable()) { if (loc.accessEnable()) {
_sticker = std::make_unique<Image>( _sticker = std::make_unique<Image>(loc.name());
std::make_unique<Images::ImageSource>(loc.name()));
loc.accessDisable(); loc.accessDisable();
} }
} else { } else {
_sticker = std::make_unique<Image>( _sticker = std::make_unique<Image>(_bytes);
std::make_unique<Images::ImageSource>(_bytes));
} }
} }
@ -288,20 +282,16 @@ void DocumentMedia::automaticLoad(
void DocumentMedia::collectLocalData(not_null<DocumentMedia*> local) { void DocumentMedia::collectLocalData(not_null<DocumentMedia*> local) {
if (const auto image = local->_goodThumbnail.get()) { if (const auto image = local->_goodThumbnail.get()) {
_goodThumbnail = std::make_unique<Image>( _goodThumbnail = std::make_unique<Image>(image->original());
std::make_unique<Images::ImageSource>(image->original()));
} }
if (const auto image = local->_inlineThumbnail.get()) { if (const auto image = local->_inlineThumbnail.get()) {
_inlineThumbnail = std::make_unique<Image>( _inlineThumbnail = std::make_unique<Image>(image->original());
std::make_unique<Images::ImageSource>(image->original()));
} }
if (const auto image = local->_thumbnail.get()) { if (const auto image = local->_thumbnail.get()) {
_thumbnail = std::make_unique<Image>( _thumbnail = std::make_unique<Image>(image->original());
std::make_unique<Images::ImageSource>(image->original()));
} }
if (const auto image = local->_sticker.get()) { if (const auto image = local->_sticker.get()) {
_sticker = std::make_unique<Image>( _sticker = std::make_unique<Image>(image->original());
std::make_unique<Images::ImageSource>(image->original()));
} }
_bytes = local->_bytes; _bytes = local->_bytes;
_videoThumbnailBytes = local->_videoThumbnailBytes; _videoThumbnailBytes = local->_videoThumbnailBytes;
@ -373,8 +363,7 @@ void DocumentMedia::checkStickerLarge(not_null<FileLoader*> loader) {
if (_owner->sticker() if (_owner->sticker()
&& !_sticker && !_sticker
&& !loader->imageData().isNull()) { && !loader->imageData().isNull()) {
_sticker = std::make_unique<Image>( _sticker = std::make_unique<Image>(loader->imageData());
std::make_unique<Images::ImageSource>(loader->imageData()));
} }
} }

View File

@ -48,7 +48,7 @@ public:
[[nodiscard]] not_null<DocumentData*> owner() const; [[nodiscard]] not_null<DocumentData*> owner() const;
void goodThumbnailWanted(); void goodThumbnailWanted();
[[nodiscard]] Image *goodThumbnail() const; // #TODO optimize QImage-wrap [[nodiscard]] Image *goodThumbnail() const;
void setGoodThumbnail(QImage thumbnail); void setGoodThumbnail(QImage thumbnail);
[[nodiscard]] Image *thumbnailInline() const; [[nodiscard]] Image *thumbnailInline() const;

View File

@ -25,7 +25,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_theme_document.h" #include "history/view/media/history_view_theme_document.h"
#include "history/view/media/history_view_dice.h" #include "history/view/media/history_view_dice.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "ui/text_options.h" #include "ui/text_options.h"
#include "ui/emoji_config.h" #include "ui/emoji_config.h"
#include "storage/storage_shared_media.h" #include "storage/storage_shared_media.h"

View File

@ -28,7 +28,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwindow.h" #include "mainwindow.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "ui/empty_userpic.h" #include "ui/empty_userpic.h"
#include "ui/text_options.h" #include "ui/text_options.h"
#include "history/history.h" #include "history/history.h"
@ -220,10 +219,9 @@ Image *PeerData::currentUserpic(
_userpicEmpty = nullptr; _userpicEmpty = nullptr;
} else if (isNotificationsUser()) { } else if (isNotificationsUser()) {
static auto result = Image( static auto result = Image(
std::make_unique<Images::ImageSource>( Core::App().logoNoMargin().scaledToWidth(
Core::App().logoNoMargin().scaledToWidth( kUserpicSize,
kUserpicSize, Qt::SmoothTransformation));
Qt::SmoothTransformation)));
return &result; return &result;
} }
return image; return image;
@ -236,7 +234,7 @@ void PeerData::paintUserpic(
int y, int y,
int size) const { int size) const {
if (const auto userpic = currentUserpic(view)) { if (const auto userpic = currentUserpic(view)) {
p.drawPixmap(x, y, userpic->pixCircled(userpicOrigin(), size, size)); p.drawPixmap(x, y, userpic->pixCircled(size, size));
} else { } else {
ensureEmptyUserpic()->paint(p, x, y, x + size + x, size); ensureEmptyUserpic()->paint(p, x, y, x + size + x, size);
} }
@ -249,7 +247,7 @@ void PeerData::paintUserpicRounded(
int y, int y,
int size) const { int size) const {
if (const auto userpic = currentUserpic(view)) { if (const auto userpic = currentUserpic(view)) {
p.drawPixmap(x, y, userpic->pixRounded(userpicOrigin(), size, size, ImageRoundRadius::Small)); p.drawPixmap(x, y, userpic->pixRounded(size, size, ImageRoundRadius::Small));
} else { } else {
ensureEmptyUserpic()->paintRounded(p, x, y, x + size + x, size); ensureEmptyUserpic()->paintRounded(p, x, y, x + size + x, size);
} }
@ -262,7 +260,7 @@ void PeerData::paintUserpicSquare(
int y, int y,
int size) const { int size) const {
if (const auto userpic = currentUserpic(view)) { if (const auto userpic = currentUserpic(view)) {
p.drawPixmap(x, y, userpic->pix(userpicOrigin(), size, size)); p.drawPixmap(x, y, userpic->pix(size, size));
} else { } else {
ensureEmptyUserpic()->paintSquare(p, x, y, x + size + x, size); ensureEmptyUserpic()->paintSquare(p, x, y, x + size + x, size);
} }
@ -319,7 +317,7 @@ QPixmap PeerData::genUserpic(
std::shared_ptr<Data::CloudImageView> &view, std::shared_ptr<Data::CloudImageView> &view,
int size) const { int size) const {
if (const auto userpic = currentUserpic(view)) { if (const auto userpic = currentUserpic(view)) {
return userpic->pixCircled(userpicOrigin(), size, size); return userpic->pixCircled(size, size);
} }
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor()); result.setDevicePixelRatio(cRetinaFactor());
@ -334,8 +332,8 @@ QPixmap PeerData::genUserpic(
QPixmap PeerData::genUserpicRounded( QPixmap PeerData::genUserpicRounded(
std::shared_ptr<Data::CloudImageView> &view, std::shared_ptr<Data::CloudImageView> &view,
int size) const { int size) const {
if (auto userpic = currentUserpic(view)) { if (const auto userpic = currentUserpic(view)) {
return userpic->pixRounded(userpicOrigin(), size, size, ImageRoundRadius::Small); return userpic->pixRounded(size, size, ImageRoundRadius::Small);
} }
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor()); result.setDevicePixelRatio(cRetinaFactor());

View File

@ -12,7 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_reply_preview.h" #include "data/data_reply_preview.h"
#include "data/data_photo_media.h" #include "data/data_photo_media.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "storage/file_download.h" #include "storage/file_download.h"

View File

@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item.h" #include "history/history_item.h"
#include "history/history.h" #include "history/history.h"
#include "storage/file_download.h" #include "storage/file_download.h"
#include "ui/image/image_source.h" #include "ui/image/image.h"
namespace Data { namespace Data {
@ -36,9 +36,7 @@ Image *PhotoMedia::thumbnailInline() const {
if (!_inlineThumbnail) { if (!_inlineThumbnail) {
auto image = Images::FromInlineBytes(_owner->inlineThumbnailBytes()); auto image = Images::FromInlineBytes(_owner->inlineThumbnailBytes());
if (!image.isNull()) { if (!image.isNull()) {
_inlineThumbnail = std::make_unique<Image>( _inlineThumbnail = std::make_unique<Image>(std::move(image));
std::make_unique<Images::ImageSource>(
std::move(image)));
} }
} }
return _inlineThumbnail.get(); return _inlineThumbnail.get();
@ -77,8 +75,7 @@ void PhotoMedia::set(PhotoSize size, QImage image) {
Qt::KeepAspectRatio, Qt::KeepAspectRatio,
Qt::SmoothTransformation); Qt::SmoothTransformation);
} }
_images[index] = std::make_unique<Image>( _images[index] = std::make_unique<Image>(std::move(image));
std::make_unique<Images::ImageSource>(std::move(image)));
_owner->session().downloaderTaskFinished().notify(); _owner->session().downloaderTaskFinished().notify();
} }
@ -112,13 +109,11 @@ void PhotoMedia::automaticLoad(
void PhotoMedia::collectLocalData(not_null<PhotoMedia*> local) { void PhotoMedia::collectLocalData(not_null<PhotoMedia*> local) {
if (const auto image = local->_inlineThumbnail.get()) { if (const auto image = local->_inlineThumbnail.get()) {
_inlineThumbnail = std::make_unique<Image>( _inlineThumbnail = std::make_unique<Image>(image->original());
std::make_unique<Images::ImageSource>(image->original()));
} }
for (auto i = 0; i != kPhotoSizeCount; ++i) { for (auto i = 0; i != kPhotoSizeCount; ++i) {
if (const auto image = local->_images[i].get()) { if (const auto image = local->_images[i].get()) {
_images[i] = std::make_unique<Image>( _images[i] = std::make_unique<Image>(image->original());
std::make_unique<Images::ImageSource>(image->original()));
} }
} }
} }

View File

@ -13,7 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_photo_media.h" #include "data/data_photo_media.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h"
namespace Data { namespace Data {
@ -28,7 +27,7 @@ ReplyPreview::ReplyPreview(not_null<PhotoData*> photo)
ReplyPreview::~ReplyPreview() = default; ReplyPreview::~ReplyPreview() = default;
void ReplyPreview::prepare(not_null<Image*> image, Images::Options options) { void ReplyPreview::prepare(not_null<Image*> image, Images::Options options) {
if (image->isNull() || !image->loaded()) { if (image->isNull()) {
return; return;
} }
int w = image->width(), h = image->height(); int w = image->width(), h = image->height();
@ -47,15 +46,12 @@ void ReplyPreview::prepare(not_null<Image*> image, Images::Options options) {
| options; | options;
auto outerSize = st::msgReplyBarSize.height(); auto outerSize = st::msgReplyBarSize.height();
auto bitmap = image->pixNoCache( auto bitmap = image->pixNoCache(
FileOrigin(),
thumbSize.width(), thumbSize.width(),
thumbSize.height(), thumbSize.height(),
prepareOptions, prepareOptions,
outerSize, outerSize,
outerSize); outerSize);
_image = std::make_unique<Image>( _image = std::make_unique<Image>(bitmap.toImage());
std::make_unique<Images::ImageSource>(
bitmap.toImage()));
_good = ((options & Images::Option::Blurred) == 0); _good = ((options & Images::Option::Blurred) == 0);
} }

View File

@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/mime_type.h" // Core::IsMimeSticker #include "core/mime_type.h" // Core::IsMimeSticker
#include "core/crash_reports.h" // CrashReports::SetAnnotation #include "core/crash_reports.h" // CrashReports::SetAnnotation
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h" // Images::ImageSource
#include "ui/image/image_location_factory.h" // Images::FromPhotoSize #include "ui/image/image_location_factory.h" // Images::FromPhotoSize
#include "export/export_controller.h" #include "export/export_controller.h"
#include "export/view/export_view_panel_controller.h" #include "export/view/export_view_panel_controller.h"
@ -3822,8 +3821,7 @@ void Session::setWallpapers(const QVector<MTPWallPaper> &data, int32 hash) {
_wallpapers.push_back(Data::Legacy1DefaultWallPaper()); _wallpapers.push_back(Data::Legacy1DefaultWallPaper());
_wallpapers.back().setLocalImageAsThumbnail(std::make_shared<Image>( _wallpapers.back().setLocalImageAsThumbnail(std::make_shared<Image>(
std::make_unique<Images::ImageSource>( u":/gui/art/bg_initial.jpg"_q));
u":/gui/art/bg_initial.jpg"_q)));
for (const auto &paper : data) { for (const auto &paper : data) {
if (const auto parsed = Data::WallPaper::Create(paper)) { if (const auto parsed = Data::WallPaper::Create(paper)) {
_wallpapers.push_back(*parsed); _wallpapers.push_back(*parsed);
@ -3835,8 +3833,7 @@ void Session::setWallpapers(const QVector<MTPWallPaper> &data, int32 hash) {
if (defaultFound == end(_wallpapers)) { if (defaultFound == end(_wallpapers)) {
_wallpapers.push_back(Data::DefaultWallPaper()); _wallpapers.push_back(Data::DefaultWallPaper());
_wallpapers.back().setLocalImageAsThumbnail(std::make_shared<Image>( _wallpapers.back().setLocalImageAsThumbnail(std::make_shared<Image>(
std::make_unique<Images::ImageSource>( u":/gui/arg/bg.jpg"_q));
u":/gui/arg/bg.jpg"_q)));
} }
} }

View File

@ -22,7 +22,7 @@ public:
[[nodiscard]] WallPaperId id() const; [[nodiscard]] WallPaperId id() const;
[[nodiscard]] std::optional<QColor> backgroundColor() const; [[nodiscard]] std::optional<QColor> backgroundColor() const;
[[nodiscard]] DocumentData *document() const; [[nodiscard]] DocumentData *document() const;
[[nodiscard]] Image *localThumbnail() const; // #TODO optimize QImage-wrap [[nodiscard]] Image *localThumbnail() const;
[[nodiscard]] bool isPattern() const; [[nodiscard]] bool isPattern() const;
[[nodiscard]] bool isDefault() const; [[nodiscard]] bool isDefault() const;
[[nodiscard]] bool isCreator() const; [[nodiscard]] bool isCreator() const;

View File

@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_document.h" #include "data/data_document.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "ui/text/text_entity.h" #include "ui/text/text_entity.h"
namespace { namespace {

View File

@ -341,7 +341,7 @@ void HistoryMessageReply::paint(
auto to = style::rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x); auto to = style::rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x);
auto previewWidth = image->width() / cIntRetinaFactor(); auto previewWidth = image->width() / cIntRetinaFactor();
auto previewHeight = image->height() / cIntRetinaFactor(); auto previewHeight = image->height() / cIntRetinaFactor();
auto preview = image->pixSingle(replyToMsg->fullId(), previewWidth, previewHeight, to.width(), to.height(), ImageRoundRadius::Small, RectPart::AllCorners, selected ? &st::msgStickerOverlay : nullptr); auto preview = image->pixSingle(previewWidth, previewHeight, to.width(), to.height(), ImageRoundRadius::Small, RectPart::AllCorners, selected ? &st::msgStickerOverlay : nullptr);
p.drawPixmap(to.x(), to.y(), preview); p.drawPixmap(to.x(), to.y(), preview);
} }
} }

View File

@ -6764,7 +6764,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
if (drawMsgText->media() && drawMsgText->media()->hasReplyPreview()) { if (drawMsgText->media() && drawMsgText->media()->hasReplyPreview()) {
if (const auto image = drawMsgText->media()->replyPreview()) { if (const auto image = drawMsgText->media()->replyPreview()) {
auto to = QRect(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); auto to = QRect(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), image->pixSingle(drawMsgText->fullId(), image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small)); p.drawPixmap(to.x(), to.y(), image->pixSingle(image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
} }
replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }
@ -6799,10 +6799,10 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
if (preview) { if (preview) {
auto to = QRect(forwardLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); auto to = QRect(forwardLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
if (preview->width() == preview->height()) { if (preview->width() == preview->height()) {
p.drawPixmap(to.x(), to.y(), preview->pix(firstItem->fullId())); p.drawPixmap(to.x(), to.y(), preview->pix());
} else { } else {
auto from = (preview->width() > preview->height()) ? QRect((preview->width() - preview->height()) / 2, 0, preview->height(), preview->height()) : QRect(0, (preview->height() - preview->width()) / 2, preview->width(), preview->width()); auto from = (preview->width() > preview->height()) ? QRect((preview->width() - preview->height()) / 2, 0, preview->height(), preview->height()) : QRect(0, (preview->height() - preview->width()) / 2, preview->width(), preview->width());
p.drawPixmap(to, preview->pix(firstItem->fullId()), from); p.drawPixmap(to, preview->pix(), from);
} }
forwardLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); forwardLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }
@ -6824,10 +6824,10 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
if (preview) { if (preview) {
auto to = QRect(previewLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); auto to = QRect(previewLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
if (preview->width() == preview->height()) { if (preview->width() == preview->height()) {
p.drawPixmap(to.x(), to.y(), preview->pix(Data::FileOrigin())); p.drawPixmap(to.x(), to.y(), preview->pix());
} else { } else {
auto from = (preview->width() > preview->height()) ? QRect((preview->width() - preview->height()) / 2, 0, preview->height(), preview->height()) : QRect(0, (preview->height() - preview->width()) / 2, preview->width(), preview->width()); auto from = (preview->width() > preview->height()) ? QRect((preview->width() - preview->height()) / 2, 0, preview->height(), preview->height()) : QRect(0, (preview->height() - preview->width()) / 2, preview->width(), preview->width());
p.drawPixmap(to, preview->pix(Data::FileOrigin()), from); p.drawPixmap(to, preview->pix(), from);
} }
} }
previewLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); previewLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
@ -6933,7 +6933,7 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
if (media && media->hasReplyPreview()) { if (media && media->hasReplyPreview()) {
if (const auto image = media->replyPreview()) { if (const auto image = media->replyPreview()) {
QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), image->pixSingle(_pinnedBar->msg->fullId(), image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small)); p.drawPixmap(to.x(), to.y(), image->pixSingle(image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
} }
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }

View File

@ -285,9 +285,9 @@ void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
QRect rthumb(style::rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width())); QRect rthumb(style::rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width()));
QPixmap thumb; QPixmap thumb;
if (const auto normal = _dataMedia->thumbnail()) { if (const auto normal = _dataMedia->thumbnail()) {
thumb = normal->pixSingle(_realParent->fullId(), thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius); thumb = normal->pixSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius);
} else if (const auto blurred = _dataMedia->thumbnailInline()) { } else if (const auto blurred = _dataMedia->thumbnailInline()) {
thumb = blurred->pixBlurredSingle(_realParent->fullId(), thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius); thumb = blurred->pixBlurredSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius);
} }
p.drawPixmap(rthumb.topLeft(), thumb); p.drawPixmap(rthumb.topLeft(), thumb);
if (selected) { if (selected) {

View File

@ -26,7 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_media_common.h" #include "history/view/media/history_view_media_common.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "core/application.h" // Application::showDocument. #include "core/application.h" // Application::showDocument.
#include "ui/image/image_source.h" #include "ui/image/image.h"
#include "ui/grouped_layout.h" #include "ui/grouped_layout.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_streaming.h" #include "data/data_streaming.h"
@ -422,23 +422,23 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
} else { } else {
ensureDataMediaCreated(); ensureDataMediaCreated();
if (const auto good = _dataMedia->goodThumbnail()) { if (const auto good = _dataMedia->goodThumbnail()) {
p.drawPixmap(rthumb.topLeft(), good->pixSingle({}, _thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); p.drawPixmap(rthumb.topLeft(), good->pixSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
} else { } else {
const auto normal = _dataMedia->thumbnail(); const auto normal = _dataMedia->thumbnail();
if (normal) { if (normal) {
if (normal->width() >= kUseNonBlurredThreshold if (normal->width() >= kUseNonBlurredThreshold
|| normal->height() >= kUseNonBlurredThreshold) { || normal->height() >= kUseNonBlurredThreshold) {
p.drawPixmap(rthumb.topLeft(), normal->pixSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); p.drawPixmap(rthumb.topLeft(), normal->pixSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
} else { } else {
p.drawPixmap(rthumb.topLeft(), normal->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); p.drawPixmap(rthumb.topLeft(), normal->pixBlurredSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
} }
} else { } else {
_data->loadThumbnail(_realParent->fullId()); _data->loadThumbnail(_realParent->fullId());
validateVideoThumbnail(); validateVideoThumbnail();
if (_videoThumbnailFrame) { if (_videoThumbnailFrame) {
p.drawPixmap(rthumb.topLeft(), _videoThumbnailFrame->pixSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); p.drawPixmap(rthumb.topLeft(), _videoThumbnailFrame->pixSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
} else if (const auto blurred = _dataMedia->thumbnailInline()) { } else if (const auto blurred = _dataMedia->thumbnailInline()) {
p.drawPixmap(rthumb.topLeft(), blurred->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); p.drawPixmap(rthumb.topLeft(), blurred->pixBlurredSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
} else if (!isRound) { } else if (!isRound) {
const auto roundTop = (roundCorners & RectPart::TopLeft); const auto roundTop = (roundCorners & RectPart::TopLeft);
const auto roundBottom = (roundCorners & RectPart::BottomLeft); const auto roundBottom = (roundCorners & RectPart::BottomLeft);
@ -649,11 +649,9 @@ void Gif::validateVideoThumbnail() const {
return; return;
} }
auto info = ::Media::Clip::PrepareForSending(QString(), content); auto info = ::Media::Clip::PrepareForSending(QString(), content);
_videoThumbnailFrame = std::make_unique<Image>( _videoThumbnailFrame = std::make_unique<Image>(info.thumbnail.isNull()
std::make_unique<Images::ImageSource>( ? Image::BlankMedia()->original()
(info.thumbnail.isNull() : info.thumbnail);
? Image::BlankMedia()->original()
: info.thumbnail)));
} }
void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const { void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const {
@ -1214,7 +1212,6 @@ void Gif::validateGroupedCache(
*cacheKey = key; *cacheKey = key;
*cache = (image ? image : Image::BlankMedia().get())->pixNoCache( *cache = (image ? image : Image::BlankMedia().get())->pixNoCache(
_realParent->fullId(),
pixWidth, pixWidth,
pixHeight, pixHeight,
options, options,

View File

@ -71,7 +71,6 @@ void LargeEmoji::draw(Painter &p, const QRect &r, bool selected) {
const auto &padding = st::largeEmojiPadding; const auto &padding = st::largeEmojiPadding;
auto x = r.x() + (r.width() - _size.width()) / 2 + padding.left(); auto x = r.x() + (r.width() - _size.width()) / 2 + padding.left();
const auto y = r.y() + (r.height() - _size.height()) / 2 + padding.top(); const auto y = r.y() + (r.height() - _size.height()) / 2 + padding.top();
const auto o = Data::FileOrigin();
const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline; const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
const auto size = EmojiImage::Size() / cIntRetinaFactor(); const auto size = EmojiImage::Size() / cIntRetinaFactor();
for (const auto &image : images) { for (const auto &image : images) {
@ -80,8 +79,8 @@ void LargeEmoji::draw(Painter &p, const QRect &r, bool selected) {
const auto h = size.height(); const auto h = size.height();
const auto &c = st::msgStickerOverlay; const auto &c = st::msgStickerOverlay;
const auto pixmap = selected const auto pixmap = selected
? prepared->pixColored(o, c, w, h) ? prepared->pixColored(c, w, h)
: prepared->pix(o, w, h); : prepared->pix(w, h);
p.drawPixmap(x, y, pixmap); p.drawPixmap(x, y, pixmap);
} else if (image->load) { } else if (image->load) {
image->load(); image->load();

View File

@ -180,7 +180,7 @@ void Location::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
auto rthumb = QRect(paintx, painty, paintw, painth); auto rthumb = QRect(paintx, painty, paintw, painth);
ensureMediaCreated(); ensureMediaCreated();
if (const auto thumbnail = _media->image()) { if (const auto thumbnail = _media->image()) {
const auto &pix = thumbnail->pixSingle({}, paintw, painth, paintw, painth, roundRadius, roundCorners); const auto &pix = thumbnail->pixSingle(paintw, painth, paintw, painth, roundRadius, roundCorners);
p.drawPixmap(rthumb.topLeft(), pix); p.drawPixmap(rthumb.topLeft(), pix);
} else { } else {
App::complexLocationRect(p, rthumb, roundRadius, roundCorners); App::complexLocationRect(p, rthumb, roundRadius, roundCorners);

View File

@ -211,15 +211,15 @@ void Photo::draw(Painter &p, const QRect &r, TextSelection selection, crl::time
if (_serviceWidth > 0) { if (_serviceWidth > 0) {
const auto pix = [&] { const auto pix = [&] {
if (const auto large = _dataMedia->image(PhotoSize::Large)) { if (const auto large = _dataMedia->image(PhotoSize::Large)) {
return large->pixCircled(_realParent->fullId(), _pixw, _pixh); return large->pixCircled(_pixw, _pixh);
} else if (const auto thumbnail = _dataMedia->image( } else if (const auto thumbnail = _dataMedia->image(
PhotoSize::Thumbnail)) { PhotoSize::Thumbnail)) {
return thumbnail->pixBlurredCircled(_realParent->fullId(), _pixw, _pixh); return thumbnail->pixBlurredCircled(_pixw, _pixh);
} else if (const auto small = _dataMedia->image( } else if (const auto small = _dataMedia->image(
PhotoSize::Small)) { PhotoSize::Small)) {
return small->pixBlurredCircled(_realParent->fullId(), _pixw, _pixh); return small->pixBlurredCircled(_pixw, _pixh);
} else if (const auto blurred = _dataMedia->thumbnailInline()) { } else if (const auto blurred = _dataMedia->thumbnailInline()) {
return blurred->pixBlurredCircled(_realParent->fullId(), _pixw, _pixh); return blurred->pixBlurredCircled(_pixw, _pixh);
} else { } else {
return QPixmap(); return QPixmap();
} }
@ -243,15 +243,15 @@ void Photo::draw(Painter &p, const QRect &r, TextSelection selection, crl::time
| ((isBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None)); | ((isBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None));
const auto pix = [&] { const auto pix = [&] {
if (const auto large = _dataMedia->image(PhotoSize::Large)) { if (const auto large = _dataMedia->image(PhotoSize::Large)) {
return large->pixSingle(_realParent->fullId(), _pixw, _pixh, paintw, painth, roundRadius, roundCorners); return large->pixSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners);
} else if (const auto thumbnail = _dataMedia->image( } else if (const auto thumbnail = _dataMedia->image(
PhotoSize::Thumbnail)) { PhotoSize::Thumbnail)) {
return thumbnail->pixBlurredSingle(_realParent->fullId(), _pixw, _pixh, paintw, painth, roundRadius, roundCorners); return thumbnail->pixBlurredSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners);
} else if (const auto small = _dataMedia->image( } else if (const auto small = _dataMedia->image(
PhotoSize::Small)) { PhotoSize::Small)) {
return small->pixBlurredSingle(_realParent->fullId(), _pixw, _pixh, paintw, painth, roundRadius, roundCorners); return small->pixBlurredSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners);
} else if (const auto blurred = _dataMedia->thumbnailInline()) { } else if (const auto blurred = _dataMedia->thumbnailInline()) {
return blurred->pixBlurredSingle(_realParent->fullId(), _pixw, _pixh, paintw, painth, roundRadius, roundCorners); return blurred->pixBlurredSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners);
} else { } else {
return QPixmap(); return QPixmap();
} }
@ -577,7 +577,7 @@ void Photo::validateGroupedCache(
: Image::BlankMedia().get(); : Image::BlankMedia().get();
*cacheKey = key; *cacheKey = key;
*cache = image->pixNoCache(_realParent->fullId(), pixWidth, pixHeight, options, width, height); *cache = image->pixNoCache(pixWidth, pixHeight, options, width, height);
} }
TextForMimeData Photo::selectedText(TextSelection selection) const { TextForMimeData Photo::selectedText(TextSelection selection) const {

View File

@ -208,30 +208,29 @@ void Sticker::paintPixmap(Painter &p, const QRect &r, bool selected) {
} }
QPixmap Sticker::paintedPixmap(bool selected) const { QPixmap Sticker::paintedPixmap(bool selected) const {
const auto o = _parent->data()->fullId();
const auto w = _size.width(); const auto w = _size.width();
const auto h = _size.height(); const auto h = _size.height();
const auto &c = st::msgStickerOverlay; const auto &c = st::msgStickerOverlay;
const auto good = _dataMedia->goodThumbnail(); const auto good = _dataMedia->goodThumbnail();
if (const auto image = _dataMedia->getStickerLarge()) { if (const auto image = _dataMedia->getStickerLarge()) {
return selected return selected
? image->pixColored(o, c, w, h) ? image->pixColored(c, w, h)
: image->pix(o, w, h); : image->pix(w, h);
// //
// Inline thumbnails can't have alpha channel. // Inline thumbnails can't have alpha channel.
// //
//} else if (const auto blurred = _data->thumbnailInline()) { //} else if (const auto blurred = _data->thumbnailInline()) {
// return selected // return selected
// ? blurred->pixBlurredColored(o, c, w, h) // ? blurred->pixBlurredColored(c, w, h)
// : blurred->pixBlurred(o, w, h); // : blurred->pixBlurred(w, h);
} else if (good) { } else if (good) {
return selected return selected
? good->pixColored(o, c, w, h) ? good->pixColored(c, w, h)
: good->pix(o, w, h); : good->pix(w, h);
} else if (const auto thumbnail = _dataMedia->thumbnail()) { } else if (const auto thumbnail = _dataMedia->thumbnail()) {
return selected return selected
? thumbnail->pixBlurredColored(o, c, w, h) ? thumbnail->pixBlurredColored(c, w, h)
: thumbnail->pixBlurred(o, w, h); : thumbnail->pixBlurred(w, h);
} }
return QPixmap(); return QPixmap();
} }

View File

@ -483,12 +483,12 @@ void WebPage::draw(Painter &p, const QRect &r, TextSelection selection, crl::tim
} }
if (const auto thumbnail = _photoMedia->image( if (const auto thumbnail = _photoMedia->image(
Data::PhotoSize::Thumbnail)) { Data::PhotoSize::Thumbnail)) {
pix = thumbnail->pixSingle(contextId, pixw, pixh, pw, ph, ImageRoundRadius::Small); pix = thumbnail->pixSingle(pixw, pixh, pw, ph, ImageRoundRadius::Small);
} else if (const auto small = _photoMedia->image( } else if (const auto small = _photoMedia->image(
Data::PhotoSize::Small)) { Data::PhotoSize::Small)) {
pix = small->pixBlurredSingle(contextId, pixw, pixh, pw, ph, ImageRoundRadius::Small); pix = small->pixBlurredSingle(pixw, pixh, pw, ph, ImageRoundRadius::Small);
} else if (const auto blurred = _photoMedia->thumbnailInline()) { } else if (const auto blurred = _photoMedia->thumbnailInline()) {
pix = blurred->pixBlurredSingle(contextId, pixw, pixh, pw, ph, ImageRoundRadius::Small); pix = blurred->pixBlurredSingle(pixw, pixh, pw, ph, ImageRoundRadius::Small);
} }
p.drawPixmapLeft(padding.left() + paintw - pw, tshift, width(), pix); p.drawPixmapLeft(padding.left() + paintw - pw, tshift, width(), pix);
if (selected) { if (selected) {

View File

@ -321,7 +321,6 @@ void Gif::validateThumbnail(
} }
_thumbGood = good; _thumbGood = good;
_thumb = image->pixNoCache( _thumb = image->pixNoCache(
fileOrigin(),
frame.width() * cIntRetinaFactor(), frame.width() * cIntRetinaFactor(),
frame.height() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(),
(Images::Option::Smooth (Images::Option::Smooth
@ -554,7 +553,6 @@ void Sticker::prepareThumbnail() const {
if (!_lottie && !_thumbLoaded && _dataMedia->loaded()) { if (!_lottie && !_thumbLoaded && _dataMedia->loaded()) {
const auto thumbSize = getThumbSize(); const auto thumbSize = getThumbSize();
_thumb = sticker->pix( _thumb = sticker->pix(
document->stickerSetOrigin(),
thumbSize.width(), thumbSize.width(),
thumbSize.height()); thumbSize.height());
_thumbLoaded = true; _thumbLoaded = true;
@ -653,7 +651,6 @@ void Photo::validateThumbnail(
} }
const auto origin = fileOrigin(); const auto origin = fileOrigin();
_thumb = image->pixNoCache( _thumb = image->pixNoCache(
origin,
frame.width() * cIntRetinaFactor(), frame.width() * cIntRetinaFactor(),
frame.height() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(),
Images::Option::Smooth | (good ? Images::Option(0) : Images::Option::Blurred), Images::Option::Smooth | (good ? Images::Option(0) : Images::Option::Blurred),
@ -809,7 +806,7 @@ void Video::prepareThumbnail(QSize size) const {
w = width; w = width;
} }
} }
_thumb = thumb->pixNoCache({}, w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
} }
@ -1139,7 +1136,7 @@ void Contact::prepareThumbnail(int width, int height) const {
w = width; w = width;
} }
} }
_thumb = thumb->pixNoCache(origin, w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
Article::Article( Article::Article(
@ -1291,7 +1288,7 @@ void Article::prepareThumbnail(int width, int height) const {
w = width; w = width;
} }
} }
_thumb = thumb->pixNoCache(origin, w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
Game::Game(not_null<Context*> context, not_null<Result*> result) Game::Game(not_null<Context*> context, not_null<Result*> result)
@ -1506,7 +1503,6 @@ void Game::validateThumbnail(Image *image, QSize size, bool good) const {
} }
_thumbGood = good; _thumbGood = good;
_thumb = image->pixNoCache( _thumb = image->pixNoCache(
fileOrigin(),
w * cIntRetinaFactor(), w * cIntRetinaFactor(),
h * cIntRetinaFactor(), h * cIntRetinaFactor(),
(Images::Option::Smooth (Images::Option::Smooth

View File

@ -34,7 +34,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h" #include "ui/toast/toast.h"
#include "ui/widgets/dropdown_menu.h" #include "ui/widgets/dropdown_menu.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "ui/focus_persister.h" #include "ui/focus_persister.h"
#include "ui/resize_area.h" #include "ui/resize_area.h"
#include "ui/text_options.h" #include "ui/text_options.h"
@ -1354,8 +1353,7 @@ void MainWidget::setReadyChatBackground(
if (image.isNull() if (image.isNull()
&& !background.document() && !background.document()
&& background.localThumbnail() && background.localThumbnail()) {
&& background.localThumbnail()->loaded()) {
image = background.localThumbnail()->original(); image = background.localThumbnail()->original();
} }

View File

@ -248,7 +248,7 @@ void GroupThumbs::Thumb::validateImage() {
const auto originalHeight = _image->height(); const auto originalHeight = _image->height();
const auto takeWidth = originalWidth * st::mediaviewGroupWidthMax const auto takeWidth = originalWidth * st::mediaviewGroupWidthMax
/ pixSize.width(); / pixSize.width();
const auto original = _image->pixNoCache(_origin).toImage(); const auto original = _image->original();
_full = App::pixmapFromImageInPlace(original.copy( _full = App::pixmapFromImageInPlace(original.copy(
(originalWidth - takeWidth) / 2, (originalWidth - takeWidth) / 2,
0, 0,
@ -261,7 +261,6 @@ void GroupThumbs::Thumb::validateImage() {
Qt::SmoothTransformation)); Qt::SmoothTransformation));
} else { } else {
_full = _image->pixNoCache( _full = _image->pixNoCache(
_origin,
pixSize.width() * cIntRetinaFactor(), pixSize.width() * cIntRetinaFactor(),
pixSize.height() * cIntRetinaFactor(), pixSize.height() * cIntRetinaFactor(),
Images::Option::Smooth); Images::Option::Smooth);

View File

@ -2014,10 +2014,9 @@ void OverlayWidget::displayDocument(
if (_document) { if (_document) {
if (_document->sticker()) { if (_document->sticker()) {
if (const auto image = _documentMedia->getStickerLarge()) { if (const auto image = _documentMedia->getStickerLarge()) {
_staticContent = image->pix(fileOrigin()); _staticContent = image->pix();
} else if (const auto thumbnail = _documentMedia->thumbnail()) { } else if (const auto thumbnail = _documentMedia->thumbnail()) {
_staticContent = thumbnail->pixBlurred( _staticContent = thumbnail->pixBlurred(
fileOrigin(),
_document->dimensions.width(), _document->dimensions.width(),
_document->dimensions.height()); _document->dimensions.height());
} }
@ -2235,7 +2234,6 @@ void OverlayWidget::initStreamingThumbnail() {
: blurred : blurred
? blurred ? blurred
: Image::BlankMedia().get())->pixNoCache( : Image::BlankMedia().get())->pixNoCache(
fileOrigin(),
w, w,
h, h,
useGood ? goodOptions : options, useGood ? goodOptions : options,
@ -2715,7 +2713,7 @@ void OverlayWidget::updatePlaybackState() {
} }
void OverlayWidget::validatePhotoImage(Image *image, bool blurred) { void OverlayWidget::validatePhotoImage(Image *image, bool blurred) {
if (!image || !image->loaded()) { if (!image) {
return; return;
} else if (!_staticContent.isNull() && (blurred || !_blurred)) { } else if (!_staticContent.isNull() && (blurred || !_blurred)) {
return; return;
@ -2723,7 +2721,6 @@ void OverlayWidget::validatePhotoImage(Image *image, bool blurred) {
const auto use = flipSizeByRotation({ _width, _height }) const auto use = flipSizeByRotation({ _width, _height })
* cIntRetinaFactor(); * cIntRetinaFactor();
_staticContent = image->pixNoCache( _staticContent = image->pixNoCache(
fileOrigin(),
use.width(), use.width(),
use.height(), use.height(),
Images::Option::Smooth Images::Option::Smooth
@ -2842,7 +2839,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
} }
} else if (const auto thumbnail = _documentMedia->thumbnail()) { } else if (const auto thumbnail = _documentMedia->thumbnail()) {
int32 rf(cIntRetinaFactor()); int32 rf(cIntRetinaFactor());
p.drawPixmap(_docIconRect.topLeft(), thumbnail->pix(fileOrigin(), _docThumbw), QRect(_docThumbx * rf, _docThumby * rf, st::mediaviewFileIconSize * rf, st::mediaviewFileIconSize * rf)); p.drawPixmap(_docIconRect.topLeft(), thumbnail->pix(_docThumbw), QRect(_docThumbx * rf, _docThumby * rf, st::mediaviewFileIconSize * rf, st::mediaviewFileIconSize * rf));
} }
paintRadialLoading(p, radial, radialOpacity); paintRadialLoading(p, radial, radialOpacity);

View File

@ -838,8 +838,7 @@ void Pip::setupPanel() {
} }
const auto media = _data->activeMediaView(); const auto media = _data->activeMediaView();
const auto good = media ? media->goodThumbnail() : nullptr; const auto good = media ? media->goodThumbnail() : nullptr;
const auto useGood = (good && good->loaded()); const auto original = good ? good->size() : _data->dimensions;
const auto original = useGood ? good->size() : _data->dimensions;
return original.isEmpty() ? QSize(1, 1) : original; return original.isEmpty() ? QSize(1, 1) : original;
}(); }();
_panel.setAspectRatio(FlipSizeByRotation(size, _rotation)); _panel.setAspectRatio(FlipSizeByRotation(size, _rotation));
@ -1427,7 +1426,6 @@ QImage Pip::videoFrame(const FrameRequest &request) const {
: blurred : blurred
? blurred ? blurred
: Image::BlankMedia().get())->pixNoCache( : Image::BlankMedia().get())->pixNoCache(
_contextId,
request.resize.width(), request.resize.width(),
request.resize.height(), request.resize.height(),
options, options,

View File

@ -439,8 +439,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
const auto selected = (selection == FullSelection); const auto selected = (selection == FullSelection);
const auto blurred = _dataMedia->thumbnailInline(); const auto blurred = _dataMedia->thumbnailInline();
const auto thumbnail = _dataMedia->thumbnail(); const auto thumbnail = _dataMedia->thumbnail();
const auto goodLoaded = _dataMedia->goodThumbnail() const auto good = _dataMedia->goodThumbnail();
&& _dataMedia->goodThumbnail()->loaded();
bool loaded = dataLoaded(), displayLoading = _data->displayLoading(); bool loaded = dataLoaded(), displayLoading = _data->displayLoading();
if (displayLoading) { if (displayLoading) {
@ -453,12 +452,12 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
const auto radial = isRadialAnimation(); const auto radial = isRadialAnimation();
const auto radialOpacity = radial ? _radial->opacity() : 0.; const auto radialOpacity = radial ? _radial->opacity() : 0.;
if ((blurred || thumbnail || goodLoaded) if ((blurred || thumbnail || good)
&& ((_pix.width() != _width * cIntRetinaFactor()) && ((_pix.width() != _width * cIntRetinaFactor())
|| (_pixBlurred && (thumbnail || goodLoaded)))) { || (_pixBlurred && (thumbnail || good)))) {
auto size = _width * cIntRetinaFactor(); auto size = _width * cIntRetinaFactor();
auto img = goodLoaded auto img = good
? _dataMedia->goodThumbnail()->original() ? good->original()
: thumbnail : thumbnail
? thumbnail->original() ? thumbnail->original()
: Images::prepareBlur(blurred->original()); : Images::prepareBlur(blurred->original());
@ -474,7 +473,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
img.setDevicePixelRatio(cRetinaFactor()); img.setDevicePixelRatio(cRetinaFactor());
_pix = App::pixmapFromImageInPlace(std::move(img)); _pix = App::pixmapFromImageInPlace(std::move(img));
_pixBlurred = !(thumbnail || goodLoaded); _pixBlurred = !(thumbnail || good);
} }
if (_pix.isNull()) { if (_pix.isNull()) {
@ -695,14 +694,8 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
if (thumbnail || blurred) { if (thumbnail || blurred) {
const auto thumb = thumbnail const auto thumb = thumbnail
? thumbnail->pixCircled( ? thumbnail->pixCircled(inner.width(), inner.height())
parent()->fullId(), : blurred->pixBlurredCircled(inner.width(), inner.height());
inner.width(),
inner.height())
: blurred->pixBlurredCircled(
parent()->fullId(),
inner.width(),
inner.height());
p.drawPixmap(inner.topLeft(), thumb); p.drawPixmap(inner.topLeft(), thumb);
} else if (_data->hasThumbnail()) { } else if (_data->hasThumbnail()) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
@ -1070,7 +1063,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
? Images::Option::None ? Images::Option::None
: Images::Option::Blurred); : Images::Option::Blurred);
const auto image = thumbnail ? thumbnail : blurred; const auto image = thumbnail ? thumbnail : blurred;
_thumb = image->pixNoCache(parent()->fullId(), _thumbw * cIntRetinaFactor(), 0, options, _st.fileThumbSize, _st.fileThumbSize); _thumb = image->pixNoCache(_thumbw * cIntRetinaFactor(), 0, options, _st.fileThumbSize, _st.fileThumbSize);
} }
p.drawPixmap(rthumb.topLeft(), _thumb); p.drawPixmap(rthumb.topLeft(), _thumb);
} else { } else {
@ -1628,13 +1621,13 @@ void Link::validateThumbnail() {
using Data::PhotoSize; using Data::PhotoSize;
ensurePhotoMediaCreated(); ensurePhotoMediaCreated();
if (const auto thumbnail = _photoMedia->image(PhotoSize::Thumbnail)) { if (const auto thumbnail = _photoMedia->image(PhotoSize::Thumbnail)) {
_thumbnail = thumbnail->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); _thumbnail = thumbnail->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small);
} else if (const auto large = _photoMedia->image(PhotoSize::Large)) { } else if (const auto large = _photoMedia->image(PhotoSize::Large)) {
_thumbnail = large->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); _thumbnail = large->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small);
} else if (const auto small = _photoMedia->image(PhotoSize::Small)) { } else if (const auto small = _photoMedia->image(PhotoSize::Small)) {
_thumbnail = small->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); _thumbnail = small->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small);
} else if (const auto blurred = _photoMedia->thumbnailInline()) { } else if (const auto blurred = _photoMedia->thumbnailInline()) {
_thumbnail = blurred->pixBlurredSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); _thumbnail = blurred->pixBlurredSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small);
} else { } else {
return; return;
} }
@ -1646,7 +1639,7 @@ void Link::validateThumbnail() {
auto roundRadius = _page->document->isVideoMessage() auto roundRadius = _page->document->isVideoMessage()
? ImageRoundRadius::Ellipse ? ImageRoundRadius::Ellipse
: ImageRoundRadius::Small; : ImageRoundRadius::Small;
_thumbnail = thumbnail->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius); _thumbnail = thumbnail->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius);
_documentMedia = nullptr; _documentMedia = nullptr;
delegate()->unregisterHeavyItem(this); delegate()->unregisterHeavyItem(this);
} }

View File

@ -709,7 +709,6 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
.scaled(kCircleDiameter, kCircleDiameter, Qt::KeepAspectRatio); .scaled(kCircleDiameter, kCircleDiameter, Qt::KeepAspectRatio);
_imageView.image = [qt_mac_create_nsimage( _imageView.image = [qt_mac_create_nsimage(
_image->pixSingle( _image->pixSingle(
fileOrigin,
size.width(), size.width(),
size.height(), size.height(),
kCircleDiameter, kCircleDiameter,

View File

@ -482,7 +482,7 @@ bool Manager::Private::showNotification(
const auto key = hideNameAndPhoto const auto key = hideNameAndPhoto
? InMemoryKey() ? InMemoryKey()
: peer->userpicUniqueKey(view); : peer->userpicUniqueKey(view);
const auto userpicPath = _cachedUserpics.get(key, peer); const auto userpicPath = _cachedUserpics.get(key, peer, view);
const auto userpicPathWide = QDir::toNativeSeparators(userpicPath).toStdWString(); const auto userpicPathWide = QDir::toNativeSeparators(userpicPath).toStdWString();
hr = SetImageSrc(userpicPathWide.c_str(), toastXml.Get()); hr = SetImageSrc(userpicPathWide.c_str(), toastXml.Get());

View File

@ -27,7 +27,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/radial_animation.h" #include "ui/effects/radial_animation.h"
#include "ui/toast/toast.h" #include "ui/toast/toast.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "window/themes/window_themes_embedded.h" #include "window/themes/window_themes_embedded.h"
@ -439,7 +438,6 @@ void BackgroundRow::paintEvent(QPaintEvent *e) {
p.drawPixmap(0, 0, _background); p.drawPixmap(0, 0, _background);
} else { } else {
const auto &pix = backThumb->pixBlurred( const auto &pix = backThumb->pixBlurred(
Data::FileOrigin(),
st::settingsBackgroundThumb); st::settingsBackgroundThumb);
const auto factor = cIntRetinaFactor(); const auto factor = cIntRetinaFactor();
p.drawPixmap( p.drawPixmap(
@ -630,7 +628,7 @@ void ChooseFromFile(
} }
auto local = Data::CustomWallPaper(); auto local = Data::CustomWallPaper();
local.setLocalImageAsThumbnail(std::make_shared<Image>( local.setLocalImageAsThumbnail(std::make_shared<Image>(
std::make_unique<Images::ImageSource>(std::move(image)))); std::move(image)));
Ui::show(Box<BackgroundPreviewBox>(session, local)); Ui::show(Box<BackgroundPreviewBox>(session, local));
}); });
FileDialog::GetOpenPath( FileDialog::GetOpenPath(

View File

@ -7,10 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "storage/cache/storage_cache_database.h" #include "storage/cache/storage_cache_database.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_file_origin.h"
#include "chat_helpers/stickers.h" #include "chat_helpers/stickers.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "app.h" #include "app.h"
@ -20,16 +18,27 @@ using namespace Images;
namespace Images { namespace Images {
namespace { namespace {
uint64 PixKey(int width, int height, Options options) { [[nodiscard]] uint64 PixKey(int width, int height, Options options) {
return static_cast<uint64>(width) return static_cast<uint64>(width)
| (static_cast<uint64>(height) << 24) | (static_cast<uint64>(height) << 24)
| (static_cast<uint64>(options) << 48); | (static_cast<uint64>(options) << 48);
} }
uint64 SinglePixKey(Options options) { [[nodiscard]] uint64 SinglePixKey(Options options) {
return PixKey(0, 0, options); return PixKey(0, 0, options);
} }
[[nodiscard]] QByteArray ReadContent(const QString &path) {
auto file = QFile(path);
const auto good = (file.size() <= App::kImageSizeLimit)
&& file.open(QIODevice::ReadOnly);
return good ? file.readAll() : QByteArray();
}
[[nodiscard]] QImage ReadImage(const QByteArray &content) {
return App::readImage(content, nullptr, false, nullptr);
}
} // namespace } // namespace
QByteArray ExpandInlineBytes(const QByteArray &bytes) { QByteArray ExpandInlineBytes(const QByteArray &bytes) {
@ -97,14 +106,17 @@ QSize GetSizeForDocument(const QVector<MTPDocumentAttribute> &attributes) {
} // namespace Images } // namespace Images
Image::Image(std::unique_ptr<Source> &&source) Image::Image(const QString &path) : Image(ReadContent(path)) {
: _source(std::move(source)) {
} }
Image::~Image() = default; Image::Image(const QByteArray &content) : Image(ReadImage(content)) {
}
Image::Image(QImage &&data) : _data(std::move(data)) {
}
not_null<Image*> Image::Empty() { not_null<Image*> Image::Empty() {
static auto result = [] { static auto result = Image([] {
const auto factor = cIntRetinaFactor(); const auto factor = cIntRetinaFactor();
auto data = QImage( auto data = QImage(
factor, factor,
@ -112,13 +124,13 @@ not_null<Image*> Image::Empty() {
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
data.fill(Qt::transparent); data.fill(Qt::transparent);
data.setDevicePixelRatio(cRetinaFactor()); data.setDevicePixelRatio(cRetinaFactor());
return Image(std::make_unique<ImageSource>(std::move(data))); return data;
}(); }());
return &result; return &result;
} }
not_null<Image*> Image::BlankMedia() { not_null<Image*> Image::BlankMedia() {
static auto result = [] { static auto result = Image([] {
const auto factor = cIntRetinaFactor(); const auto factor = cIntRetinaFactor();
auto data = QImage( auto data = QImage(
factor, factor,
@ -126,21 +138,16 @@ not_null<Image*> Image::BlankMedia() {
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
data.fill(Qt::black); data.fill(Qt::black);
data.setDevicePixelRatio(cRetinaFactor()); data.setDevicePixelRatio(cRetinaFactor());
return Image(std::make_unique<ImageSource>(std::move(data))); return data;
}(); }());
return &result; return &result;
} }
bool Image::isNull() const { QImage Image::original() const {
return (this == Empty()); return _data;
} }
const QPixmap &Image::pix( const QPixmap &Image::pix(int w, int h) const {
Data::FileOrigin origin,
int32 w,
int32 h) const {
checkSource();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
w = width(); w = width();
} else { } else {
@ -149,23 +156,20 @@ const QPixmap &Image::pix(
} }
auto options = Option::Smooth | Option::None; auto options = Option::Smooth | Option::None;
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _cache.find(k);
if (i == _sizesCache.cend()) { if (i == _cache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _cache.emplace(k, p).first;
} }
return i.value(); return i->second;
} }
const QPixmap &Image::pixRounded( const QPixmap &Image::pixRounded(
Data::FileOrigin origin, int w,
int32 w, int h,
int32 h,
ImageRoundRadius radius, ImageRoundRadius radius,
RectParts corners) const { RectParts corners) const {
checkSource();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
w = width(); w = width();
} else { } else {
@ -187,21 +191,16 @@ const QPixmap &Image::pixRounded(
options |= Option::Circled | cornerOptions(corners); options |= Option::Circled | cornerOptions(corners);
} }
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _cache.find(k);
if (i == _sizesCache.cend()) { if (i == _cache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _cache.emplace(k, p).first;
} }
return i.value(); return i->second;
} }
const QPixmap &Image::pixCircled( const QPixmap &Image::pixCircled(int w, int h) const {
Data::FileOrigin origin,
int32 w,
int32 h) const {
checkSource();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
w = width(); w = width();
} else { } else {
@ -210,21 +209,16 @@ const QPixmap &Image::pixCircled(
} }
auto options = Option::Smooth | Option::Circled; auto options = Option::Smooth | Option::Circled;
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _cache.find(k);
if (i == _sizesCache.cend()) { if (i == _cache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _cache.emplace(k, p).first;
} }
return i.value(); return i->second;
} }
const QPixmap &Image::pixBlurredCircled( const QPixmap &Image::pixBlurredCircled(int w, int h) const {
Data::FileOrigin origin,
int32 w,
int32 h) const {
checkSource();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
w = width(); w = width();
} else { } else {
@ -233,21 +227,16 @@ const QPixmap &Image::pixBlurredCircled(
} }
auto options = Option::Smooth | Option::Circled | Option::Blurred; auto options = Option::Smooth | Option::Circled | Option::Blurred;
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _cache.find(k);
if (i == _sizesCache.cend()) { if (i == _cache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _cache.emplace(k, p).first;
} }
return i.value(); return i->second;
} }
const QPixmap &Image::pixBlurred( const QPixmap &Image::pixBlurred(int w, int h) const {
Data::FileOrigin origin,
int32 w,
int32 h) const {
checkSource();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor(); w = width() * cIntRetinaFactor();
} else { } else {
@ -256,22 +245,16 @@ const QPixmap &Image::pixBlurred(
} }
auto options = Option::Smooth | Option::Blurred; auto options = Option::Smooth | Option::Blurred;
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _cache.find(k);
if (i == _sizesCache.cend()) { if (i == _cache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _cache.emplace(k, p).first;
} }
return i.value(); return i->second;
} }
const QPixmap &Image::pixColored( const QPixmap &Image::pixColored(style::color add, int w, int h) const {
Data::FileOrigin origin,
style::color add,
int32 w,
int32 h) const {
checkSource();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor(); w = width() * cIntRetinaFactor();
} else { } else {
@ -280,22 +263,19 @@ const QPixmap &Image::pixColored(
} }
auto options = Option::Smooth | Option::Colored; auto options = Option::Smooth | Option::Colored;
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _cache.find(k);
if (i == _sizesCache.cend()) { if (i == _cache.cend()) {
auto p = pixColoredNoCache(origin, add, w, h, true); auto p = pixColoredNoCache(add, w, h, true);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _cache.emplace(k, p).first;
} }
return i.value(); return i->second;
} }
const QPixmap &Image::pixBlurredColored( const QPixmap &Image::pixBlurredColored(
Data::FileOrigin origin,
style::color add, style::color add,
int32 w, int w,
int32 h) const { int h) const {
checkSource();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor(); w = width() * cIntRetinaFactor();
} else { } else {
@ -304,26 +284,23 @@ const QPixmap &Image::pixBlurredColored(
} }
auto options = Option::Blurred | Option::Smooth | Option::Colored; auto options = Option::Blurred | Option::Smooth | Option::Colored;
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _cache.find(k);
if (i == _sizesCache.cend()) { if (i == _cache.cend()) {
auto p = pixBlurredColoredNoCache(origin, add, w, h); auto p = pixBlurredColoredNoCache(add, w, h);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _cache.emplace(k, p).first;
} }
return i.value(); return i->second;
} }
const QPixmap &Image::pixSingle( const QPixmap &Image::pixSingle(
Data::FileOrigin origin, int w,
int32 w, int h,
int32 h, int outerw,
int32 outerw, int outerh,
int32 outerh,
ImageRoundRadius radius, ImageRoundRadius radius,
RectParts corners, RectParts corners,
const style::color *colored) const { const style::color *colored) const {
checkSource();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor(); w = width() * cIntRetinaFactor();
} else { } else {
@ -350,25 +327,22 @@ const QPixmap &Image::pixSingle(
} }
auto k = SinglePixKey(options); auto k = SinglePixKey(options);
auto i = _sizesCache.constFind(k); auto i = _cache.find(k);
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) { if (i == _cache.cend() || i->second.width() != (outerw * cIntRetinaFactor()) || i->second.height() != (outerh * cIntRetinaFactor())) {
auto p = pixNoCache(origin, w, h, options, outerw, outerh, colored); auto p = pixNoCache(w, h, options, outerw, outerh, colored);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _cache.emplace(k, p).first;
} }
return i.value(); return i->second;
} }
const QPixmap &Image::pixBlurredSingle( const QPixmap &Image::pixBlurredSingle(
Data::FileOrigin origin, int w,
int32 w, int h,
int32 h, int outerw,
int32 outerw, int outerh,
int32 outerh,
ImageRoundRadius radius, ImageRoundRadius radius,
RectParts corners) const { RectParts corners) const {
checkSource();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor(); w = width() * cIntRetinaFactor();
} else { } else {
@ -392,30 +366,27 @@ const QPixmap &Image::pixBlurredSingle(
} }
auto k = SinglePixKey(options); auto k = SinglePixKey(options);
auto i = _sizesCache.constFind(k); auto i = _cache.find(k);
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) { if (i == _cache.cend() || i->second.width() != (outerw * cIntRetinaFactor()) || i->second.height() != (outerh * cIntRetinaFactor())) {
auto p = pixNoCache(origin, w, h, options, outerw, outerh); auto p = pixNoCache(w, h, options, outerw, outerh);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _cache.emplace(k, p).first;
} }
return i.value(); return i->second;
} }
QPixmap Image::pixNoCache( QPixmap Image::pixNoCache(
Data::FileOrigin origin,
int w, int w,
int h, int h,
Options options, Options options,
int outerw, int outerw,
int outerh, int outerh,
const style::color *colored) const { const style::color *colored) const {
checkSource();
if (_data.isNull()) { if (_data.isNull()) {
if (h <= 0 && height() > 0) { if (h <= 0 && height() > 0) {
h = qRound(width() * w / float64(height())); h = qRound(width() * w / float64(height()));
} }
return Empty()->pixNoCache(origin, w, h, options, outerw, outerh); return Empty()->pixNoCache(w, h, options, outerw, outerh);
} }
if (isNull() && outerw > 0 && outerh > 0) { if (isNull() && outerw > 0 && outerh > 0) {
@ -462,15 +433,12 @@ QPixmap Image::pixNoCache(
} }
QPixmap Image::pixColoredNoCache( QPixmap Image::pixColoredNoCache(
Data::FileOrigin origin,
style::color add, style::color add,
int32 w, int w,
int32 h, int h,
bool smooth) const { bool smooth) const {
checkSource();
if (_data.isNull()) { if (_data.isNull()) {
return Empty()->pix(origin); return Empty()->pix();
} }
auto img = _data; auto img = _data;
@ -484,14 +452,11 @@ QPixmap Image::pixColoredNoCache(
} }
QPixmap Image::pixBlurredColoredNoCache( QPixmap Image::pixBlurredColoredNoCache(
Data::FileOrigin origin,
style::color add, style::color add,
int32 w, int w,
int32 h) const { int h) const {
checkSource();
if (_data.isNull()) { if (_data.isNull()) {
return Empty()->pix(origin); return Empty()->pix();
} }
auto img = prepareBlur(_data); auto img = prepareBlur(_data);
@ -503,31 +468,3 @@ QPixmap Image::pixBlurredColoredNoCache(
return App::pixmapFromImageInPlace(prepareColored(add, img)); return App::pixmapFromImageInPlace(prepareColored(add, img));
} }
QImage Image::original() const {
checkSource();
return _data;
}
void Image::load() {
if (!loaded()) {
_source->load();
}
}
bool Image::loaded() const {
checkSource();
return !_data.isNull();
}
void Image::checkSource() const {
auto data = _source->takeLoaded();
if (_data.isNull() && !data.isNull()) {
invalidateSizeCache();
_data = std::move(data);
}
}
void Image::invalidateSizeCache() const {
_sizesCache.clear();
}

View File

@ -9,8 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/image/image_prepare.h" #include "ui/image/image_prepare.h"
class HistoryItem;
namespace Images { namespace Images {
[[nodiscard]] QByteArray ExpandInlineBytes(const QByteArray &bytes); [[nodiscard]] QByteArray ExpandInlineBytes(const QByteArray &bytes);
@ -19,125 +17,81 @@ namespace Images {
[[nodiscard]] QSize GetSizeForDocument( [[nodiscard]] QSize GetSizeForDocument(
const QVector<MTPDocumentAttribute> &attributes); const QVector<MTPDocumentAttribute> &attributes);
class Source {
public:
Source() = default;
Source(const Source &other) = delete;
Source(Source &&other) = delete;
Source &operator=(const Source &other) = delete;
Source &operator=(Source &&other) = delete;
virtual ~Source() = default;
virtual void load() = 0;
virtual QImage takeLoaded() = 0;
virtual int width() = 0;
virtual int height() = 0;
};
} // namespace Images } // namespace Images
class Image final { class Image final {
public: public:
explicit Image(std::unique_ptr<Images::Source> &&source); explicit Image(const QString &path);
explicit Image(const QByteArray &content);
explicit Image(QImage &&data);
static not_null<Image*> Empty(); // 1x1 transparent [[nodiscard]] static not_null<Image*> Empty(); // 1x1 transparent
static not_null<Image*> BlankMedia(); // 1x1 black [[nodiscard]] static not_null<Image*> BlankMedia(); // 1x1 black
QImage original() const; [[nodiscard]] int width() const {
return _data.width();
}
[[nodiscard]] int height() const {
return _data.height();
}
[[nodiscard]] QSize size() const {
return { width(), height() };
}
const QPixmap &pix( [[nodiscard]] bool isNull() const {
Data::FileOrigin origin, return (this == Empty());
int32 w = 0, }
int32 h = 0) const;
const QPixmap &pixRounded( [[nodiscard]] QImage original() const;
Data::FileOrigin origin,
int32 w = 0, [[nodiscard]] const QPixmap &pix(int w = 0, int h = 0) const;
int32 h = 0, [[nodiscard]] const QPixmap &pixRounded(
int w = 0,
int h = 0,
ImageRoundRadius radius = ImageRoundRadius::None, ImageRoundRadius radius = ImageRoundRadius::None,
RectParts corners = RectPart::AllCorners) const; RectParts corners = RectPart::AllCorners) const;
const QPixmap &pixBlurred( [[nodiscard]] const QPixmap &pixBlurred(int w = 0, int h = 0) const;
Data::FileOrigin origin, [[nodiscard]] const QPixmap &pixColored(style::color add, int w = 0, int h = 0) const;
int32 w = 0, [[nodiscard]] const QPixmap &pixBlurredColored(
int32 h = 0) const;
const QPixmap &pixColored(
Data::FileOrigin origin,
style::color add, style::color add,
int32 w = 0, int w = 0,
int32 h = 0) const; int h = 0) const;
const QPixmap &pixBlurredColored( [[nodiscard]] const QPixmap &pixSingle(
Data::FileOrigin origin, int w,
style::color add, int h,
int32 w = 0, int outerw,
int32 h = 0) const; int outerh,
const QPixmap &pixSingle(
Data::FileOrigin origin,
int32 w,
int32 h,
int32 outerw,
int32 outerh,
ImageRoundRadius radius, ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners, RectParts corners = RectPart::AllCorners,
const style::color *colored = nullptr) const; const style::color *colored = nullptr) const;
const QPixmap &pixBlurredSingle( [[nodiscard]] const QPixmap &pixBlurredSingle(
Data::FileOrigin origin, int w,
int32 w, int h,
int32 h, int outerw,
int32 outerw, int outerh,
int32 outerh,
ImageRoundRadius radius, ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners) const; RectParts corners = RectPart::AllCorners) const;
const QPixmap &pixCircled( [[nodiscard]] const QPixmap &pixCircled(int w = 0, int h = 0) const;
Data::FileOrigin origin, [[nodiscard]] const QPixmap &pixBlurredCircled(int w = 0, int h = 0) const;
int32 w = 0, [[nodiscard]] QPixmap pixNoCache(
int32 h = 0) const;
const QPixmap &pixBlurredCircled(
Data::FileOrigin origin,
int32 w = 0,
int32 h = 0) const;
QPixmap pixNoCache(
Data::FileOrigin origin,
int w = 0, int w = 0,
int h = 0, int h = 0,
Images::Options options = 0, Images::Options options = 0,
int outerw = -1, int outerw = -1,
int outerh = -1, int outerh = -1,
const style::color *colored = nullptr) const; const style::color *colored = nullptr) const;
QPixmap pixColoredNoCache( [[nodiscard]] QPixmap pixColoredNoCache(
Data::FileOrigin origin,
style::color add, style::color add,
int32 w = 0, int w = 0,
int32 h = 0, int h = 0,
bool smooth = false) const; bool smooth = false) const;
QPixmap pixBlurredColoredNoCache( [[nodiscard]] QPixmap pixBlurredColoredNoCache(
Data::FileOrigin origin,
style::color add, style::color add,
int32 w, int w,
int32 h = 0) const; int h = 0) const;
int width() const {
return _source->width();
}
int height() const {
return _source->height();
}
QSize size() const {
return { width(), height() };
}
void load();
bool loaded() const;
bool isNull() const;
~Image();
private: private:
void checkSource() const; const QImage _data;
void invalidateSizeCache() const; mutable base::flat_map<uint64, QPixmap> _cache;
std::unique_ptr<Images::Source> _source;
mutable QMap<uint64, QPixmap> _sizesCache;
mutable QImage _data;
}; };

View File

@ -1,31 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/image/image.h"
namespace Images {
class ImageSource : public Source {
public:
explicit ImageSource(const QString &path);
explicit ImageSource(const QByteArray &content);
explicit ImageSource(QImage &&data);
void load() override;
QImage takeLoaded() override;
int width() override;
int height() override;
private:
QImage _data;
};
} // namespace Images

View File

@ -24,11 +24,26 @@ constexpr int kNotifyDeletePhotoAfterMs = 60000;
CachedUserpics::CachedUserpics(Type type) CachedUserpics::CachedUserpics(Type type)
: _type(type) : _type(type)
, _clearTimer([=] { onClear(); }) { , _clearTimer([=] { clear(); }) {
QDir().mkpath(cWorkingDir() + qsl("tdata/temp")); QDir().mkpath(cWorkingDir() + qsl("tdata/temp"));
} }
QString CachedUserpics::get(const InMemoryKey &key, PeerData *peer) { CachedUserpics::~CachedUserpics() {
if (_someSavedFlag) {
crl::time result = 0;
for (const auto &item : std::as_const(_images)) {
QFile(item.path).remove();
}
// This works about 1200ms on Windows for a folder with one image O_o
// psDeleteDir(cWorkingDir() + qsl("tdata/temp"));
}
}
QString CachedUserpics::get(
const InMemoryKey &key,
not_null<PeerData*> peer,
std::shared_ptr<Data::CloudImageView> &view) {
auto ms = crl::now(); auto ms = crl::now();
auto i = _images.find(key); auto i = _images.find(key);
if (i != _images.cend()) { if (i != _images.cend()) {
@ -46,16 +61,15 @@ QString CachedUserpics::get(const InMemoryKey &key, PeerData *peer) {
} }
v.path = cWorkingDir() + qsl("tdata/temp/") + QString::number(rand_value<uint64>(), 16) + qsl(".png"); v.path = cWorkingDir() + qsl("tdata/temp/") + QString::number(rand_value<uint64>(), 16) + qsl(".png");
if (key.first || key.second) { if (key.first || key.second) {
auto userpic = std::shared_ptr<Data::CloudImageView>(); // #TODO optimize userpic
if (peer->isSelf()) { if (peer->isSelf()) {
const auto method = (_type == Type::Rounded) const auto method = (_type == Type::Rounded)
? Ui::EmptyUserpic::GenerateSavedMessagesRounded ? Ui::EmptyUserpic::GenerateSavedMessagesRounded
: Ui::EmptyUserpic::GenerateSavedMessages; : Ui::EmptyUserpic::GenerateSavedMessages;
method(st::notifyMacPhotoSize).save(v.path, "PNG"); method(st::notifyMacPhotoSize).save(v.path, "PNG");
} else if (_type == Type::Rounded) { } else if (_type == Type::Rounded) {
peer->saveUserpicRounded(userpic, v.path, st::notifyMacPhotoSize); peer->saveUserpicRounded(view, v.path, st::notifyMacPhotoSize);
} else { } else {
peer->saveUserpic(userpic, v.path, st::notifyMacPhotoSize); peer->saveUserpic(view, v.path, st::notifyMacPhotoSize);
} }
} else { } else {
Core::App().logoNoMargin().save(v.path, "PNG"); Core::App().logoNoMargin().save(v.path, "PNG");
@ -98,7 +112,7 @@ void CachedUserpics::clearInMs(int ms) {
_clearTimer.callOnce(ms); _clearTimer.callOnce(ms);
} }
void CachedUserpics::onClear() { void CachedUserpics::clear() {
auto ms = crl::now(); auto ms = crl::now();
auto minuntil = clear(ms); auto minuntil = clear(ms);
if (minuntil) { if (minuntil) {
@ -106,17 +120,5 @@ void CachedUserpics::onClear() {
} }
} }
CachedUserpics::~CachedUserpics() {
if (_someSavedFlag) {
crl::time result = 0;
for (const auto &item : std::as_const(_images)) {
QFile(item.path).remove();
}
// This works about 1200ms on Windows for a folder with one image O_o
// psDeleteDir(cWorkingDir() + qsl("tdata/temp"));
}
}
} // namespace Notifications } // namespace Notifications
} // namespace Window } // namespace Window

View File

@ -10,27 +10,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/notifications_manager.h" #include "window/notifications_manager.h"
#include "base/timer.h" #include "base/timer.h"
namespace Data {
class CloudImageView;
} // namespace Data
namespace Window { namespace Window {
namespace Notifications { namespace Notifications {
class CachedUserpics : public QObject { class CachedUserpics : public QObject {
Q_OBJECT
public: public:
enum class Type { enum class Type {
Rounded, Rounded,
Circled, Circled,
}; };
CachedUserpics(Type type); CachedUserpics(Type type);
QString get(const InMemoryKey &key, PeerData *peer);
~CachedUserpics(); ~CachedUserpics();
private slots: [[nodiscard]] QString get(
void onClear(); const InMemoryKey &key,
not_null<PeerData*> peer,
std::shared_ptr<Data::CloudImageView> &view);
private: private:
void clear();
void clearInMs(int ms); void clearInMs(int ms);
crl::time clear(crl::time ms); crl::time clear(crl::time ms);

View File

@ -265,13 +265,13 @@ QPixmap MediaPreviewWidget::currentImage() const {
return QPixmap(); return QPixmap();
} else if (const auto image = _documentMedia->getStickerLarge()) { } else if (const auto image = _documentMedia->getStickerLarge()) {
QSize s = currentDimensions(); QSize s = currentDimensions();
_cache = image->pix(_origin, s.width(), s.height()); _cache = image->pix(s.width(), s.height());
_cacheStatus = CacheLoaded; _cacheStatus = CacheLoaded;
} else if (_cacheStatus != CacheThumbLoaded } else if (_cacheStatus != CacheThumbLoaded
&& _document->hasThumbnail() && _document->hasThumbnail()
&& _documentMedia->thumbnail()) { && _documentMedia->thumbnail()) {
QSize s = currentDimensions(); QSize s = currentDimensions();
_cache = _documentMedia->thumbnail()->pixBlurred(_origin, s.width(), s.height()); _cache = _documentMedia->thumbnail()->pixBlurred(s.width(), s.height());
_cacheStatus = CacheThumbLoaded; _cacheStatus = CacheThumbLoaded;
} }
} }
@ -290,10 +290,10 @@ QPixmap MediaPreviewWidget::currentImage() const {
QSize s = currentDimensions(); QSize s = currentDimensions();
const auto thumbnail = _documentMedia->thumbnail(); const auto thumbnail = _documentMedia->thumbnail();
if (thumbnail) { if (thumbnail) {
_cache = thumbnail->pixBlurred(_origin, s.width(), s.height()); _cache = thumbnail->pixBlurred(s.width(), s.height());
_cacheStatus = CacheThumbLoaded; _cacheStatus = CacheThumbLoaded;
} else if (const auto blurred = _documentMedia->thumbnailInline()) { } else if (const auto blurred = _documentMedia->thumbnailInline()) {
_cache = blurred->pixBlurred(_origin, s.width(), s.height()); _cache = blurred->pixBlurred(s.width(), s.height());
_cacheStatus = CacheThumbLoaded; _cacheStatus = CacheThumbLoaded;
} }
} }
@ -302,7 +302,7 @@ QPixmap MediaPreviewWidget::currentImage() const {
if (_cacheStatus != CacheLoaded) { if (_cacheStatus != CacheLoaded) {
if (_photoMedia->loaded()) { if (_photoMedia->loaded()) {
QSize s = currentDimensions(); QSize s = currentDimensions();
_cache = _photoMedia->image(Data::PhotoSize::Large)->pix(_origin, s.width(), s.height()); _cache = _photoMedia->image(Data::PhotoSize::Large)->pix(s.width(), s.height());
_cacheStatus = CacheLoaded; _cacheStatus = CacheLoaded;
} else { } else {
_photo->load(_origin); _photo->load(_origin);
@ -310,14 +310,14 @@ QPixmap MediaPreviewWidget::currentImage() const {
QSize s = currentDimensions(); QSize s = currentDimensions();
if (const auto thumbnail = _photoMedia->image( if (const auto thumbnail = _photoMedia->image(
Data::PhotoSize::Thumbnail)) { Data::PhotoSize::Thumbnail)) {
_cache = thumbnail->pixBlurred(_origin, s.width(), s.height()); _cache = thumbnail->pixBlurred(s.width(), s.height());
_cacheStatus = CacheThumbLoaded; _cacheStatus = CacheThumbLoaded;
} else if (const auto small = _photoMedia->image( } else if (const auto small = _photoMedia->image(
Data::PhotoSize::Small)) { Data::PhotoSize::Small)) {
_cache = small->pixBlurred(_origin, s.width(), s.height()); _cache = small->pixBlurred(s.width(), s.height());
_cacheStatus = CacheThumbLoaded; _cacheStatus = CacheThumbLoaded;
} else if (const auto blurred = _photoMedia->thumbnailInline()) { } else if (const auto blurred = _photoMedia->thumbnailInline()) {
_cache = blurred->pixBlurred(_origin, s.width(), s.height()); _cache = blurred->pixBlurred(s.width(), s.height());
_cacheStatus = CacheThumbLoaded; _cacheStatus = CacheThumbLoaded;
} else { } else {
_photoMedia->wanted(Data::PhotoSize::Small, _origin); _photoMedia->wanted(Data::PhotoSize::Small, _origin);