mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-01-02 12:42:16 +00:00
Remove legacy image-related code.
This commit is contained in:
parent
f066e0f05a
commit
6513422e40
@ -331,7 +331,6 @@ PRIVATE
|
||||
core/launcher.h
|
||||
core/local_url_handlers.cpp
|
||||
core/local_url_handlers.h
|
||||
core/media_active_cache.h
|
||||
core/mime_type.cpp
|
||||
core/mime_type.h
|
||||
core/sandbox.cpp
|
||||
|
@ -227,8 +227,6 @@ namespace App {
|
||||
clearCorners();
|
||||
|
||||
Data::clearGlobalStructures();
|
||||
|
||||
Images::ClearAll();
|
||||
}
|
||||
|
||||
void hoveredItem(HistoryView::Element *item) {
|
||||
|
@ -266,10 +266,8 @@ void BackgroundBox::Inner::resizeToContentAndPreload() {
|
||||
|
||||
const auto preload = kBackgroundsInRow * 3;
|
||||
for (const auto &paper : _papers | ranges::view::take(preload)) {
|
||||
if (paper.data.localThumbnail()) {
|
||||
paper.data.loadLocalThumbnail();
|
||||
} else if (const auto document = paper.data.document()) {
|
||||
if (!paper.dataMedia) {
|
||||
if (!paper.data.localThumbnail() && !paper.dataMedia) {
|
||||
if (const auto document = paper.data.document()) {
|
||||
paper.dataMedia = document->createMediaView();
|
||||
paper.dataMedia->thumbnailWanted(paper.data.fileOrigin());
|
||||
}
|
||||
@ -323,9 +321,6 @@ void BackgroundBox::Inner::validatePaperThumbnail(
|
||||
if (!paper.dataMedia || !paper.dataMedia->thumbnail()) {
|
||||
return;
|
||||
}
|
||||
} else if (!localThumbnail->loaded()) {
|
||||
localThumbnail->load(paper.data.fileOrigin());
|
||||
return;
|
||||
}
|
||||
const auto thumbnail = localThumbnail
|
||||
? localThumbnail
|
||||
|
@ -434,7 +434,6 @@ void BackgroundPreviewBox::prepare() {
|
||||
}
|
||||
updateServiceBg(_paper.backgroundColor());
|
||||
|
||||
_paper.loadLocalThumbnail();
|
||||
_paper.loadDocument();
|
||||
const auto document = _paper.document();
|
||||
if (document && document->loading()) {
|
||||
|
@ -12,6 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "mtproto/mtproto_rpc_sender.h"
|
||||
|
||||
class Image;
|
||||
|
||||
namespace ChatHelpers {
|
||||
class TabbedPanel;
|
||||
} // namespace ChatHelpers
|
||||
|
@ -14,6 +14,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
class Image;
|
||||
|
||||
namespace Data {
|
||||
class PhotoMedia;
|
||||
class CloudImageView;
|
||||
|
@ -452,25 +452,13 @@ void GifsListWidget::processPanelHideFinished() {
|
||||
}
|
||||
|
||||
void GifsListWidget::clearHeavyData() {
|
||||
const auto itemForget = [](const auto &item) {
|
||||
if (const auto document = item->getDocument()) {
|
||||
document->unload();
|
||||
}
|
||||
if (const auto photo = item->getPhoto()) {
|
||||
photo->unload();
|
||||
}
|
||||
if (const auto result = item->getResult()) {
|
||||
result->unload();
|
||||
}
|
||||
item->unloadHeavyPart();
|
||||
};
|
||||
// Preserve panel state through visibility toggles.
|
||||
//clearInlineRows(false);
|
||||
for (const auto &[document, layout] : _gifLayouts) {
|
||||
itemForget(layout);
|
||||
layout->unloadHeavyPart();
|
||||
}
|
||||
for (const auto &[document, layout] : _inlineLayouts) {
|
||||
itemForget(layout);
|
||||
layout->unloadHeavyPart();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,31 +123,11 @@ public:
|
||||
EmojiPtr emoji,
|
||||
not_null<crl::object_on_queue<EmojiImageLoader>*> loader);
|
||||
|
||||
void load(Data::FileOrigin origin) override;
|
||||
void loadEvenCancelled(Data::FileOrigin origin) override;
|
||||
void load() override;
|
||||
QImage takeLoaded() override;
|
||||
void unload() override;
|
||||
|
||||
bool loading() override;
|
||||
bool displayLoading() override;
|
||||
void cancel() override;
|
||||
float64 progress() override;
|
||||
int loadOffset() override;
|
||||
|
||||
const StorageImageLocation &location() override;
|
||||
void refreshFileReference(const QByteArray &data) override;
|
||||
Storage::Cache::Key cacheKey() override;
|
||||
void setDelayedStorageLocation(
|
||||
const StorageImageLocation &location) override;
|
||||
void performDelayedLoad(Data::FileOrigin origin) override;
|
||||
void setImageBytes(const QByteArray &bytes) override;
|
||||
|
||||
int width() override;
|
||||
int height() override;
|
||||
int bytesSize() override;
|
||||
void setInformation(int size, int width, int height) override;
|
||||
|
||||
QByteArray bytesForCache() override;
|
||||
|
||||
private:
|
||||
// While HistoryView::Element-s are almost never destroyed
|
||||
@ -155,8 +135,6 @@ private:
|
||||
not_null<crl::object_on_queue<EmojiImageLoader>*> _loader;
|
||||
EmojiPtr _emoji = nullptr;
|
||||
QImage _data;
|
||||
QByteArray _format;
|
||||
QByteArray _bytes;
|
||||
QSize _size;
|
||||
base::binary_guard _loading;
|
||||
|
||||
@ -170,92 +148,29 @@ ImageSource::ImageSource(
|
||||
, _size(SingleSize()) {
|
||||
}
|
||||
|
||||
void ImageSource::load(Data::FileOrigin origin) {
|
||||
if (!_data.isNull()) {
|
||||
void ImageSource::load() {
|
||||
if (!_data.isNull() || _loading) {
|
||||
return;
|
||||
}
|
||||
if (_bytes.isEmpty()) {
|
||||
_loader->with([
|
||||
this,
|
||||
emoji = _emoji,
|
||||
guard = _loading.make_guard()
|
||||
](EmojiImageLoader &loader) mutable {
|
||||
if (!guard) {
|
||||
return;
|
||||
}
|
||||
crl::on_main(std::move(guard), [this, image = loader.prepare(emoji)]{
|
||||
_data = image;
|
||||
Auth().downloaderTaskFinished().notify();
|
||||
});
|
||||
_loader->with([
|
||||
this,
|
||||
emoji = _emoji,
|
||||
guard = _loading.make_guard()
|
||||
](EmojiImageLoader &loader) mutable {
|
||||
if (!guard) {
|
||||
return;
|
||||
}
|
||||
crl::on_main(std::move(guard), [this, image = loader.prepare(emoji)]{
|
||||
_data = image;
|
||||
Auth().downloaderTaskFinished().notify();
|
||||
});
|
||||
} else {
|
||||
_data = App::readImage(_bytes, &_format, false);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageSource::loadEvenCancelled(Data::FileOrigin origin) {
|
||||
load(origin);
|
||||
});
|
||||
}
|
||||
|
||||
QImage ImageSource::takeLoaded() {
|
||||
load({});
|
||||
return _data;
|
||||
}
|
||||
|
||||
void ImageSource::unload() {
|
||||
if (_bytes.isEmpty() && !_data.isNull()) {
|
||||
if (_format != "JPG") {
|
||||
_format = "PNG";
|
||||
}
|
||||
{
|
||||
QBuffer buffer(&_bytes);
|
||||
_data.save(&buffer, _format);
|
||||
}
|
||||
Assert(!_bytes.isEmpty());
|
||||
}
|
||||
_data = QImage();
|
||||
}
|
||||
|
||||
bool ImageSource::loading() {
|
||||
return _data.isNull() && _bytes.isEmpty();
|
||||
}
|
||||
|
||||
bool ImageSource::displayLoading() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ImageSource::cancel() {
|
||||
}
|
||||
|
||||
float64 ImageSource::progress() {
|
||||
return 1.;
|
||||
}
|
||||
|
||||
int ImageSource::loadOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const StorageImageLocation &ImageSource::location() {
|
||||
return StorageImageLocation::Invalid();
|
||||
}
|
||||
|
||||
void ImageSource::refreshFileReference(const QByteArray &data) {
|
||||
}
|
||||
|
||||
Storage::Cache::Key ImageSource::cacheKey() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void ImageSource::setDelayedStorageLocation(
|
||||
const StorageImageLocation &location) {
|
||||
}
|
||||
|
||||
void ImageSource::performDelayedLoad(Data::FileOrigin origin) {
|
||||
}
|
||||
|
||||
void ImageSource::setImageBytes(const QByteArray &bytes) {
|
||||
}
|
||||
|
||||
int ImageSource::width() {
|
||||
return _size.width();
|
||||
}
|
||||
@ -264,29 +179,6 @@ int ImageSource::height() {
|
||||
return _size.height();
|
||||
}
|
||||
|
||||
int ImageSource::bytesSize() {
|
||||
return _bytes.size();
|
||||
}
|
||||
|
||||
void ImageSource::setInformation(int size, int width, int height) {
|
||||
if (width && height) {
|
||||
_size = QSize(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray ImageSource::bytesForCache() {
|
||||
auto result = QByteArray();
|
||||
{
|
||||
QBuffer buffer(&result);
|
||||
if (!_data.save(&buffer, _format)) {
|
||||
if (_data.save(&buffer, "PNG")) {
|
||||
_format = "PNG";
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EmojiImageLoader::EmojiImageLoader(
|
||||
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include <crl/crl_object_on_queue.h>
|
||||
|
||||
class Image;
|
||||
class HistoryItem;
|
||||
class DocumentData;
|
||||
|
||||
|
@ -31,7 +31,7 @@ void SetThumbnailView::set(
|
||||
_content = std::move(content);
|
||||
} else {
|
||||
_image = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(std::move(image), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(std::move(image)));
|
||||
}
|
||||
session->downloaderTaskFinished().notify();
|
||||
}
|
||||
|
@ -1,83 +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 "base/last_used_cache.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
template <typename Type>
|
||||
class MediaActiveCache {
|
||||
public:
|
||||
template <typename Unload>
|
||||
MediaActiveCache(int64 limit, Unload &&unload);
|
||||
|
||||
void up(Type *entry);
|
||||
void remove(Type *entry);
|
||||
void clear();
|
||||
|
||||
void increment(int64 amount);
|
||||
void decrement(int64 amount);
|
||||
|
||||
private:
|
||||
template <typename Unload>
|
||||
void check(Unload &&unload);
|
||||
|
||||
base::last_used_cache<Type*> _cache;
|
||||
SingleQueuedInvokation _delayed;
|
||||
int64 _usage = 0;
|
||||
int64 _limit = 0;
|
||||
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
template <typename Unload>
|
||||
MediaActiveCache<Type>::MediaActiveCache(int64 limit, Unload &&unload)
|
||||
: _delayed([=] { check(unload); })
|
||||
, _limit(limit) {
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void MediaActiveCache<Type>::up(Type *entry) {
|
||||
_cache.up(entry);
|
||||
_delayed.call();
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void MediaActiveCache<Type>::remove(Type *entry) {
|
||||
_cache.remove(entry);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void MediaActiveCache<Type>::clear() {
|
||||
_cache.clear();
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void MediaActiveCache<Type>::increment(int64 amount) {
|
||||
_usage += amount;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void MediaActiveCache<Type>::decrement(int64 amount) {
|
||||
_usage -= amount;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
template <typename Unload>
|
||||
void MediaActiveCache<Type>::check(Unload &&unload) {
|
||||
while (_usage > _limit) {
|
||||
if (const auto entry = _cache.take_lowest()) {
|
||||
unload(entry);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Core
|
@ -175,7 +175,6 @@ public:
|
||||
std::deque<not_null<UserData*>> lastAuthors;
|
||||
base::flat_set<not_null<PeerData*>> markupSenders;
|
||||
int botStatus = 0; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||
// ImagePtr photoFull;
|
||||
|
||||
private:
|
||||
Flags _flags;
|
||||
|
@ -22,7 +22,7 @@ void CloudImageView::set(
|
||||
not_null<Main::Session*> session,
|
||||
QImage image) {
|
||||
_image = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(std::move(image), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(std::move(image)));
|
||||
session->downloaderTaskFinished().notify();
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/image/image_location.h"
|
||||
|
||||
class FileLoader;
|
||||
class Image;
|
||||
|
||||
namespace Storage {
|
||||
namespace Cache {
|
||||
|
@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "main/main_session.h"
|
||||
#include "mainwidget.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "core/media_active_cache.h"
|
||||
#include "core/mime_type.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
#include "chat_helpers/stickers_set.h"
|
||||
@ -457,7 +456,6 @@ DocumentData::~DocumentData() {
|
||||
base::take(_thumbnail.loader).reset();
|
||||
base::take(_videoThumbnail.loader).reset();
|
||||
destroyLoader();
|
||||
unload();
|
||||
}
|
||||
|
||||
Data::Session &DocumentData::owner() const {
|
||||
@ -803,10 +801,6 @@ bool DocumentData::saveToCache() const {
|
||||
|| isTheme());
|
||||
}
|
||||
|
||||
void DocumentData::unload() {
|
||||
_replyPreview = nullptr;
|
||||
}
|
||||
|
||||
void DocumentData::automaticLoadSettingsChanged() {
|
||||
if (!cancelled() || status != FileReady) {
|
||||
return;
|
||||
|
@ -125,7 +125,6 @@ public:
|
||||
|
||||
[[nodiscard]] bool saveToCache() const;
|
||||
|
||||
void unload();
|
||||
[[nodiscard]] Image *getReplyPreview(Data::FileOrigin origin);
|
||||
|
||||
[[nodiscard]] StickerData *sticker() const;
|
||||
|
@ -166,7 +166,7 @@ void DocumentMedia::setGoodThumbnail(QImage thumbnail) {
|
||||
return;
|
||||
}
|
||||
_goodThumbnail = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(std::move(thumbnail), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(std::move(thumbnail)));
|
||||
_owner->session().downloaderTaskFinished().notify();
|
||||
}
|
||||
|
||||
@ -175,9 +175,7 @@ Image *DocumentMedia::thumbnailInline() const {
|
||||
auto image = Images::FromInlineBytes(_owner->inlineThumbnailBytes());
|
||||
if (!image.isNull()) {
|
||||
_inlineThumbnail = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(
|
||||
std::move(image),
|
||||
"PNG"));
|
||||
std::make_unique<Images::ImageSource>(std::move(image)));
|
||||
}
|
||||
}
|
||||
return _inlineThumbnail.get();
|
||||
@ -203,7 +201,7 @@ QSize DocumentMedia::thumbnailSize() const {
|
||||
|
||||
void DocumentMedia::setThumbnail(QImage thumbnail) {
|
||||
_thumbnail = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(std::move(thumbnail), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(std::move(thumbnail)));
|
||||
_owner->session().downloaderTaskFinished().notify();
|
||||
}
|
||||
|
||||
@ -243,18 +241,12 @@ void DocumentMedia::checkStickerLarge() {
|
||||
const auto &loc = _owner->location(true);
|
||||
if (loc.accessEnable()) {
|
||||
_sticker = std::make_unique<Image>(
|
||||
std::make_unique<Images::LocalFileSource>(loc.name()));
|
||||
std::make_unique<Images::ImageSource>(loc.name()));
|
||||
loc.accessDisable();
|
||||
}
|
||||
} else {
|
||||
auto format = QByteArray();
|
||||
auto image = App::readImage(_bytes, &format, false);
|
||||
_sticker = std::make_unique<Image>(
|
||||
std::make_unique<Images::LocalFileSource>(
|
||||
QString(),
|
||||
_bytes,
|
||||
format,
|
||||
std::move(image)));
|
||||
std::make_unique<Images::ImageSource>(_bytes));
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,19 +289,19 @@ void DocumentMedia::automaticLoad(
|
||||
void DocumentMedia::collectLocalData(not_null<DocumentMedia*> local) {
|
||||
if (const auto image = local->_goodThumbnail.get()) {
|
||||
_goodThumbnail = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(image->original(), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(image->original()));
|
||||
}
|
||||
if (const auto image = local->_inlineThumbnail.get()) {
|
||||
_inlineThumbnail = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(image->original(), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(image->original()));
|
||||
}
|
||||
if (const auto image = local->_thumbnail.get()) {
|
||||
_thumbnail = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(image->original(), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(image->original()));
|
||||
}
|
||||
if (const auto image = local->_sticker.get()) {
|
||||
_sticker = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(image->original(), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(image->original()));
|
||||
}
|
||||
_bytes = local->_bytes;
|
||||
_videoThumbnailBytes = local->_videoThumbnailBytes;
|
||||
@ -380,14 +372,9 @@ Image *DocumentMedia::getStickerSmall() {
|
||||
void DocumentMedia::checkStickerLarge(not_null<FileLoader*> loader) {
|
||||
if (_owner->sticker()
|
||||
&& !_sticker
|
||||
&& !loader->imageData().isNull()
|
||||
&& !_bytes.isEmpty()) {
|
||||
&& !loader->imageData().isNull()) {
|
||||
_sticker = std::make_unique<Image>(
|
||||
std::make_unique<Images::LocalFileSource>(
|
||||
QString(),
|
||||
_bytes,
|
||||
loader->imageFormat(),
|
||||
loader->imageData()));
|
||||
std::make_unique<Images::ImageSource>(loader->imageData()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "base/flags.h"
|
||||
|
||||
class Image;
|
||||
class FileLoader;
|
||||
|
||||
namespace Media {
|
||||
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "data/data_location.h"
|
||||
|
||||
class Image;
|
||||
class HistoryItem;
|
||||
|
||||
namespace base {
|
||||
|
@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mainwindow.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/image/image_source.h"
|
||||
#include "ui/empty_userpic.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "history/history.h"
|
||||
@ -217,6 +218,13 @@ Image *PeerData::currentUserpic(
|
||||
const auto image = view ? view->image() : nullptr;
|
||||
if (image) {
|
||||
_userpicEmpty = nullptr;
|
||||
} else if (isNotificationsUser()) {
|
||||
static auto result = Image(
|
||||
std::make_unique<Images::ImageSource>(
|
||||
Core::App().logoNoMargin().scaledToWidth(
|
||||
kUserpicSize,
|
||||
Qt::SmoothTransformation)));
|
||||
return &result;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
@ -370,17 +378,6 @@ void PeerData::updateUserpic(
|
||||
}
|
||||
|
||||
void PeerData::clearUserpic() {
|
||||
//const auto photo = [&] { // #TODO optimize
|
||||
// if (isNotificationsUser()) {
|
||||
// auto image = Core::App().logoNoMargin().scaledToWidth(
|
||||
// kUserpicSize,
|
||||
// Qt::SmoothTransformation);
|
||||
// return _userpic
|
||||
// ? _userpic
|
||||
// : Images::Create(std::move(image), "PNG");
|
||||
// }
|
||||
// return ImagePtr();
|
||||
//}();
|
||||
setUserpicChecked(PhotoId(), ImageLocation());
|
||||
}
|
||||
|
||||
|
@ -169,10 +169,6 @@ bool PhotoData::uploading() const {
|
||||
return (uploadingData != nullptr);
|
||||
}
|
||||
|
||||
void PhotoData::unload() {
|
||||
_replyPreview = nullptr;
|
||||
}
|
||||
|
||||
Image *PhotoData::getReplyPreview(Data::FileOrigin origin) {
|
||||
if (!_replyPreview) {
|
||||
_replyPreview = std::make_unique<Data::ReplyPreview>(this);
|
||||
|
@ -59,7 +59,6 @@ public:
|
||||
void setWaitingForAlbum();
|
||||
[[nodiscard]] bool waitingForAlbum() const;
|
||||
|
||||
void unload();
|
||||
[[nodiscard]] Image *getReplyPreview(Data::FileOrigin origin);
|
||||
|
||||
void setRemoteLocation(
|
||||
|
@ -38,8 +38,7 @@ Image *PhotoMedia::thumbnailInline() const {
|
||||
if (!image.isNull()) {
|
||||
_inlineThumbnail = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(
|
||||
std::move(image),
|
||||
"PNG"));
|
||||
std::move(image)));
|
||||
}
|
||||
}
|
||||
return _inlineThumbnail.get();
|
||||
@ -79,7 +78,7 @@ void PhotoMedia::set(PhotoSize size, QImage image) {
|
||||
Qt::SmoothTransformation);
|
||||
}
|
||||
_images[index] = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(std::move(image), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(std::move(image)));
|
||||
_owner->session().downloaderTaskFinished().notify();
|
||||
}
|
||||
|
||||
@ -114,14 +113,12 @@ void PhotoMedia::automaticLoad(
|
||||
void PhotoMedia::collectLocalData(not_null<PhotoMedia*> local) {
|
||||
if (const auto image = local->_inlineThumbnail.get()) {
|
||||
_inlineThumbnail = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(image->original(), "PNG"));
|
||||
std::make_unique<Images::ImageSource>(image->original()));
|
||||
}
|
||||
for (auto i = 0; i != kPhotoSizeCount; ++i) {
|
||||
if (const auto image = local->_images[i].get()) {
|
||||
_images[i] = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(
|
||||
image->original(),
|
||||
"PNG"));
|
||||
std::make_unique<Images::ImageSource>(image->original()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ ReplyPreview::ReplyPreview(not_null<PhotoData*> photo)
|
||||
: _photo(photo) {
|
||||
}
|
||||
|
||||
ReplyPreview::~ReplyPreview() = default;
|
||||
|
||||
void ReplyPreview::prepare(not_null<Image*> image, Images::Options options) {
|
||||
if (image->isNull() || !image->loaded()) {
|
||||
return;
|
||||
@ -53,8 +55,7 @@ void ReplyPreview::prepare(not_null<Image*> image, Images::Options options) {
|
||||
outerSize);
|
||||
_image = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(
|
||||
bitmap.toImage(),
|
||||
"PNG"));
|
||||
bitmap.toImage()));
|
||||
_good = ((options & Images::Option::Blurred) == 0);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class Image;
|
||||
class DocumentData;
|
||||
class PhotoData;
|
||||
|
||||
@ -20,6 +21,7 @@ class ReplyPreview {
|
||||
public:
|
||||
explicit ReplyPreview(not_null<DocumentData*> document);
|
||||
explicit ReplyPreview(not_null<PhotoData*> photo);
|
||||
~ReplyPreview();
|
||||
|
||||
[[nodiscard]] Image *image(Data::FileOrigin origin);
|
||||
|
||||
|
@ -16,7 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "core/mime_type.h" // Core::IsMimeSticker
|
||||
#include "core/crash_reports.h" // CrashReports::SetAnnotation
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/image/image_source.h" // Images::LocalFileSource
|
||||
#include "ui/image/image_source.h" // Images::ImageSource
|
||||
#include "ui/image/image_location_factory.h" // Images::FromPhotoSize
|
||||
#include "export/export_controller.h"
|
||||
#include "export/view/export_view_panel_controller.h"
|
||||
@ -1080,7 +1080,6 @@ Session::~Session() {
|
||||
_session->notifications().clearAllFast();
|
||||
|
||||
clear();
|
||||
Images::ClearRemote();
|
||||
}
|
||||
|
||||
template <typename Method>
|
||||
@ -3823,10 +3822,8 @@ void Session::setWallpapers(const QVector<MTPWallPaper> &data, int32 hash) {
|
||||
|
||||
_wallpapers.push_back(Data::Legacy1DefaultWallPaper());
|
||||
_wallpapers.back().setLocalImageAsThumbnail(std::make_shared<Image>(
|
||||
std::make_unique<Images::LocalFileSource>(
|
||||
qsl(":/gui/art/bg_initial.jpg"),
|
||||
QByteArray(),
|
||||
"JPG")));
|
||||
std::make_unique<Images::ImageSource>(
|
||||
u":/gui/art/bg_initial.jpg"_q)));
|
||||
for (const auto &paper : data) {
|
||||
if (const auto parsed = Data::WallPaper::Create(paper)) {
|
||||
_wallpapers.push_back(*parsed);
|
||||
@ -3838,10 +3835,8 @@ void Session::setWallpapers(const QVector<MTPWallPaper> &data, int32 hash) {
|
||||
if (defaultFound == end(_wallpapers)) {
|
||||
_wallpapers.push_back(Data::DefaultWallPaper());
|
||||
_wallpapers.back().setLocalImageAsThumbnail(std::make_shared<Image>(
|
||||
std::make_unique<Images::LocalFileSource>(
|
||||
qsl(":/gui/arg/bg.jpg"),
|
||||
QByteArray(),
|
||||
"JPG")));
|
||||
std::make_unique<Images::ImageSource>(
|
||||
u":/gui/arg/bg.jpg"_q)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,12 +183,6 @@ QString WallPaper::shareUrl() const {
|
||||
: base + '?' + params.join('&');
|
||||
}
|
||||
|
||||
void WallPaper::loadLocalThumbnail() const {
|
||||
if (_thumbnail) {
|
||||
_thumbnail->load(fileOrigin());
|
||||
}
|
||||
}
|
||||
|
||||
void WallPaper::loadDocumentThumbnail() const {
|
||||
if (_document) {
|
||||
_document->loadThumbnail(fileOrigin());
|
||||
|
@ -34,7 +34,6 @@ public:
|
||||
[[nodiscard]] QString shareUrl() const;
|
||||
|
||||
void loadDocument() const;
|
||||
void loadLocalThumbnail() const;
|
||||
void loadDocumentThumbnail() const;
|
||||
[[nodiscard]] FileOrigin fileOrigin() const;
|
||||
|
||||
|
@ -6921,7 +6921,6 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
|
||||
|
||||
auto top = _topBar->bottomNoMargins();
|
||||
bool serviceColor = false, hasForward = readyToForward();
|
||||
ImagePtr preview;
|
||||
p.fillRect(myrtlrect(0, top, width(), st::historyReplyHeight), st::historyPinnedBg);
|
||||
|
||||
top += st::msgReplyPadding.top();
|
||||
|
@ -80,6 +80,10 @@ Contact::Contact(
|
||||
|
||||
Contact::~Contact() {
|
||||
history()->owner().unregisterContactView(_userId, _parent);
|
||||
if (_userpic) {
|
||||
_userpic = nullptr;
|
||||
_parent->checkHeavyPart();
|
||||
}
|
||||
}
|
||||
|
||||
void Contact::updateSharedContactUserId(UserId userId) {
|
||||
|
@ -421,13 +421,9 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
|
||||
}
|
||||
} else {
|
||||
ensureDataMediaCreated();
|
||||
const auto good = _dataMedia->goodThumbnail();
|
||||
if (good && good->loaded()) {
|
||||
if (const auto good = _dataMedia->goodThumbnail()) {
|
||||
p.drawPixmap(rthumb.topLeft(), good->pixSingle({}, _thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
|
||||
} else {
|
||||
if (good) {
|
||||
good->load({});
|
||||
}
|
||||
const auto normal = _dataMedia->thumbnail();
|
||||
if (normal) {
|
||||
if (normal->width() >= kUseNonBlurredThreshold
|
||||
@ -657,8 +653,7 @@ void Gif::validateVideoThumbnail() const {
|
||||
std::make_unique<Images::ImageSource>(
|
||||
(info.thumbnail.isNull()
|
||||
? Image::BlankMedia()->original()
|
||||
: info.thumbnail),
|
||||
"PNG"));
|
||||
: info.thumbnail)));
|
||||
}
|
||||
|
||||
void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const {
|
||||
@ -1179,23 +1174,18 @@ void Gif::validateGroupedCache(
|
||||
ensureDataMediaCreated();
|
||||
|
||||
const auto good = _dataMedia->goodThumbnail();
|
||||
const auto useGood = (good && good->loaded());
|
||||
const auto thumb = _dataMedia->thumbnail();
|
||||
const auto useThumb = (thumb != nullptr);
|
||||
const auto image = useGood
|
||||
const auto image = good
|
||||
? good
|
||||
: useThumb
|
||||
: thumb
|
||||
? thumb
|
||||
: _dataMedia->thumbnailInline();
|
||||
const auto blur = !useGood
|
||||
&& (!useThumb
|
||||
const auto blur = !good
|
||||
&& (!thumb
|
||||
|| (thumb->width() < kUseNonBlurredThreshold
|
||||
&& thumb->height() < kUseNonBlurredThreshold));
|
||||
if (good && !useGood) {
|
||||
good->load({});
|
||||
}
|
||||
|
||||
const auto loadLevel = useGood ? 3 : useThumb ? 2 : image ? 1 : 0;
|
||||
const auto loadLevel = good ? 3 : thumb ? 2 : image ? 1 : 0;
|
||||
const auto width = geometry.width();
|
||||
const auto height = geometry.height();
|
||||
const auto options = Option::Smooth
|
||||
@ -1312,6 +1302,7 @@ bool Gif::hasHeavyPart() const {
|
||||
void Gif::unloadHeavyPart() {
|
||||
stopAnimation();
|
||||
_dataMedia = nullptr;
|
||||
_videoThumbnailFrame = nullptr;
|
||||
}
|
||||
|
||||
void Gif::refreshParentId(not_null<HistoryItem*> realParent) {
|
||||
@ -1498,7 +1489,6 @@ void Gif::stopAnimation() {
|
||||
if (_streamed) {
|
||||
setStreamed(nullptr);
|
||||
history()->owner().requestViewResize(_parent);
|
||||
_data->unload();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/view/media/history_view_file.h"
|
||||
#include "media/streaming/media_streaming_common.h"
|
||||
|
||||
class Image;
|
||||
struct HistoryMessageVia;
|
||||
struct HistoryMessageReply;
|
||||
struct HistoryMessageForwarded;
|
||||
|
@ -72,7 +72,7 @@ void LargeEmoji::draw(Painter &p, const QRect &r, bool selected) {
|
||||
const auto o = Data::FileOrigin();
|
||||
const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
|
||||
for (const auto &image : images) {
|
||||
image->load(Data::FileOrigin());
|
||||
image->load();
|
||||
const auto w = image->width() / cIntRetinaFactor();
|
||||
if (image->loaded()) {
|
||||
const auto h = image->height() / cIntRetinaFactor();
|
||||
|
@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/view/media/history_view_media_unwrapped.h"
|
||||
#include "ui/text/text_isolated_emoji.h"
|
||||
|
||||
class Image;
|
||||
|
||||
namespace Data {
|
||||
struct FileOrigin;
|
||||
} // namespace Data
|
||||
|
@ -51,6 +51,13 @@ Location::Location(
|
||||
}
|
||||
}
|
||||
|
||||
Location::~Location() {
|
||||
if (_media) {
|
||||
_media = nullptr;
|
||||
_parent->checkHeavyPart();
|
||||
}
|
||||
}
|
||||
|
||||
void Location::ensureMediaCreated() const {
|
||||
if (_media) {
|
||||
return;
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
Data::LocationPoint point,
|
||||
const QString &title = QString(),
|
||||
const QString &description = QString());
|
||||
~Location();
|
||||
|
||||
void draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const override;
|
||||
TextState textState(QPoint point, StateRequest request) const override;
|
||||
|
@ -1523,6 +1523,10 @@ void Poll::toggleLinkRipple(bool pressed) {
|
||||
|
||||
Poll::~Poll() {
|
||||
history()->owner().unregisterPollView(_poll, _parent);
|
||||
if (hasHeavyPart()) {
|
||||
unloadHeavyPart();
|
||||
_parent->checkHeavyPart();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
@ -213,9 +213,6 @@ QPixmap Sticker::paintedPixmap(bool selected) const {
|
||||
const auto h = _size.height();
|
||||
const auto &c = st::msgStickerOverlay;
|
||||
const auto good = _dataMedia->goodThumbnail();
|
||||
if (good && !good->loaded()) {
|
||||
good->load({});
|
||||
}
|
||||
if (const auto image = _dataMedia->getStickerLarge()) {
|
||||
return selected
|
||||
? image->pixColored(o, c, w, h)
|
||||
@ -227,7 +224,7 @@ QPixmap Sticker::paintedPixmap(bool selected) const {
|
||||
// return selected
|
||||
// ? blurred->pixBlurredColored(o, c, w, h)
|
||||
// : blurred->pixBlurred(o, w, h);
|
||||
} else if (good && good->loaded()) {
|
||||
} else if (good) {
|
||||
return selected
|
||||
? good->pixColored(o, c, w, h)
|
||||
: good->pix(o, w, h);
|
||||
|
@ -207,14 +207,10 @@ void ThemeDocument::validateThumbnail() const {
|
||||
}
|
||||
ensureDataMediaCreated();
|
||||
if (const auto good = _dataMedia->goodThumbnail()) {
|
||||
if (good->loaded()) {
|
||||
prepareThumbnailFrom(good, 1);
|
||||
return;
|
||||
} else {
|
||||
good->load({});
|
||||
}
|
||||
prepareThumbnailFrom(good, 1);
|
||||
return;
|
||||
}
|
||||
if (_thumbnailGood >= 0 || !_dataMedia->thumbnail()) {
|
||||
if (_thumbnailGood >= 0) {
|
||||
return;
|
||||
}
|
||||
if (const auto normal = _dataMedia->thumbnail()) {
|
||||
|
@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "history/view/media/history_view_file.h"
|
||||
|
||||
class Image;
|
||||
|
||||
namespace Data {
|
||||
class DocumentMedia;
|
||||
} // namespace Data
|
||||
|
@ -315,9 +315,6 @@ void Gif::validateThumbnail(
|
||||
bool good) const {
|
||||
if (!image || (_thumbGood && !good)) {
|
||||
return;
|
||||
} else if (!image->loaded()) {
|
||||
image->load(fileOrigin());
|
||||
return;
|
||||
} else if ((_thumb.size() == size * cIntRetinaFactor())
|
||||
&& (_thumbGood || !good)) {
|
||||
return;
|
||||
@ -393,7 +390,6 @@ void Gif::radialAnimationCallback(crl::time now) const {
|
||||
|
||||
void Gif::unloadHeavyPart() {
|
||||
_gif.reset();
|
||||
getShownDocument()->unload();
|
||||
_dataMedia = nullptr;
|
||||
}
|
||||
|
||||
@ -404,7 +400,6 @@ void Gif::clipCallback(Media::Clip::Notification notification) {
|
||||
if (_gif) {
|
||||
if (_gif->state() == State::Error) {
|
||||
_gif.setBad();
|
||||
getShownDocument()->unload();
|
||||
} else if (_gif->ready() && !_gif->started()) {
|
||||
if (_gif->width() * _gif->height() > kMaxInlineArea) {
|
||||
getShownDocument()->dimensions = QSize(
|
||||
@ -608,7 +603,6 @@ TextState Photo::getState(
|
||||
}
|
||||
|
||||
void Photo::unloadHeavyPart() {
|
||||
getShownPhoto()->unload();
|
||||
_photoMedia = nullptr;
|
||||
}
|
||||
|
||||
@ -653,9 +647,6 @@ void Photo::validateThumbnail(
|
||||
bool good) const {
|
||||
if (!image || (_thumbGood && !good)) {
|
||||
return;
|
||||
} else if (!image->loaded()) {
|
||||
image->load(fileOrigin());
|
||||
return;
|
||||
} else if ((_thumb.size() == size * cIntRetinaFactor())
|
||||
&& (_thumbGood || !good)) {
|
||||
return;
|
||||
@ -802,28 +793,23 @@ void Video::prepareThumbnail(QSize size) const {
|
||||
if (!thumb) {
|
||||
return;
|
||||
}
|
||||
const auto origin = fileOrigin();
|
||||
if (thumb->loaded()) {
|
||||
if (_thumb.size() != size * cIntRetinaFactor()) {
|
||||
const auto width = size.width();
|
||||
const auto height = size.height();
|
||||
auto w = qMax(style::ConvertScale(thumb->width()), 1);
|
||||
auto h = qMax(style::ConvertScale(thumb->height()), 1);
|
||||
if (w * height > h * width) {
|
||||
if (height < h) {
|
||||
w = w * height / h;
|
||||
h = height;
|
||||
}
|
||||
} else {
|
||||
if (width < w) {
|
||||
h = h * width / w;
|
||||
w = width;
|
||||
}
|
||||
if (_thumb.size() != size * cIntRetinaFactor()) {
|
||||
const auto width = size.width();
|
||||
const auto height = size.height();
|
||||
auto w = qMax(style::ConvertScale(thumb->width()), 1);
|
||||
auto h = qMax(style::ConvertScale(thumb->height()), 1);
|
||||
if (w * height > h * width) {
|
||||
if (height < h) {
|
||||
w = w * height / h;
|
||||
h = height;
|
||||
}
|
||||
} else {
|
||||
if (width < w) {
|
||||
h = h * width / w;
|
||||
w = width;
|
||||
}
|
||||
_thumb = thumb->pixNoCache(origin, w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height);
|
||||
}
|
||||
} else {
|
||||
thumb->load(origin);
|
||||
_thumb = thumb->pixNoCache({}, w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1497,9 +1483,6 @@ void Game::ensureDataMediaCreated(not_null<PhotoData*> photo) const {
|
||||
void Game::validateThumbnail(Image *image, QSize size, bool good) const {
|
||||
if (!image || (_thumbGood && !good)) {
|
||||
return;
|
||||
} else if (!image->loaded()) {
|
||||
image->load(fileOrigin());
|
||||
return;
|
||||
} else if ((_thumb.size() == size * cIntRetinaFactor())
|
||||
&& (_thumbGood || !good)) {
|
||||
return;
|
||||
@ -1565,14 +1548,8 @@ void Game::radialAnimationCallback(crl::time now) const {
|
||||
|
||||
void Game::unloadHeavyPart() {
|
||||
_gif.reset();
|
||||
if (const auto document = getResultDocument()) {
|
||||
document->unload();
|
||||
_documentMedia = nullptr;
|
||||
}
|
||||
if (const auto photo = getResultPhoto()) {
|
||||
photo->unload();
|
||||
_photoMedia = nullptr;
|
||||
}
|
||||
_documentMedia = nullptr;
|
||||
_photoMedia = nullptr;
|
||||
}
|
||||
|
||||
void Game::clipCallback(Media::Clip::Notification notification) {
|
||||
@ -1582,7 +1559,6 @@ void Game::clipCallback(Media::Clip::Notification notification) {
|
||||
if (_gif) {
|
||||
if (_gif->state() == State::Error) {
|
||||
_gif.setBad();
|
||||
getResultDocument()->unload();
|
||||
} else if (_gif->ready() && !_gif->started()) {
|
||||
if (_gif->width() * _gif->height() > kMaxInlineArea) {
|
||||
getResultDocument()->dimensions = QSize(
|
||||
|
@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "layout.h"
|
||||
#include "ui/text/text.h"
|
||||
|
||||
class Image;
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
@ -329,15 +329,6 @@ bool Result::onChoose(Layout::ItemBase *layout) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Result::unload() {
|
||||
if (_document) {
|
||||
_document->unload();
|
||||
}
|
||||
if (_photo) {
|
||||
_photo->unload();
|
||||
}
|
||||
}
|
||||
|
||||
void Result::openFile() {
|
||||
if (_document) {
|
||||
DocumentOpenClickHandler(_document).onClick({});
|
||||
|
@ -52,7 +52,6 @@ public:
|
||||
// inline bot result. If it returns true you need to send this result.
|
||||
bool onChoose(Layout::ItemBase *layout);
|
||||
|
||||
void unload();
|
||||
void openFile();
|
||||
void cancelFile();
|
||||
|
||||
|
@ -297,21 +297,9 @@ void Inner::hideFinished() {
|
||||
}
|
||||
|
||||
void Inner::clearHeavyData() {
|
||||
const auto unload = [](const auto &item) {
|
||||
if (const auto document = item->getDocument()) {
|
||||
document->unload();
|
||||
}
|
||||
if (const auto photo = item->getPhoto()) {
|
||||
photo->unload();
|
||||
}
|
||||
if (const auto result = item->getResult()) {
|
||||
result->unload();
|
||||
}
|
||||
item->unloadHeavyPart();
|
||||
};
|
||||
clearInlineRows(false);
|
||||
for (const auto &[result, layout] : _inlineLayouts) {
|
||||
unload(layout);
|
||||
layout->unloadHeavyPart();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,7 +442,6 @@ void Account::loggedOut() {
|
||||
Local::reset();
|
||||
|
||||
cSetOtherOnline(0);
|
||||
Images::ClearRemote();
|
||||
}
|
||||
|
||||
void Account::destroyMtpKeys(MTP::AuthKeysList &&keys) {
|
||||
|
@ -1383,8 +1383,6 @@ float64 MainWidget::chatBackgroundProgress() const {
|
||||
return 1.;
|
||||
} else if (const auto document = _background->data.document()) {
|
||||
return _background->dataMedia->progress();
|
||||
} else if (const auto thumbnail = _background->data.localThumbnail()) {
|
||||
return thumbnail->progress();
|
||||
}
|
||||
}
|
||||
return 1.;
|
||||
|
@ -22,6 +22,7 @@ class HistoryWidget;
|
||||
class StackItem;
|
||||
struct FileLoadResult;
|
||||
class History;
|
||||
class Image;
|
||||
|
||||
namespace Api {
|
||||
struct SendAction;
|
||||
|
@ -241,10 +241,6 @@ void GroupThumbs::Thumb::validateImage() {
|
||||
if (!_full.isNull() || !_image) {
|
||||
return;
|
||||
}
|
||||
_image->load(_origin);
|
||||
if (!_image->loaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto pixSize = wantedPixSize();
|
||||
if (pixSize.width() > st::mediaviewGroupWidthMax) {
|
||||
|
@ -2214,15 +2214,10 @@ void OverlayWidget::initStreamingThumbnail() {
|
||||
Expects(_document != nullptr);
|
||||
|
||||
const auto good = _documentMedia->goodThumbnail();
|
||||
const auto useGood = (good && good->loaded());
|
||||
const auto useGood = (good != nullptr);
|
||||
const auto thumbnail = _documentMedia->thumbnail();
|
||||
const auto useThumb = (thumbnail != nullptr);
|
||||
const auto blurred = _documentMedia->thumbnailInline();
|
||||
if (good && !useGood) {
|
||||
good->load({});
|
||||
} else if (thumbnail) {
|
||||
thumbnail->load(fileOrigin());
|
||||
}
|
||||
const auto size = useGood ? good->size() : _document->dimensions;
|
||||
if (!useGood && !thumbnail && !blurred) {
|
||||
return;
|
||||
|
@ -1379,16 +1379,14 @@ QImage Pip::videoFrame(const FrameRequest &request) const {
|
||||
? nullptr
|
||||
: _data->createMediaView();
|
||||
const auto good = use ? use->goodThumbnail() : nullptr;
|
||||
const auto useGood = (good && good->loaded());
|
||||
const auto thumb = use ? use->thumbnail() : nullptr;
|
||||
const auto useThumb = (thumb && thumb->loaded());
|
||||
const auto blurred = use ? use->thumbnailInline() : nullptr;
|
||||
|
||||
const auto state = !cover.isNull()
|
||||
? ThumbState::Cover
|
||||
: useGood
|
||||
: good
|
||||
? ThumbState::Good
|
||||
: useThumb
|
||||
: thumb
|
||||
? ThumbState::Thumb
|
||||
: blurred
|
||||
? ThumbState::Inline
|
||||
@ -1406,14 +1404,9 @@ QImage Pip::videoFrame(const FrameRequest &request) const {
|
||||
request,
|
||||
std::move(_preparedCoverStorage));
|
||||
} else if (!request.resize.isEmpty()) {
|
||||
if (good && !useGood) {
|
||||
good->load({});
|
||||
} else if (thumb && !useThumb) {
|
||||
thumb->load(_contextId);
|
||||
}
|
||||
using Option = Images::Option;
|
||||
const auto options = Option::Smooth
|
||||
| (useGood ? Option(0) : Option::Blurred)
|
||||
| (good ? Option(0) : Option::Blurred)
|
||||
| Option::RoundedLarge
|
||||
| ((request.corners & RectPart::TopLeft)
|
||||
? Option::RoundedTopLeft
|
||||
@ -1427,9 +1420,9 @@ QImage Pip::videoFrame(const FrameRequest &request) const {
|
||||
| ((request.corners & RectPart::BottomLeft)
|
||||
? Option::RoundedBottomLeft
|
||||
: Option(0));
|
||||
_preparedCoverStorage = (useGood
|
||||
_preparedCoverStorage = (good
|
||||
? good
|
||||
: useThumb
|
||||
: thumb
|
||||
? thumb
|
||||
: blurred
|
||||
? blurred
|
||||
|
@ -358,8 +358,6 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||
}
|
||||
|
||||
void Photo::setPixFrom(not_null<Image*> image) {
|
||||
Expects(image->loaded());
|
||||
|
||||
const auto size = _width * cIntRetinaFactor();
|
||||
auto img = image->original();
|
||||
if (!_goodLoaded) {
|
||||
|
@ -13,6 +13,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "styles/style_overview.h"
|
||||
|
||||
class Image;
|
||||
|
||||
namespace style {
|
||||
struct RoundCheckbox;
|
||||
} // namespace style
|
||||
|
@ -630,9 +630,7 @@ void ChooseFromFile(
|
||||
}
|
||||
auto local = Data::CustomWallPaper();
|
||||
local.setLocalImageAsThumbnail(std::make_shared<Image>(
|
||||
std::make_unique<Images::ImageSource>(
|
||||
std::move(image),
|
||||
"JPG")));
|
||||
std::make_unique<Images::ImageSource>(std::move(image))));
|
||||
Ui::show(Box<BackgroundPreviewBox>(session, local));
|
||||
});
|
||||
FileDialog::GetOpenPath(
|
||||
|
@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/image/image.h"
|
||||
|
||||
#include "ui/image/image_source.h"
|
||||
#include "core/media_active_cache.h"
|
||||
#include "storage/cache/storage_cache_database.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
@ -21,31 +20,6 @@ using namespace Images;
|
||||
namespace Images {
|
||||
namespace {
|
||||
|
||||
// After 128 MB of unpacked images we try to clear some memory.
|
||||
constexpr auto kMemoryForCache = 128 * 1024 * 1024;
|
||||
|
||||
std::unordered_map<InMemoryKey, std::unique_ptr<Image>> StorageImages;
|
||||
std::unordered_map<InMemoryKey, std::unique_ptr<Image>> GeoPointImages;
|
||||
|
||||
int64 ComputeUsage(QSize size) {
|
||||
return int64(size.width()) * size.height() * 4;
|
||||
}
|
||||
|
||||
int64 ComputeUsage(const QPixmap &image) {
|
||||
return ComputeUsage(image.size());
|
||||
}
|
||||
|
||||
int64 ComputeUsage(const QImage &image) {
|
||||
return ComputeUsage(image.size());
|
||||
}
|
||||
|
||||
[[nodiscard]] Core::MediaActiveCache<const Image> &ActiveCache() {
|
||||
static auto Instance = Core::MediaActiveCache<const Image>(
|
||||
kMemoryForCache,
|
||||
[](const Image *image) { image->unload(); });
|
||||
return Instance;
|
||||
}
|
||||
|
||||
uint64 PixKey(int width, int height, Options options) {
|
||||
return static_cast<uint64>(width)
|
||||
| (static_cast<uint64>(height) << 24)
|
||||
@ -111,54 +85,6 @@ QImage FromInlineBytes(const QByteArray &bytes) {
|
||||
return App::readImage(ExpandInlineBytes(bytes));
|
||||
}
|
||||
|
||||
void ClearRemote() {
|
||||
base::take(StorageImages);
|
||||
base::take(GeoPointImages);
|
||||
}
|
||||
|
||||
void ClearAll() {
|
||||
ActiveCache().clear();
|
||||
ClearRemote();
|
||||
}
|
||||
|
||||
ImagePtr Create(QImage &&image, QByteArray format) {
|
||||
return ImagePtr(new Image(std::make_unique<ImageSource>(
|
||||
std::move(image),
|
||||
format)));
|
||||
}
|
||||
|
||||
template <typename SourceType>
|
||||
ImagePtr Create(
|
||||
const StorageImageLocation &location,
|
||||
int size,
|
||||
const QByteArray &bytes) {
|
||||
if (!location.valid()) {
|
||||
return ImagePtr();
|
||||
}
|
||||
const auto key = inMemoryKey(location);
|
||||
const auto i = StorageImages.find(key);
|
||||
const auto found = (i != end(StorageImages));
|
||||
const auto image = found
|
||||
? i->second.get()
|
||||
: StorageImages.emplace(
|
||||
key,
|
||||
std::make_unique<Image>(
|
||||
std::make_unique<SourceType>(location, size))
|
||||
).first->second.get();
|
||||
if (found) {
|
||||
image->refreshFileReference(location.fileReference());
|
||||
}
|
||||
if (!bytes.isEmpty()) {
|
||||
image->setImageBytes(bytes);
|
||||
}
|
||||
return ImagePtr(image);
|
||||
|
||||
}
|
||||
|
||||
ImagePtr Create(const StorageImageLocation &location, int size) {
|
||||
return Create<StorageSource>(location, size, QByteArray());
|
||||
}
|
||||
|
||||
QSize GetSizeForDocument(const QVector<MTPDocumentAttribute> &attributes) {
|
||||
for (const auto &attribute : attributes) {
|
||||
if (attribute.type() == mtpc_documentAttributeImageSize) {
|
||||
@ -169,33 +95,13 @@ QSize GetSizeForDocument(const QVector<MTPDocumentAttribute> &attributes) {
|
||||
return QSize();
|
||||
}
|
||||
|
||||
ImagePtr Create(const GeoPointLocation &location) {
|
||||
const auto key = inMemoryKey(location);
|
||||
const auto i = GeoPointImages.find(key);
|
||||
const auto image = (i != end(GeoPointImages))
|
||||
? i->second.get()
|
||||
: GeoPointImages.emplace(
|
||||
key,
|
||||
std::make_unique<Image>(
|
||||
std::make_unique<GeoPointSource>(location))
|
||||
).first->second.get();
|
||||
return ImagePtr(image);
|
||||
}
|
||||
|
||||
} // namespace Images
|
||||
|
||||
Image::Image(std::unique_ptr<Source> &&source)
|
||||
: _source(std::move(source)) {
|
||||
}
|
||||
|
||||
void Image::replaceSource(std::unique_ptr<Source> &&source) {
|
||||
const auto width = _source->width();
|
||||
const auto height = _source->height();
|
||||
if (width > 0 && height > 0) {
|
||||
source->setInformation(_source->bytesSize(), width, height);
|
||||
}
|
||||
_source = std::move(source);
|
||||
}
|
||||
Image::~Image() = default;
|
||||
|
||||
not_null<Image*> Image::Empty() {
|
||||
static auto result = [] {
|
||||
@ -206,7 +112,7 @@ not_null<Image*> Image::Empty() {
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
data.fill(Qt::transparent);
|
||||
data.setDevicePixelRatio(cRetinaFactor());
|
||||
return Image(std::make_unique<ImageSource>(std::move(data), "GIF"));
|
||||
return Image(std::make_unique<ImageSource>(std::move(data)));
|
||||
}();
|
||||
return &result;
|
||||
}
|
||||
@ -220,7 +126,7 @@ not_null<Image*> Image::BlankMedia() {
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
data.fill(Qt::black);
|
||||
data.setDevicePixelRatio(cRetinaFactor());
|
||||
return Image(std::make_unique<ImageSource>(std::move(data), "GIF"));
|
||||
return Image(std::make_unique<ImageSource>(std::move(data)));
|
||||
}();
|
||||
return &result;
|
||||
}
|
||||
@ -248,7 +154,6 @@ const QPixmap &Image::pix(
|
||||
auto p = pixNoCache(origin, w, h, options);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
ActiveCache().increment(ComputeUsage(*i));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
@ -287,7 +192,6 @@ const QPixmap &Image::pixRounded(
|
||||
auto p = pixNoCache(origin, w, h, options);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
ActiveCache().increment(ComputeUsage(*i));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
@ -311,7 +215,6 @@ const QPixmap &Image::pixCircled(
|
||||
auto p = pixNoCache(origin, w, h, options);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
ActiveCache().increment(ComputeUsage(*i));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
@ -335,7 +238,6 @@ const QPixmap &Image::pixBlurredCircled(
|
||||
auto p = pixNoCache(origin, w, h, options);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
ActiveCache().increment(ComputeUsage(*i));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
@ -359,7 +261,6 @@ const QPixmap &Image::pixBlurred(
|
||||
auto p = pixNoCache(origin, w, h, options);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
ActiveCache().increment(ComputeUsage(*i));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
@ -384,7 +285,6 @@ const QPixmap &Image::pixColored(
|
||||
auto p = pixColoredNoCache(origin, add, w, h, true);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
ActiveCache().increment(ComputeUsage(*i));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
@ -409,7 +309,6 @@ const QPixmap &Image::pixBlurredColored(
|
||||
auto p = pixBlurredColoredNoCache(origin, add, w, h);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
ActiveCache().increment(ComputeUsage(*i));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
@ -453,13 +352,9 @@ const QPixmap &Image::pixSingle(
|
||||
auto k = SinglePixKey(options);
|
||||
auto i = _sizesCache.constFind(k);
|
||||
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) {
|
||||
if (i != _sizesCache.cend()) {
|
||||
ActiveCache().decrement(ComputeUsage(*i));
|
||||
}
|
||||
auto p = pixNoCache(origin, w, h, options, outerw, outerh, colored);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
ActiveCache().increment(ComputeUsage(*i));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
@ -499,13 +394,9 @@ const QPixmap &Image::pixBlurredSingle(
|
||||
auto k = SinglePixKey(options);
|
||||
auto i = _sizesCache.constFind(k);
|
||||
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) {
|
||||
if (i != _sizesCache.cend()) {
|
||||
ActiveCache().decrement(ComputeUsage(*i));
|
||||
}
|
||||
auto p = pixNoCache(origin, w, h, options, outerw, outerh);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
ActiveCache().increment(ComputeUsage(*i));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
@ -518,9 +409,6 @@ QPixmap Image::pixNoCache(
|
||||
int outerw,
|
||||
int outerh,
|
||||
const style::color *colored) const {
|
||||
if (!loading()) {
|
||||
const_cast<Image*>(this)->load(origin);
|
||||
}
|
||||
checkSource();
|
||||
|
||||
if (_data.isNull()) {
|
||||
@ -579,9 +467,6 @@ QPixmap Image::pixColoredNoCache(
|
||||
int32 w,
|
||||
int32 h,
|
||||
bool smooth) const {
|
||||
if (!loading()) {
|
||||
const_cast<Image*>(this)->load(origin);
|
||||
}
|
||||
checkSource();
|
||||
|
||||
if (_data.isNull()) {
|
||||
@ -603,9 +488,6 @@ QPixmap Image::pixBlurredColoredNoCache(
|
||||
style::color add,
|
||||
int32 w,
|
||||
int32 h) const {
|
||||
if (!loading()) {
|
||||
const_cast<Image*>(this)->load(origin);
|
||||
}
|
||||
checkSource();
|
||||
|
||||
if (_data.isNull()) {
|
||||
@ -627,22 +509,12 @@ QImage Image::original() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
void Image::load(Data::FileOrigin origin) {
|
||||
void Image::load() {
|
||||
if (!loaded()) {
|
||||
_source->load(origin);
|
||||
_source->load();
|
||||
}
|
||||
}
|
||||
|
||||
void Image::loadEvenCancelled(Data::FileOrigin origin) {
|
||||
if (!loaded()) {
|
||||
_source->loadEvenCancelled(origin);
|
||||
}
|
||||
}
|
||||
|
||||
Storage::Cache::Key Image::cacheKey() const {
|
||||
return _source->cacheKey();
|
||||
}
|
||||
|
||||
bool Image::loaded() const {
|
||||
checkSource();
|
||||
return !_data.isNull();
|
||||
@ -653,46 +525,9 @@ void Image::checkSource() const {
|
||||
if (_data.isNull() && !data.isNull()) {
|
||||
invalidateSizeCache();
|
||||
_data = std::move(data);
|
||||
ActiveCache().increment(ComputeUsage(_data));
|
||||
}
|
||||
|
||||
ActiveCache().up(this);
|
||||
}
|
||||
|
||||
void Image::unload() const {
|
||||
_source->unload();
|
||||
invalidateSizeCache();
|
||||
ActiveCache().decrement(ComputeUsage(_data));
|
||||
_data = QImage();
|
||||
}
|
||||
|
||||
void Image::setDelayedStorageLocation(
|
||||
Data::FileOrigin origin,
|
||||
const StorageImageLocation &location) {
|
||||
_source->setDelayedStorageLocation(location);
|
||||
if (!loaded()) {
|
||||
_source->performDelayedLoad(origin);
|
||||
}
|
||||
}
|
||||
|
||||
void Image::setImageBytes(const QByteArray &bytes) {
|
||||
_source->setImageBytes(bytes);
|
||||
checkSource();
|
||||
}
|
||||
|
||||
void Image::invalidateSizeCache() const {
|
||||
auto &cache = ActiveCache();
|
||||
for (const auto &image : std::as_const(_sizesCache)) {
|
||||
cache.decrement(ComputeUsage(image));
|
||||
}
|
||||
_sizesCache.clear();
|
||||
}
|
||||
|
||||
Image::~Image() {
|
||||
if (this != Empty() && this != BlankMedia()) {
|
||||
invalidateSizeCache();
|
||||
ActiveCache().decrement(ComputeUsage(_data));
|
||||
_data = QImage();
|
||||
ActiveCache().remove(this);
|
||||
}
|
||||
}
|
||||
|
@ -16,16 +16,9 @@ namespace Images {
|
||||
[[nodiscard]] QByteArray ExpandInlineBytes(const QByteArray &bytes);
|
||||
[[nodiscard]] QImage FromInlineBytes(const QByteArray &bytes);
|
||||
|
||||
void ClearRemote();
|
||||
void ClearAll();
|
||||
|
||||
[[nodiscard]] QSize GetSizeForDocument(
|
||||
const QVector<MTPDocumentAttribute> &attributes);
|
||||
|
||||
ImagePtr Create(QImage &&data, QByteArray format);
|
||||
ImagePtr Create(const StorageImageLocation &location, int size = 0);
|
||||
ImagePtr Create(const GeoPointLocation &location);
|
||||
|
||||
class Source {
|
||||
public:
|
||||
Source() = default;
|
||||
@ -35,31 +28,11 @@ public:
|
||||
Source &operator=(Source &&other) = delete;
|
||||
virtual ~Source() = default;
|
||||
|
||||
virtual void load(Data::FileOrigin origin) = 0;
|
||||
virtual void loadEvenCancelled(Data::FileOrigin origin) = 0;
|
||||
virtual void load() = 0;
|
||||
virtual QImage takeLoaded() = 0;
|
||||
virtual void unload() = 0;
|
||||
|
||||
virtual bool loading() = 0;
|
||||
virtual bool displayLoading() = 0;
|
||||
virtual void cancel() = 0;
|
||||
virtual float64 progress() = 0;
|
||||
virtual int loadOffset() = 0;
|
||||
|
||||
virtual const StorageImageLocation &location() = 0;
|
||||
virtual void refreshFileReference(const QByteArray &data) = 0;
|
||||
virtual Storage::Cache::Key cacheKey() = 0;
|
||||
virtual void setDelayedStorageLocation(
|
||||
const StorageImageLocation &location) = 0;
|
||||
virtual void performDelayedLoad(Data::FileOrigin origin) = 0;
|
||||
virtual void setImageBytes(const QByteArray &bytes) = 0;
|
||||
|
||||
virtual int width() = 0;
|
||||
virtual int height() = 0;
|
||||
virtual int bytesSize() = 0;
|
||||
virtual void setInformation(int size, int width, int height) = 0;
|
||||
|
||||
virtual QByteArray bytesForCache() = 0;
|
||||
|
||||
};
|
||||
|
||||
@ -69,8 +42,6 @@ class Image final {
|
||||
public:
|
||||
explicit Image(std::unique_ptr<Images::Source> &&source);
|
||||
|
||||
void replaceSource(std::unique_ptr<Images::Source> &&source);
|
||||
|
||||
static not_null<Image*> Empty(); // 1x1 transparent
|
||||
static not_null<Image*> BlankMedia(); // 1x1 black
|
||||
|
||||
@ -145,21 +116,6 @@ public:
|
||||
int32 w,
|
||||
int32 h = 0) const;
|
||||
|
||||
bool loading() const {
|
||||
return _source->loading();
|
||||
}
|
||||
bool displayLoading() const {
|
||||
return _source->displayLoading();
|
||||
}
|
||||
void cancel() {
|
||||
_source->cancel();
|
||||
}
|
||||
float64 progress() const {
|
||||
return loaded() ? 1. : _source->progress();
|
||||
}
|
||||
int loadOffset() const {
|
||||
return _source->loadOffset();
|
||||
}
|
||||
int width() const {
|
||||
return _source->width();
|
||||
}
|
||||
@ -169,32 +125,10 @@ public:
|
||||
QSize size() const {
|
||||
return { width(), height() };
|
||||
}
|
||||
int bytesSize() const {
|
||||
return _source->bytesSize();
|
||||
}
|
||||
void setInformation(int size, int width, int height) {
|
||||
_source->setInformation(size, width, height);
|
||||
}
|
||||
void load(Data::FileOrigin origin);
|
||||
void loadEvenCancelled(Data::FileOrigin origin);
|
||||
const StorageImageLocation &location() const {
|
||||
return _source->location();
|
||||
}
|
||||
void refreshFileReference(const QByteArray &data) {
|
||||
_source->refreshFileReference(data);
|
||||
}
|
||||
Storage::Cache::Key cacheKey() const;
|
||||
QByteArray bytesForCache() const {
|
||||
return _source->bytesForCache();
|
||||
}
|
||||
void load();
|
||||
|
||||
bool loaded() const;
|
||||
bool isNull() const;
|
||||
void unload() const;
|
||||
void setDelayedStorageLocation(
|
||||
Data::FileOrigin origin,
|
||||
const StorageImageLocation &location);
|
||||
void setImageBytes(const QByteArray &bytes);
|
||||
|
||||
~Image();
|
||||
|
||||
|
@ -68,23 +68,6 @@ MTPInputPeer GenerateInputPeer(
|
||||
|
||||
} // namespace
|
||||
|
||||
ImagePtr::ImagePtr() : _data(Image::Empty()) {
|
||||
}
|
||||
|
||||
ImagePtr::ImagePtr(not_null<Image*> data) : _data(data) {
|
||||
}
|
||||
|
||||
Image *ImagePtr::operator->() const {
|
||||
return _data;
|
||||
}
|
||||
Image *ImagePtr::get() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
ImagePtr::operator bool() const {
|
||||
return !_data->isNull();
|
||||
}
|
||||
|
||||
WebFileLocation WebFileLocation::Null;
|
||||
|
||||
StorageFileLocation::StorageFileLocation(
|
||||
|
@ -616,22 +616,6 @@ struct ImageWithLocation {
|
||||
QImage preloaded;
|
||||
};
|
||||
|
||||
class Image;
|
||||
class ImagePtr {
|
||||
public:
|
||||
ImagePtr();
|
||||
explicit ImagePtr(not_null<Image*> data);
|
||||
|
||||
Image *operator->() const;
|
||||
Image *get() const;
|
||||
|
||||
explicit operator bool() const;
|
||||
|
||||
private:
|
||||
not_null<Image*> _data;
|
||||
|
||||
};
|
||||
|
||||
InMemoryKey inMemoryKey(const StorageFileLocation &location);
|
||||
|
||||
inline InMemoryKey inMemoryKey(const StorageImageLocation &location) {
|
||||
|
@ -20,597 +20,45 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtCore/QBuffer>
|
||||
|
||||
namespace Images {
|
||||
namespace {
|
||||
|
||||
ImageSource::ImageSource(QImage &&data, const QByteArray &format)
|
||||
: _data(std::move(data))
|
||||
, _format(format)
|
||||
, _width(_data.width())
|
||||
, _height(_data.height()) {
|
||||
[[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();
|
||||
}
|
||||
|
||||
void ImageSource::load(Data::FileOrigin origin) {
|
||||
if (_data.isNull() && !_bytes.isEmpty()) {
|
||||
_data = App::readImage(_bytes, &_format, false);
|
||||
}
|
||||
[[nodiscard]] QImage ReadImage(const QByteArray &content) {
|
||||
return App::readImage(content, nullptr, false, nullptr);
|
||||
}
|
||||
|
||||
void ImageSource::loadEvenCancelled(Data::FileOrigin origin) {
|
||||
load(origin);
|
||||
} // namespace
|
||||
|
||||
ImageSource::ImageSource(const QString &path)
|
||||
: ImageSource(ReadContent(path)) {
|
||||
}
|
||||
|
||||
ImageSource::ImageSource(const QByteArray &content)
|
||||
: ImageSource(ReadImage(content)) {
|
||||
}
|
||||
|
||||
ImageSource::ImageSource(QImage &&data) : _data(std::move(data)) {
|
||||
}
|
||||
|
||||
void ImageSource::load() {
|
||||
}
|
||||
|
||||
QImage ImageSource::takeLoaded() {
|
||||
load({});
|
||||
return _data;
|
||||
}
|
||||
|
||||
void ImageSource::unload() {
|
||||
if (_bytes.isEmpty() && !_data.isNull()) {
|
||||
if (_format != "JPG") {
|
||||
_format = "PNG";
|
||||
}
|
||||
{
|
||||
QBuffer buffer(&_bytes);
|
||||
_data.save(&buffer, _format);
|
||||
}
|
||||
Assert(!_bytes.isEmpty());
|
||||
}
|
||||
_data = QImage();
|
||||
}
|
||||
|
||||
bool ImageSource::loading() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImageSource::displayLoading() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ImageSource::cancel() {
|
||||
}
|
||||
|
||||
float64 ImageSource::progress() {
|
||||
return 1.;
|
||||
}
|
||||
|
||||
int ImageSource::loadOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const StorageImageLocation &ImageSource::location() {
|
||||
return StorageImageLocation::Invalid();
|
||||
}
|
||||
|
||||
void ImageSource::refreshFileReference(const QByteArray &data) {
|
||||
}
|
||||
|
||||
Storage::Cache::Key ImageSource::cacheKey() {
|
||||
return Storage::Cache::Key();
|
||||
}
|
||||
|
||||
void ImageSource::setDelayedStorageLocation(
|
||||
const StorageImageLocation &location) {
|
||||
}
|
||||
|
||||
void ImageSource::performDelayedLoad(Data::FileOrigin origin) {
|
||||
}
|
||||
|
||||
void ImageSource::setImageBytes(const QByteArray &bytes) {
|
||||
}
|
||||
|
||||
int ImageSource::width() {
|
||||
return _width;
|
||||
return _data.width();
|
||||
}
|
||||
|
||||
int ImageSource::height() {
|
||||
return _height;
|
||||
}
|
||||
|
||||
int ImageSource::bytesSize() {
|
||||
return _bytes.size();
|
||||
}
|
||||
|
||||
void ImageSource::setInformation(int size, int width, int height) {
|
||||
if (width && height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray ImageSource::bytesForCache() {
|
||||
auto result = QByteArray();
|
||||
{
|
||||
QBuffer buffer(&result);
|
||||
if (!_data.save(&buffer, _format)) {
|
||||
if (_data.save(&buffer, "PNG")) {
|
||||
_format = "PNG";
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
LocalFileSource::LocalFileSource(
|
||||
const QString &path,
|
||||
const QByteArray &content,
|
||||
const QByteArray &format,
|
||||
QImage &&data)
|
||||
: _path(path)
|
||||
, _bytes(content)
|
||||
, _format(format)
|
||||
, _data(std::move(data))
|
||||
, _width(_data.width())
|
||||
, _height(_data.height()) {
|
||||
}
|
||||
|
||||
void LocalFileSource::load(Data::FileOrigin origin) {
|
||||
if (!_data.isNull()) {
|
||||
return;
|
||||
}
|
||||
if (_bytes.isEmpty()) {
|
||||
QFile f(_path);
|
||||
if (f.size() <= App::kImageSizeLimit && f.open(QIODevice::ReadOnly)) {
|
||||
_bytes = f.readAll();
|
||||
}
|
||||
if (_bytes.isEmpty()) {
|
||||
_bytes = "(bad)";
|
||||
}
|
||||
}
|
||||
if (_bytes != "(bad)") {
|
||||
_data = App::readImage(_bytes, &_format, false, nullptr);
|
||||
}
|
||||
_width = std::max(_data.width(), 1);
|
||||
_height = std::max(_data.height(), 1);
|
||||
}
|
||||
|
||||
void LocalFileSource::loadEvenCancelled(Data::FileOrigin origin) {
|
||||
load(origin);
|
||||
}
|
||||
|
||||
QImage LocalFileSource::takeLoaded() {
|
||||
return std::move(_data);
|
||||
}
|
||||
|
||||
void LocalFileSource::unload() {
|
||||
_data = QImage();
|
||||
}
|
||||
|
||||
bool LocalFileSource::loading() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LocalFileSource::displayLoading() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void LocalFileSource::cancel() {
|
||||
}
|
||||
|
||||
float64 LocalFileSource::progress() {
|
||||
return 1.;
|
||||
}
|
||||
|
||||
int LocalFileSource::loadOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const StorageImageLocation &LocalFileSource::location() {
|
||||
return StorageImageLocation::Invalid();
|
||||
}
|
||||
|
||||
void LocalFileSource::refreshFileReference(const QByteArray &data) {
|
||||
}
|
||||
|
||||
Storage::Cache::Key LocalFileSource::cacheKey() {
|
||||
return Storage::Cache::Key();
|
||||
}
|
||||
|
||||
void LocalFileSource::setDelayedStorageLocation(
|
||||
const StorageImageLocation &location) {
|
||||
}
|
||||
|
||||
void LocalFileSource::performDelayedLoad(Data::FileOrigin origin) {
|
||||
}
|
||||
|
||||
void LocalFileSource::setImageBytes(const QByteArray &bytes) {
|
||||
_bytes = bytes;
|
||||
load({});
|
||||
}
|
||||
|
||||
int LocalFileSource::width() {
|
||||
ensureDimensionsKnown();
|
||||
return _width;
|
||||
}
|
||||
|
||||
int LocalFileSource::height() {
|
||||
ensureDimensionsKnown();
|
||||
return _height;
|
||||
}
|
||||
|
||||
int LocalFileSource::bytesSize() {
|
||||
ensureDimensionsKnown();
|
||||
return _bytes.size();
|
||||
}
|
||||
|
||||
void LocalFileSource::setInformation(int size, int width, int height) {
|
||||
ensureDimensionsKnown(); // First load _bytes.
|
||||
if (width && height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
void LocalFileSource::ensureDimensionsKnown() {
|
||||
if (!_width || !_height) {
|
||||
load({});
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray LocalFileSource::bytesForCache() {
|
||||
ensureDimensionsKnown();
|
||||
return (_bytes == "(bad)") ? QByteArray() : _bytes;
|
||||
}
|
||||
|
||||
QImage RemoteSource::takeLoaded() {
|
||||
if (!_loader || !_loader->finished()) {
|
||||
return QImage();
|
||||
}
|
||||
|
||||
if (_loader->cancelled()) {
|
||||
_cancelled = true;
|
||||
destroyLoader();
|
||||
return QImage();
|
||||
}
|
||||
auto data = _loader->imageData(shrinkBox());
|
||||
if (data.isNull()) {
|
||||
// Bad content in the image.
|
||||
data = Image::Empty()->original();
|
||||
}
|
||||
|
||||
setInformation(_loader->bytes().size(), data.width(), data.height());
|
||||
|
||||
destroyLoader();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void RemoteSource::destroyLoader() {
|
||||
if (!_loader) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto loader = base::take(_loader);
|
||||
if (cancelled()) {
|
||||
loader->cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteSource::loadLocal() {
|
||||
if (_loader) {
|
||||
return;
|
||||
}
|
||||
|
||||
_loader = createLoader(Data::FileOrigin(), LoadFromLocalOnly, true);
|
||||
if (_loader) {
|
||||
_loader->start();
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteSource::setImageBytes(const QByteArray &bytes) {
|
||||
if (bytes.isEmpty()) {
|
||||
return;
|
||||
} else if (_loader) {
|
||||
unload();
|
||||
}
|
||||
_loader = createLoader({}, LoadFromLocalOnly, true);
|
||||
_loader->finishWithBytes(bytes);
|
||||
|
||||
const auto location = this->location();
|
||||
if (location.valid()
|
||||
&& !bytes.isEmpty()
|
||||
&& bytes.size() <= Storage::kMaxFileInMemory) {
|
||||
Auth().data().cache().putIfEmpty(
|
||||
location.file().cacheKey(),
|
||||
Storage::Cache::Database::TaggedValue(
|
||||
base::duplicate(bytes),
|
||||
Data::kImageCacheTag));
|
||||
}
|
||||
}
|
||||
|
||||
bool RemoteSource::loading() {
|
||||
return (_loader != nullptr);
|
||||
}
|
||||
|
||||
void RemoteSource::load(Data::FileOrigin origin) {
|
||||
if (!_loader) {
|
||||
_loader = createLoader(origin, LoadFromCloudOrLocal, false);
|
||||
}
|
||||
if (_loader) {
|
||||
_loader->start();
|
||||
}
|
||||
}
|
||||
|
||||
bool RemoteSource::cancelled() const {
|
||||
return _cancelled;
|
||||
}
|
||||
|
||||
void RemoteSource::loadEvenCancelled(Data::FileOrigin origin) {
|
||||
_cancelled = false;
|
||||
return load(origin);
|
||||
}
|
||||
|
||||
bool RemoteSource::displayLoading() {
|
||||
return _loader && (!_loader->loadingLocal() || !_loader->autoLoading());
|
||||
}
|
||||
|
||||
void RemoteSource::cancel() {
|
||||
if (!_loader) {
|
||||
return;
|
||||
}
|
||||
_cancelled = true;
|
||||
destroyLoader();
|
||||
}
|
||||
|
||||
void RemoteSource::unload() {
|
||||
base::take(_loader);
|
||||
}
|
||||
|
||||
float64 RemoteSource::progress() {
|
||||
return _loader ? _loader->currentProgress() : 0.;
|
||||
}
|
||||
|
||||
int RemoteSource::loadOffset() {
|
||||
return _loader ? _loader->currentOffset() : 0;
|
||||
}
|
||||
|
||||
RemoteSource::~RemoteSource() {
|
||||
unload();
|
||||
}
|
||||
|
||||
const StorageImageLocation &RemoteSource::location() {
|
||||
return StorageImageLocation::Invalid();
|
||||
}
|
||||
|
||||
void RemoteSource::refreshFileReference(const QByteArray &data) {
|
||||
}
|
||||
|
||||
void RemoteSource::setDelayedStorageLocation(
|
||||
const StorageImageLocation &location) {
|
||||
}
|
||||
|
||||
void RemoteSource::performDelayedLoad(Data::FileOrigin origin) {
|
||||
}
|
||||
|
||||
QByteArray RemoteSource::bytesForCache() {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
StorageSource::StorageSource(const StorageImageLocation &location, int size)
|
||||
: _location(location)
|
||||
, _size(size) {
|
||||
}
|
||||
|
||||
void StorageSource::refreshFileReference(const QByteArray &data) {
|
||||
_location.refreshFileReference(data);
|
||||
}
|
||||
|
||||
const StorageImageLocation &StorageSource::location() {
|
||||
return _location;
|
||||
}
|
||||
|
||||
Storage::Cache::Key StorageSource::cacheKey() {
|
||||
return _location.valid()
|
||||
? _location.file().cacheKey()
|
||||
: Storage::Cache::Key();
|
||||
}
|
||||
|
||||
int StorageSource::width() {
|
||||
return _location.width();
|
||||
}
|
||||
|
||||
int StorageSource::height() {
|
||||
return _location.height();
|
||||
}
|
||||
|
||||
int StorageSource::bytesSize() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
void StorageSource::setInformation(int size, int width, int height) {
|
||||
if (size) {
|
||||
_size = size;
|
||||
}
|
||||
if (width && height) {
|
||||
_location.setSize(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
QSize StorageSource::shrinkBox() const {
|
||||
return QSize();
|
||||
}
|
||||
|
||||
std::unique_ptr<FileLoader> StorageSource::createLoader(
|
||||
Data::FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) {
|
||||
return _location.valid()
|
||||
? std::make_unique<mtpFileLoader>(
|
||||
_location.file(),
|
||||
origin,
|
||||
UnknownFileLocation,
|
||||
QString(),
|
||||
_size,
|
||||
LoadToCacheAsWell,
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
Data::kImageCacheTag)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
WebCachedSource::WebCachedSource(
|
||||
const WebFileLocation &location,
|
||||
QSize box,
|
||||
int size)
|
||||
: _location(location)
|
||||
, _box(box)
|
||||
, _size(size) {
|
||||
}
|
||||
|
||||
WebCachedSource::WebCachedSource(
|
||||
const WebFileLocation &location,
|
||||
int width,
|
||||
int height,
|
||||
int size)
|
||||
: _location(location)
|
||||
, _width(width)
|
||||
, _height(height)
|
||||
, _size(size) {
|
||||
}
|
||||
|
||||
Storage::Cache::Key WebCachedSource::cacheKey() {
|
||||
return _location.isNull()
|
||||
? Storage::Cache::Key()
|
||||
: Data::WebDocumentCacheKey(_location);
|
||||
}
|
||||
|
||||
int WebCachedSource::width() {
|
||||
return _width;
|
||||
}
|
||||
|
||||
int WebCachedSource::height() {
|
||||
return _height;
|
||||
}
|
||||
|
||||
int WebCachedSource::bytesSize() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
void WebCachedSource::setInformation(int size, int width, int height) {
|
||||
if (size) {
|
||||
_size = size;
|
||||
}
|
||||
if (width && height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
QSize WebCachedSource::shrinkBox() const {
|
||||
return _box;
|
||||
}
|
||||
|
||||
std::unique_ptr<FileLoader> WebCachedSource::createLoader(
|
||||
Data::FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) {
|
||||
return !_location.isNull()
|
||||
? std::make_unique<mtpFileLoader>(
|
||||
_location,
|
||||
_size,
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
Data::kImageCacheTag)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
GeoPointSource::GeoPointSource(const GeoPointLocation &location)
|
||||
: _location(location) {
|
||||
}
|
||||
|
||||
Storage::Cache::Key GeoPointSource::cacheKey() {
|
||||
return Data::GeoPointCacheKey(_location);
|
||||
}
|
||||
|
||||
int GeoPointSource::width() {
|
||||
return _location.width * _location.scale;
|
||||
}
|
||||
|
||||
int GeoPointSource::height() {
|
||||
return _location.height * _location.scale;
|
||||
}
|
||||
|
||||
int GeoPointSource::bytesSize() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
void GeoPointSource::setInformation(int size, int width, int height) {
|
||||
Expects(_location.scale != 0);
|
||||
|
||||
if (size) {
|
||||
_size = size;
|
||||
}
|
||||
if (width && height) {
|
||||
_location.width = width / _location.scale;
|
||||
_location.height = height / _location.scale;
|
||||
}
|
||||
}
|
||||
|
||||
QSize GeoPointSource::shrinkBox() const {
|
||||
return QSize();
|
||||
}
|
||||
|
||||
std::unique_ptr<FileLoader> GeoPointSource::createLoader(
|
||||
Data::FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) {
|
||||
return std::make_unique<mtpFileLoader>(
|
||||
_location,
|
||||
_size,
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
Data::kImageCacheTag);
|
||||
}
|
||||
|
||||
WebUrlSource::WebUrlSource(const QString &url, QSize box)
|
||||
: _url(url)
|
||||
, _box(box) {
|
||||
}
|
||||
|
||||
WebUrlSource::WebUrlSource(const QString &url, int width, int height)
|
||||
: _url(url)
|
||||
, _width(width)
|
||||
, _height(height) {
|
||||
}
|
||||
|
||||
Storage::Cache::Key WebUrlSource::cacheKey() {
|
||||
return Data::UrlCacheKey(_url);
|
||||
}
|
||||
|
||||
int WebUrlSource::width() {
|
||||
return _width;
|
||||
}
|
||||
|
||||
int WebUrlSource::height() {
|
||||
return _height;
|
||||
}
|
||||
|
||||
int WebUrlSource::bytesSize() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
void WebUrlSource::setInformation(int size, int width, int height) {
|
||||
if (size) {
|
||||
_size = size;
|
||||
}
|
||||
if (width && height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
QSize WebUrlSource::shrinkBox() const {
|
||||
return _box;
|
||||
}
|
||||
|
||||
std::unique_ptr<FileLoader> WebUrlSource::createLoader(
|
||||
Data::FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) {
|
||||
return std::make_unique<webFileLoader>(
|
||||
_url,
|
||||
QString(),
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
Data::kImageCacheTag);
|
||||
return _data.height();
|
||||
}
|
||||
|
||||
} // namespace Images
|
||||
|
@ -13,244 +13,18 @@ namespace Images {
|
||||
|
||||
class ImageSource : public Source {
|
||||
public:
|
||||
ImageSource(QImage &&data, const QByteArray &format);
|
||||
explicit ImageSource(const QString &path);
|
||||
explicit ImageSource(const QByteArray &content);
|
||||
explicit ImageSource(QImage &&data);
|
||||
|
||||
void load(Data::FileOrigin origin) override;
|
||||
void loadEvenCancelled(Data::FileOrigin origin) override;
|
||||
void load() override;
|
||||
QImage takeLoaded() override;
|
||||
void unload() override;
|
||||
|
||||
bool loading() override;
|
||||
bool displayLoading() override;
|
||||
void cancel() override;
|
||||
float64 progress() override;
|
||||
int loadOffset() override;
|
||||
|
||||
const StorageImageLocation &location() override;
|
||||
void refreshFileReference(const QByteArray &data) override;
|
||||
Storage::Cache::Key cacheKey() override;
|
||||
void setDelayedStorageLocation(
|
||||
const StorageImageLocation &location) override;
|
||||
void performDelayedLoad(Data::FileOrigin origin) override;
|
||||
void setImageBytes(const QByteArray &bytes) override;
|
||||
|
||||
int width() override;
|
||||
int height() override;
|
||||
int bytesSize() override;
|
||||
void setInformation(int size, int width, int height) override;
|
||||
|
||||
QByteArray bytesForCache() override;
|
||||
|
||||
private:
|
||||
QImage _data;
|
||||
QByteArray _format;
|
||||
QByteArray _bytes;
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
|
||||
};
|
||||
|
||||
class LocalFileSource : public Source {
|
||||
public:
|
||||
explicit LocalFileSource(
|
||||
const QString &path,
|
||||
const QByteArray &content = QByteArray(),
|
||||
const QByteArray &format = QByteArray(),
|
||||
QImage &&data = QImage());
|
||||
|
||||
void load(Data::FileOrigin origin) override;
|
||||
void loadEvenCancelled(Data::FileOrigin origin) override;
|
||||
QImage takeLoaded() override;
|
||||
void unload() override;
|
||||
|
||||
bool loading() override;
|
||||
bool displayLoading() override;
|
||||
void cancel() override;
|
||||
float64 progress() override;
|
||||
int loadOffset() override;
|
||||
|
||||
const StorageImageLocation &location() override;
|
||||
void refreshFileReference(const QByteArray &data) override;
|
||||
Storage::Cache::Key cacheKey() override;
|
||||
void setDelayedStorageLocation(
|
||||
const StorageImageLocation &location) override;
|
||||
void performDelayedLoad(Data::FileOrigin origin) override;
|
||||
void setImageBytes(const QByteArray &bytes) override;
|
||||
|
||||
int width() override;
|
||||
int height() override;
|
||||
int bytesSize() override;
|
||||
void setInformation(int size, int width, int height) override;
|
||||
|
||||
QByteArray bytesForCache() override;
|
||||
|
||||
private:
|
||||
void ensureDimensionsKnown();
|
||||
|
||||
QString _path;
|
||||
QByteArray _bytes;
|
||||
QByteArray _format;
|
||||
QImage _data;
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
|
||||
};
|
||||
|
||||
class RemoteSource : public Source {
|
||||
public:
|
||||
void load(Data::FileOrigin origin) override;
|
||||
void loadEvenCancelled(Data::FileOrigin origin) override;
|
||||
QImage takeLoaded() override;
|
||||
void unload() override;
|
||||
|
||||
bool loading() override;
|
||||
bool displayLoading() override;
|
||||
void cancel() override;
|
||||
float64 progress() override;
|
||||
int loadOffset() override;
|
||||
|
||||
const StorageImageLocation &location() override;
|
||||
void refreshFileReference(const QByteArray &data) override;
|
||||
void setDelayedStorageLocation(
|
||||
const StorageImageLocation &location) override;
|
||||
void performDelayedLoad(Data::FileOrigin origin) override;
|
||||
void setImageBytes(const QByteArray &bytes) override;
|
||||
|
||||
QByteArray bytesForCache() override;
|
||||
|
||||
~RemoteSource();
|
||||
|
||||
protected:
|
||||
// If after loading the image we need to shrink it to fit into a
|
||||
// specific size, you can return this size here.
|
||||
virtual QSize shrinkBox() const = 0;
|
||||
virtual std::unique_ptr<FileLoader> createLoader(
|
||||
Data::FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) = 0;
|
||||
|
||||
void loadLocal();
|
||||
FileLoader *currentLoader() const {
|
||||
return _loader.get();
|
||||
}
|
||||
|
||||
private:
|
||||
bool cancelled() const;
|
||||
void destroyLoader();
|
||||
|
||||
std::unique_ptr<FileLoader> _loader;
|
||||
bool _cancelled = false;
|
||||
|
||||
};
|
||||
|
||||
class StorageSource : public RemoteSource {
|
||||
public:
|
||||
StorageSource(
|
||||
const StorageImageLocation &location,
|
||||
int size);
|
||||
|
||||
const StorageImageLocation &location() override;
|
||||
Storage::Cache::Key cacheKey() override;
|
||||
|
||||
void refreshFileReference(const QByteArray &data) override;
|
||||
|
||||
int width() override;
|
||||
int height() override;
|
||||
int bytesSize() override;
|
||||
void setInformation(int size, int width, int height) override;
|
||||
|
||||
protected:
|
||||
QSize shrinkBox() const override;
|
||||
std::unique_ptr<FileLoader> createLoader(
|
||||
Data::FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) override;
|
||||
|
||||
StorageImageLocation _location;
|
||||
int _size = 0;
|
||||
|
||||
};
|
||||
|
||||
class WebCachedSource : public RemoteSource {
|
||||
public:
|
||||
WebCachedSource(const WebFileLocation &location, QSize box, int size = 0);
|
||||
WebCachedSource(
|
||||
const WebFileLocation &location,
|
||||
int width,
|
||||
int height,
|
||||
int size = 0);
|
||||
|
||||
Storage::Cache::Key cacheKey() override;
|
||||
|
||||
int width() override;
|
||||
int height() override;
|
||||
int bytesSize() override;
|
||||
void setInformation(int size, int width, int height) override;
|
||||
|
||||
protected:
|
||||
QSize shrinkBox() const override;
|
||||
std::unique_ptr<FileLoader> createLoader(
|
||||
Data::FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) override;
|
||||
|
||||
WebFileLocation _location;
|
||||
QSize _box;
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
int _size = 0;
|
||||
|
||||
};
|
||||
|
||||
class GeoPointSource : public RemoteSource {
|
||||
public:
|
||||
GeoPointSource(const GeoPointLocation &location);
|
||||
|
||||
Storage::Cache::Key cacheKey() override;
|
||||
|
||||
int width() override;
|
||||
int height() override;
|
||||
int bytesSize() override;
|
||||
void setInformation(int size, int width, int height) override;
|
||||
|
||||
protected:
|
||||
QSize shrinkBox() const override;
|
||||
std::unique_ptr<FileLoader> createLoader(
|
||||
Data::FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) override;
|
||||
|
||||
GeoPointLocation _location;
|
||||
int _size = 0;
|
||||
|
||||
};
|
||||
|
||||
class WebUrlSource : public RemoteSource {
|
||||
public:
|
||||
// If !box.isEmpty() then resize the image to fit in this box.
|
||||
explicit WebUrlSource(const QString &url, QSize box = QSize());
|
||||
WebUrlSource(const QString &url, int width, int height);
|
||||
|
||||
Storage::Cache::Key cacheKey() override;
|
||||
|
||||
int width() override;
|
||||
int height() override;
|
||||
int bytesSize() override;
|
||||
void setInformation(int size, int width, int height) override;
|
||||
|
||||
protected:
|
||||
QSize shrinkBox() const override;
|
||||
std::unique_ptr<FileLoader> createLoader(
|
||||
Data::FileOrigin origin,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading) override;
|
||||
|
||||
private:
|
||||
QString _url;
|
||||
QSize _box;
|
||||
int _size = 0;
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user