Move image-related modules to ui/image/.

This commit is contained in:
John Preston 2018-10-23 13:44:42 +04:00
parent 8b76428c7e
commit 595134cab5
62 changed files with 1274 additions and 1222 deletions

View File

@ -23,7 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item_components.h"
#include "history/view/history_view_service_message.h"
#include "media/media_audio.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "inline_bots/inline_bot_layout_item.h"
#include "messenger.h"
#include "application.h"

View File

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_peer.h"
enum NewMessageType : char;
enum class ImageRoundRadius;
class Messenger;
class MainWindow;
class MainWidget;

View File

@ -11,11 +11,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwidget.h"
#include "mainwindow.h"
#include "window/themes/window_theme.h"
#include "ui/effects/round_checkbox.h"
#include "ui/image/image.h"
#include "auth_session.h"
#include "styles/style_overview.h"
#include "styles/style_boxes.h"
#include "ui/effects/round_checkbox.h"
#include "ui/image.h"
#include "auth_session.h"
class BackgroundBox::Inner : public TWidget, public RPCSender, private base::Subscriber {
public:

View File

@ -19,8 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "ui/toast/toast.h"
#include "ui/image/image.h"
#include "ui/empty_userpic.h"
#include "ui/image.h"
#include "core/click_handler_types.h"
#include "storage/localstorage.h"
#include "data/data_session.h"

View File

@ -8,8 +8,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/edit_caption_box.h"
#include "ui/widgets/input_fields.h"
#include "ui/image/image.h"
#include "ui/text_options.h"
#include "ui/image.h"
#include "media/media_clip_reader.h"
#include "history/history.h"
#include "history/history_item.h"
@ -79,13 +79,13 @@ EditCaptionBox::EditCaptionBox(
| Images::Option::RoundedTopRight
| Images::Option::RoundedBottomLeft
| Images::Option::RoundedBottomRight;
_thumb = Images::pixmap(
_thumb = App::pixmapFromImageInPlace(Images::prepare(
image->pix(_msgId).toImage(),
_thumbw * cIntRetinaFactor(),
0,
options,
st::msgFileThumbSize,
st::msgFileThumbSize);
st::msgFileThumbSize));
};
}

View File

@ -766,13 +766,13 @@ void SingleFilePreview::prepareThumb(const QImage &preview) {
| Images::Option::RoundedTopRight
| Images::Option::RoundedBottomLeft
| Images::Option::RoundedBottomRight;
_fileThumb = Images::pixmap(
_fileThumb = App::pixmapFromImageInPlace(Images::prepare(
preview,
thumbWidth * cIntRetinaFactor(),
0,
options,
st::msgFileThumbSize,
st::msgFileThumbSize);
st::msgFileThumbSize));
}
void SingleFilePreview::preparePreview(const Storage::PreparedFile &file) {

View File

@ -21,8 +21,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_chat_helpers.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/scroll_area.h"
#include "ui/image/image.h"
#include "ui/emoji_config.h"
#include "ui/image.h"
#include "auth_session.h"
#include "messenger.h"

View File

@ -27,7 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/slide_animation.h"
#include "ui/widgets/discrete_sliders.h"
#include "ui/widgets/input_fields.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "auth_session.h"
#include "messenger.h"

View File

@ -16,10 +16,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/labels.h"
#include "ui/widgets/shadow.h"
#include "ui/effects/ripple_animation.h"
#include "ui/image/image.h"
#include "ui/wrap/fade_wrap.h"
#include "ui/empty_userpic.h"
#include "ui/emoji_config.h"
#include "ui/image.h"
#include "messenger.h"
#include "mainwindow.h"
#include "lang/lang_keys.h"

View File

@ -13,7 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "storage/localstorage.h"
#include "ui/widgets/scroll_area.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "styles/style_history.h"
#include "styles/style_widgets.h"
#include "styles/style_chat_helpers.h"

View File

@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/effects/ripple_animation.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "boxes/stickers_box.h"
#include "inline_bots/inline_bot_result.h"
#include "chat_helpers/stickers.h"

View File

@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "ui/widgets/buttons.h"
#include "ui/effects/ripple_animation.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "boxes/stickers_box.h"
#include "inline_bots/inline_bot_result.h"
#include "chat_helpers/stickers.h"

View File

@ -8,11 +8,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "chat_helpers/tabbed_panel.h"
#include "ui/widgets/shadow.h"
#include "styles/style_chat_helpers.h"
#include "ui/image/image_prepare.h"
#include "chat_helpers/tabbed_selector.h"
#include "window/window_controller.h"
#include "mainwindow.h"
#include "messenger.h"
#include "styles/style_chat_helpers.h"
namespace ChatHelpers {
namespace {

View File

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/shadow.h"
#include "ui/widgets/discrete_sliders.h"
#include "ui/widgets/scroll_area.h"
#include "ui/image/image_prepare.h"
#include "storage/localstorage.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"

View File

@ -21,7 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_media_types.h"
#include "window/window_controller.h"
#include "storage/cache/storage_cache_database.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "auth_session.h"
#include "mainwindow.h"
#include "messenger.h"

View File

@ -11,9 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item.h"
#include "history/history_location_manager.h"
#include "history/view/history_view_element.h"
#include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "ui/text_options.h"
#include "ui/emoji_config.h"
#include "ui/image.h"
#include "storage/storage_shared_media.h"
#include "storage/localstorage.h"
#include "data/data_session.h"

View File

@ -26,9 +26,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwindow.h"
#include "window/window_controller.h"
#include "storage/localstorage.h"
#include "ui/image/image.h"
#include "ui/empty_userpic.h"
#include "ui/text_options.h"
#include "ui/image.h"
namespace {

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_types.h"
#include "data/data_flags.h"
#include "data/data_notify_settings.h"
#include "data/data_file_origin.h"
namespace Ui {
class EmptyUserpic;

View File

@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo.h"
#include "data/data_session.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "mainwidget.h"
#include "history/history_media_types.h"
#include "auth_session.h"

View File

@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "auth_session.h"
#include "apiwrap.h"
#include "messenger.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "export/export_controller.h"
#include "export/view/export_view_panel_controller.h"
#include "window/notifications_manager.h"

View File

@ -27,7 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_controller.h"
#include "auth_session.h"
#include "ui/widgets/popup_menu.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "core/file_utilities.h"
#include "core/tl_help.h"
#include "base/overload.h"

View File

@ -32,8 +32,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_feed_messages.h"
#include "data/data_channel_admins.h"
#include "data/data_feed.h"
#include "ui/image/image.h"
#include "ui/text_options.h"
#include "ui/image.h"
#include "core/crash_reports.h"
namespace {

View File

@ -20,8 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_service_message.h"
#include "history/view/history_view_cursor_state.h"
#include "ui/widgets/popup_menu.h"
#include "ui/image/image.h"
#include "ui/text_options.h"
#include "ui/image.h"
#include "window/window_controller.h"
#include "window/window_peer_menu.h"
#include "boxes/confirm_box.h"

View File

@ -9,8 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "ui/effects/ripple_animation.h"
#include "ui/image/image.h"
#include "ui/text_options.h"
#include "ui/image.h"
#include "history/history_message.h"
#include "history/history_media.h"
#include "history/history_media_types.h"

View File

@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwidget.h"
#include "lang/lang_keys.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "platform/platform_specific.h"
namespace {

View File

@ -31,11 +31,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_controller.h"
#include "styles/style_history.h"
#include "calls/calls_instance.h"
#include "ui/image/image.h"
#include "ui/empty_userpic.h"
#include "ui/grouped_layout.h"
#include "ui/text_options.h"
#include "ui/emoji_config.h"
#include "ui/image.h"
#include "data/data_session.h"
#include "data/data_media_types.h"

View File

@ -22,7 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/shadow.h"
#include "ui/effects/ripple_animation.h"
#include "ui/special_buttons.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "inline_bots/inline_bot_result.h"
#include "data/data_drafts.h"
#include "data/data_session.h"

View File

@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item_text.h"
#include "history/history_media_types.h"
#include "ui/widgets/popup_menu.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "chat_helpers/message_field.h"
#include "boxes/confirm_box.h"
#include "data/data_photo.h"

View File

@ -21,7 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_location_manager.h"
#include "history/view/history_view_cursor_state.h"
#include "storage/localstorage.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "auth_session.h"
#include "apiwrap.h"
#include "lang/lang_keys.h"

View File

@ -14,8 +14,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "inline_bots/inline_bot_layout_internal.h"
#include "storage/localstorage.h"
#include "mainwidget.h"
#include "ui/image/image.h"
#include "ui/empty_userpic.h"
#include "ui/image.h"
namespace InlineBots {
namespace Layout {

View File

@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/file_download.h"
#include "core/file_utilities.h"
#include "core/mime_type.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "mainwidget.h"
#include "auth_session.h"

View File

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/widgets/shadow.h"
#include "ui/effects/ripple_animation.h"
#include "ui/image/image_prepare.h"
#include "boxes/confirm_box.h"
#include "inline_bots/inline_bot_result.h"
#include "inline_bots/inline_bot_layout_item.h"

View File

@ -27,11 +27,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_connecting_widget.h"
#include "ui/toast/toast.h"
#include "ui/widgets/dropdown_menu.h"
#include "ui/image/image.h"
#include "ui/focus_persister.h"
#include "ui/resize_area.h"
#include "ui/text_options.h"
#include "ui/emoji_config.h"
#include "ui/image.h"
#include "chat_helpers/message_field.h"
#include "chat_helpers/stickers.h"
#include "info/info_memento.h"

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "storage/localimageloader.h"
#include "ui/image/image_prepare.h"
class FileLocation;

View File

@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "history/history.h"
#include "history/history_media.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "auth_session.h"
#include "styles/style_mediaview.h"

View File

@ -15,8 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/mime_type.h"
#include "ui/widgets/popup_menu.h"
#include "ui/widgets/buttons.h"
#include "ui/image/image.h"
#include "ui/text_options.h"
#include "ui/image.h"
#include "media/media_clip_reader.h"
#include "media/view/media_clip_controller.h"
#include "media/view/media_view_group_thumbs.h"
@ -47,6 +47,13 @@ constexpr auto kIdsLimit = 48;
// Preload next messages if we went further from current than that.
constexpr auto kIdsPreloadAfter = 28;
Images::Options VideoThumbOptions(not_null<DocumentData*> document) {
const auto result = Images::Option::Smooth | Images::Option::Blurred;
return (document && document->isVideoMessage())
? (result | Images::Option::Circled)
: result;
}
} // namespace
struct MediaView::SharedMedia {
@ -1680,14 +1687,6 @@ void MediaView::displayFinished() {
}
}
Images::Options MediaView::videoThumbOptions() const {
auto options = Images::Option::Smooth | Images::Option::Blurred;
if (_doc && _doc->isVideoMessage()) {
options |= Images::Option::Circled;
}
return options;
}
void MediaView::initAnimation() {
Expects(_doc != nullptr);
Expects(_doc->isAnimation() || _doc->isVideoFile());
@ -1701,10 +1700,10 @@ void MediaView::initAnimation() {
} else if (_doc->dimensions.width() && _doc->dimensions.height()) {
auto w = _doc->dimensions.width();
auto h = _doc->dimensions.height();
_current = _doc->thumb->pixNoCache(fileOrigin(), w, h, videoThumbOptions(), w / cIntRetinaFactor(), h / cIntRetinaFactor());
_current = _doc->thumb->pixNoCache(fileOrigin(), w, h, VideoThumbOptions(_doc), w / cIntRetinaFactor(), h / cIntRetinaFactor());
_current.setDevicePixelRatio(cRetinaFactor());
} else {
_current = _doc->thumb->pixNoCache(fileOrigin(), _doc->thumb->width(), _doc->thumb->height(), videoThumbOptions(), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
_current = _doc->thumb->pixNoCache(fileOrigin(), _doc->thumb->width(), _doc->thumb->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
}
}
@ -1717,10 +1716,10 @@ void MediaView::createClipReader() {
if (_doc->dimensions.width() && _doc->dimensions.height()) {
int w = _doc->dimensions.width();
int h = _doc->dimensions.height();
_current = _doc->thumb->pixNoCache(fileOrigin(), w, h, videoThumbOptions(), w / cIntRetinaFactor(), h / cIntRetinaFactor());
_current = _doc->thumb->pixNoCache(fileOrigin(), w, h, VideoThumbOptions(_doc), w / cIntRetinaFactor(), h / cIntRetinaFactor());
_current.setDevicePixelRatio(cRetinaFactor());
} else {
_current = _doc->thumb->pixNoCache(fileOrigin(), _doc->thumb->width(), _doc->thumb->height(), videoThumbOptions(), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
_current = _doc->thumb->pixNoCache(fileOrigin(), _doc->thumb->width(), _doc->thumb->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
}
auto mode = (_doc->isVideoFile() || _doc->isVideoMessage())
? Media::Clip::Reader::Mode::Video

View File

@ -207,7 +207,6 @@ private:
void initAnimation();
void createClipReader();
Images::Options videoThumbOptions() const;
void initThemePreview();
void destroyThemePreview();

View File

@ -42,9 +42,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_lock_widgets.h"
#include "history/history_location_manager.h"
#include "ui/widgets/tooltip.h"
#include "ui/image/image.h"
#include "ui/text_options.h"
#include "ui/emoji_config.h"
#include "ui/image.h"
#include "storage/serialize_common.h"
#include "window/window_controller.h"
#include "base/qthelp_regex.h"

View File

@ -28,8 +28,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item_components.h"
#include "history/view/history_view_cursor_state.h"
#include "ui/effects/round_checkbox.h"
#include "ui/image/image.h"
#include "ui/text_options.h"
#include "ui/image.h"
namespace Overview {
namespace Layout {

View File

@ -20,7 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/labels.h"
#include "ui/effects/radial_animation.h"
#include "ui/toast/toast.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "lang/lang_keys.h"
#include "window/themes/window_theme_editor.h"
#include "window/themes/window_theme.h"

View File

@ -88,7 +88,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/animation.h"
#include "ui/twidget.h"
#include "ui/images.h"
#include "ui/image/image_location.h"
#include "ui/text/text.h"
#include "data/data_types.h"

View File

@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/serialize_common.h"
#include "auth_session.h"
#include "ui/image.h"
#include "ui/image/image.h"
namespace Serialize {

View File

@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/images.h"
#include "mtproto/auth_key.h"
namespace Serialize {

View File

@ -10,7 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/serialize_common.h"
#include "chat_helpers/stickers.h"
#include "data/data_session.h"
#include "ui/image.h"
#include "ui/image/image.h"
#include "auth_session.h"
namespace {

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_file_utilities.h"
#include "storage/localimageloader.h"
#include "core/mime_type.h"
#include "ui/image/image_prepare.h"
namespace Storage {
namespace {

View File

@ -5,13 +5,11 @@ 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
*/
#include "ui/image.h"
#include "ui/image/image.h"
#include "storage/file_download.h"
#include "data/data_session.h"
#include "ui/image/image_source.h"
#include "storage/cache/storage_cache_database.h"
#include "history/history_item.h"
#include "history/history.h"
#include "data/data_session.h"
#include "auth_session.h"
namespace Images {
@ -312,710 +310,6 @@ ImagePtr Create(const GeoPointLocation &location) {
return ImagePtr(i.value());
}
Source::~Source() = default;
ImageSource::ImageSource(QImage &&data, const QByteArray &format)
: _data(std::move(data))
, _format(format) {
}
void ImageSource::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
}
void ImageSource::loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
}
QImage ImageSource::takeLoaded() {
return _data;
}
void ImageSource::forget() {
}
void ImageSource::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
}
void ImageSource::automaticLoadSettingsChanged() {
}
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::Null;
}
void ImageSource::refreshFileReference(const QByteArray &data) {
}
std::optional<Storage::Cache::Key> ImageSource::cacheKey() {
return std::nullopt;
}
void ImageSource::setDelayedStorageLocation(
const StorageImageLocation &location) {
}
void ImageSource::performDelayedLoad(Data::FileOrigin origin) {
}
bool ImageSource::isDelayedStorageImage() const {
return false;
}
void ImageSource::setImageBytes(const QByteArray &bytes) {
}
int ImageSource::width() {
return _data.width();
}
int ImageSource::height() {
return _data.height();
}
void ImageSource::setInformation(int size, int width, int 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)) {
}
void LocalFileSource::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
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,
bool loadFirst,
bool prior) {
load(origin, loadFirst, prior);
}
QImage LocalFileSource::takeLoaded() {
return std::move(_data);
}
void LocalFileSource::forget() {
_data = QImage();
}
void LocalFileSource::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
}
void LocalFileSource::automaticLoadSettingsChanged() {
}
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::Null;
}
void LocalFileSource::refreshFileReference(const QByteArray &data) {
}
std::optional<Storage::Cache::Key> LocalFileSource::cacheKey() {
return std::nullopt;
}
void LocalFileSource::setDelayedStorageLocation(
const StorageImageLocation &location) {
}
void LocalFileSource::performDelayedLoad(Data::FileOrigin origin) {
}
bool LocalFileSource::isDelayedStorageImage() const {
return false;
}
void LocalFileSource::setImageBytes(const QByteArray &bytes) {
_bytes = bytes;
load({}, false, true);
}
int LocalFileSource::width() {
ensureDimensionsKnown();
return _width;
}
int LocalFileSource::height() {
ensureDimensionsKnown();
return _height;
}
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({}, false, false);
}
}
QByteArray LocalFileSource::bytesForCache() {
ensureDimensionsKnown();
return (_bytes == "(bad)") ? QByteArray() : _bytes;
}
QImage RemoteSource::takeLoaded() {
if (!loaderValid() || !_loader->finished()) {
return QImage();
}
auto data = _loader->imageData(shrinkBox());
if (data.isNull()) {
destroyLoaderDelayed(CancelledFileLoader);
return QImage();
}
setInformation(_loader->bytes().size(), data.width(), data.height());
destroyLoaderDelayed();
return data;
}
bool RemoteSource::loaderValid() const {
return _loader && _loader != CancelledFileLoader;
}
void RemoteSource::destroyLoaderDelayed(FileLoader *newValue) {
Expects(loaderValid());
_loader->stop();
auto loader = std::unique_ptr<FileLoader>(std::exchange(_loader, newValue));
Auth().downloader().delayedDestroyLoader(std::move(loader));
}
void RemoteSource::loadLocal() {
if (loaderValid()) {
return;
}
_loader = createLoader(std::nullopt, LoadFromLocalOnly, true);
if (_loader) _loader->start();
}
void RemoteSource::setImageBytes(const QByteArray &bytes) {
if (bytes.isEmpty()) {
return;
}
_loader = createLoader({}, LoadFromLocalOnly, true);
_loader->finishWithBytes(bytes);
const auto location = this->location();
if (!location.isNull()
&& !bytes.isEmpty()
&& bytes.size() <= Storage::kMaxFileInMemory) {
Auth().data().cache().putIfEmpty(
Data::StorageCacheKey(location),
Storage::Cache::Database::TaggedValue(
base::duplicate(bytes),
Data::kImageCacheTag));
}
}
bool RemoteSource::loading() {
return loaderValid();
}
void RemoteSource::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (_loader != CancelledFileLoader && item) {
bool loadFromCloud = false;
if (item->history()->peer->isUser()) {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoPrivate);
} else {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoGroups);
}
if (_loader) {
if (loadFromCloud) _loader->permitLoadFromCloud();
} else {
_loader = createLoader(
origin,
loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly,
true);
if (_loader) _loader->start();
}
}
}
void RemoteSource::automaticLoadSettingsChanged() {
if (_loader == CancelledFileLoader) {
_loader = nullptr;
}
}
void RemoteSource::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (!_loader) {
_loader = createLoader(origin, LoadFromCloudOrLocal, false);
}
if (loaderValid()) {
_loader->start(loadFirst, prior);
}
}
void RemoteSource::loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (_loader == CancelledFileLoader) {
_loader = nullptr;
}
return load(origin, loadFirst, prior);
}
RemoteSource::~RemoteSource() {
forget();
}
bool RemoteSource::displayLoading() {
return loaderValid()
&& (!_loader->loadingLocal() || !_loader->autoLoading());
}
void RemoteSource::cancel() {
if (!loaderValid()) return;
const auto loader = std::exchange(_loader, CancelledFileLoader);
loader->cancel();
loader->stop();
Auth().downloader().delayedDestroyLoader(
std::unique_ptr<FileLoader>(loader));
}
void RemoteSource::forget() {
if (loaderValid()) {
destroyLoaderDelayed();
}
}
float64 RemoteSource::progress() {
return loaderValid() ? _loader->currentProgress() : 0.;
}
int RemoteSource::loadOffset() {
return loaderValid() ? _loader->currentOffset() : 0;
}
const StorageImageLocation &RemoteSource::location() {
return StorageImageLocation::Null;
}
void RemoteSource::refreshFileReference(const QByteArray &data) {
}
void RemoteSource::setDelayedStorageLocation(
const StorageImageLocation &location) {
}
void RemoteSource::performDelayedLoad(Data::FileOrigin origin) {
}
bool RemoteSource::isDelayedStorageImage() const {
return false;
}
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;
}
std::optional<Storage::Cache::Key> StorageSource::cacheKey() {
return _location.isNull()
? std::nullopt
: base::make_optional(Data::StorageCacheKey(_location));
}
int StorageSource::width() {
return _location.width();
}
int StorageSource::height() {
return _location.height();
}
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();
}
FileLoader *StorageSource::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
if (_location.isNull()) {
return nullptr;
}
return new mtpFileLoader(
&_location,
origin,
_size,
fromCloud,
autoLoading,
Data::kImageCacheTag);
}
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) {
}
std::optional<Storage::Cache::Key> WebCachedSource::cacheKey() {
return _location.isNull()
? std::nullopt
: base::make_optional(Data::WebDocumentCacheKey(_location));
}
int WebCachedSource::width() {
return _width;
}
int WebCachedSource::height() {
return _height;
}
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;
}
FileLoader *WebCachedSource::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
return _location.isNull()
? nullptr
: new mtpFileLoader(
&_location,
_size,
fromCloud,
autoLoading,
Data::kImageCacheTag);
}
GeoPointSource::GeoPointSource(const GeoPointLocation &location)
: _location(location) {
}
std::optional<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;
}
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();
}
FileLoader *GeoPointSource::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
return new mtpFileLoader(
&_location,
_size,
fromCloud,
autoLoading,
Data::kImageCacheTag);
}
DelayedStorageSource::DelayedStorageSource()
: StorageSource(StorageImageLocation(), 0) {
}
DelayedStorageSource::DelayedStorageSource(int w, int h)
: StorageSource(StorageImageLocation(w, h, 0, 0, 0, 0, {}), 0) {
}
void DelayedStorageSource::setDelayedStorageLocation(
const StorageImageLocation &location) {
_location = location;
}
void DelayedStorageSource::performDelayedLoad(Data::FileOrigin origin) {
if (!_loadRequested) {
return;
}
_loadRequested = false;
if (_loadCancelled) {
return;
}
if (base::take(_loadFromCloud)) {
load(origin, false, true);
} else {
loadLocal();
}
}
void DelayedStorageSource::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (_location.isNull()) {
if (!_loadCancelled && item) {
bool loadFromCloud = false;
if (item->history()->peer->isUser()) {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoPrivate);
} else {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoGroups);
}
if (_loadRequested) {
if (loadFromCloud) _loadFromCloud = loadFromCloud;
} else {
_loadFromCloud = loadFromCloud;
_loadRequested = true;
}
}
} else {
StorageSource::automaticLoad(origin, item);
}
}
void DelayedStorageSource::automaticLoadSettingsChanged() {
if (_loadCancelled) _loadCancelled = false;
StorageSource::automaticLoadSettingsChanged();
}
void DelayedStorageSource::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (_location.isNull()) {
_loadRequested = _loadFromCloud = true;
} else {
StorageSource::load(origin, loadFirst, prior);
}
}
void DelayedStorageSource::loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
_loadCancelled = false;
StorageSource::loadEvenCancelled(origin, loadFirst, prior);
}
bool DelayedStorageSource::displayLoading() {
return _location.isNull() ? true : StorageSource::displayLoading();
}
void DelayedStorageSource::cancel() {
if (_loadRequested) {
_loadRequested = false;
}
StorageSource::cancel();
}
bool DelayedStorageSource::isDelayedStorageImage() const {
return true;
}
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) {
}
std::optional<Storage::Cache::Key> WebUrlSource::cacheKey() {
return Data::UrlCacheKey(_url);
}
int WebUrlSource::width() {
return _width;
}
int WebUrlSource::height() {
return _height;
}
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;
}
FileLoader *WebUrlSource::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
return new webFileLoader(
_url,
QString(),
fromCloud,
autoLoading,
Data::kImageCacheTag);
}
} // namespace Images
Image::Image(std::unique_ptr<Images::Source> &&source)
@ -1405,7 +699,7 @@ QPixmap Image::pixNoCache(
return App::pixmapFromImageInPlace(std::move(result));
}
return Images::pixmap(_data, w, h, options, outerw, outerh, colored);
return App::pixmapFromImageInPlace(Images::prepare(_data, w, h, options, outerw, outerh, colored));
}
QPixmap Image::pixColoredNoCache(

View File

@ -0,0 +1,249 @@
/*
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_prepare.h"
class HistoryItem;
namespace Images {
void ClearRemote();
void ClearAll();
void CheckCacheSize();
ImagePtr Create(const QString &file, QByteArray format);
ImagePtr Create(const QString &url, QSize box);
ImagePtr Create(const QString &url, int width, int height);
ImagePtr Create(const QByteArray &filecontent, QByteArray format);
ImagePtr Create(QImage &&data, QByteArray format);
ImagePtr Create(
const QByteArray &filecontent,
QByteArray format,
QImage &&data);
ImagePtr Create(int width, int height);
ImagePtr Create(const StorageImageLocation &location, int size = 0);
ImagePtr Create( // photoCachedSize
const StorageImageLocation &location,
const QByteArray &bytes);
ImagePtr Create(const MTPWebDocument &location);
ImagePtr Create(const MTPWebDocument &location, QSize box);
ImagePtr Create(
const WebFileLocation &location,
int width,
int height,
int size = 0);
ImagePtr Create(
const WebFileLocation &location,
QSize box,
int size = 0);
ImagePtr Create(const GeoPointLocation &location);
class Source {
public:
virtual void load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) = 0;
virtual void loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) = 0;
virtual QImage takeLoaded() = 0;
virtual void forget() = 0;
virtual void automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) = 0;
virtual void automaticLoadSettingsChanged() = 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 std::optional<Storage::Cache::Key> cacheKey() = 0;
virtual void setDelayedStorageLocation(
const StorageImageLocation &location) = 0;
virtual void performDelayedLoad(Data::FileOrigin origin) = 0;
virtual bool isDelayedStorageImage() const = 0;
virtual void setImageBytes(const QByteArray &bytes) = 0;
virtual int width() = 0;
virtual int height() = 0;
virtual void setInformation(int size, int width, int height) = 0;
virtual QByteArray bytesForCache() = 0;
virtual ~Source() = default;
};
} // namespace Images
class Image final {
public:
explicit Image(std::unique_ptr<Images::Source> &&source);
void replaceSource(std::unique_ptr<Images::Source> &&source);
static ImagePtr Blank();
const QPixmap &pix(
Data::FileOrigin origin,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixRounded(
Data::FileOrigin origin,
int32 w = 0,
int32 h = 0,
ImageRoundRadius radius = ImageRoundRadius::None,
RectParts corners = RectPart::AllCorners) const;
const QPixmap &pixBlurred(
Data::FileOrigin origin,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixColored(
Data::FileOrigin origin,
style::color add,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixBlurredColored(
Data::FileOrigin origin,
style::color add,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixSingle(
Data::FileOrigin origin,
int32 w,
int32 h,
int32 outerw,
int32 outerh,
ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners,
const style::color *colored = nullptr) const;
const QPixmap &pixBlurredSingle(
Data::FileOrigin origin,
int32 w,
int32 h,
int32 outerw,
int32 outerh,
ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners) const;
const QPixmap &pixCircled(
Data::FileOrigin origin,
int32 w = 0,
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 h = 0,
Images::Options options = 0,
int outerw = -1,
int outerh = -1,
const style::color *colored = nullptr) const;
QPixmap pixColoredNoCache(
Data::FileOrigin origin,
style::color add,
int32 w = 0,
int32 h = 0,
bool smooth = false) const;
QPixmap pixBlurredColoredNoCache(
Data::FileOrigin origin,
style::color add,
int32 w,
int32 h = 0) const;
void automaticLoad(Data::FileOrigin origin, const HistoryItem *item) {
if (!loaded()) {
_source->automaticLoad(origin, item);
}
}
void automaticLoadSettingsChanged() {
_source->automaticLoadSettingsChanged();
}
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();
}
int height() const {
return _source->height();
}
void setInformation(int size, int width, int height) {
_source->setInformation(size, width, height);
}
void load(
Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) {
if (!loaded()) {
_source->load(origin, loadFirst, prior);
}
}
void loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) {
if (!loaded()) {
_source->loadEvenCancelled(origin, loadFirst, prior);
}
}
const StorageImageLocation &location() const {
return _source->location();
}
void refreshFileReference(const QByteArray &data) {
_source->refreshFileReference(data);
}
std::optional<Storage::Cache::Key> cacheKey() const;
QByteArray bytesForCache() const {
return _source->bytesForCache();
}
bool isDelayedStorageImage() const {
return _source->isDelayedStorageImage();
}
bool loaded() const;
bool isNull() const;
void forget() const;
void setDelayedStorageLocation(
Data::FileOrigin origin,
const StorageImageLocation &location);
void setImageBytes(const QByteArray &bytes);
~Image();
private:
void checkSource() const;
void invalidateSizeCache() const;
std::unique_ptr<Images::Source> _source;
mutable QMap<uint64, QPixmap> _sizesCache;
mutable QImage _data;
};

View File

@ -0,0 +1,149 @@
/*
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
*/
#include "ui/image/image_location.h"
#include "ui/image/image.h"
#include "platform/platform_specific.h"
ImagePtr::ImagePtr() : _data(Image::Blank().get()) {
}
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();
}
StorageImageLocation StorageImageLocation::Null;
WebFileLocation WebFileLocation::Null;
StorageImageLocation::StorageImageLocation(
int32 width,
int32 height,
int32 dc,
const uint64 &volume,
int32 local,
const uint64 &secret,
const QByteArray &fileReference)
: _widthheight(packIntInt(width, height))
, _dclocal(packIntInt(dc, local))
, _volume(volume)
, _secret(secret)
, _fileReference(fileReference) {
}
StorageImageLocation::StorageImageLocation(
int32 width,
int32 height,
const MTPDfileLocation &location)
: StorageImageLocation(
width,
height,
location.vdc_id.v,
location.vvolume_id.v,
location.vlocal_id.v,
location.vsecret.v,
location.vfile_reference.v) {
}
ReadAccessEnabler::ReadAccessEnabler(const PsFileBookmark *bookmark)
: _bookmark(bookmark)
, _failed(_bookmark ? !_bookmark->enable() : false) {
}
ReadAccessEnabler::ReadAccessEnabler(
const std::shared_ptr<PsFileBookmark> &bookmark)
: _bookmark(bookmark.get())
, _failed(_bookmark ? !_bookmark->enable() : false) {
}
ReadAccessEnabler::~ReadAccessEnabler() {
if (_bookmark && !_failed) _bookmark->disable();
}
FileLocation::FileLocation(const QString &name) : fname(name) {
if (fname.isEmpty()) {
size = 0;
} else {
setBookmark(psPathBookmark(name));
QFileInfo f(name);
if (f.exists()) {
qint64 s = f.size();
if (s > INT_MAX) {
fname = QString();
_bookmark = nullptr;
size = 0;
} else {
modified = f.lastModified();
size = qint32(s);
}
} else {
fname = QString();
_bookmark = nullptr;
size = 0;
}
}
}
bool FileLocation::check() const {
if (fname.isEmpty()) return false;
ReadAccessEnabler enabler(_bookmark);
if (enabler.failed()) {
const_cast<FileLocation*>(this)->_bookmark = nullptr;
}
QFileInfo f(name());
if (!f.isReadable()) return false;
quint64 s = f.size();
if (s > INT_MAX) {
DEBUG_LOG(("File location check: Wrong size %1").arg(s));
return false;
}
if (qint32(s) != size) {
DEBUG_LOG(("File location check: Wrong size %1 when should be %2").arg(s).arg(size));
return false;
}
auto realModified = f.lastModified();
if (realModified != modified) {
DEBUG_LOG(("File location check: Wrong last modified time %1 when should be %2").arg(realModified.toMSecsSinceEpoch()).arg(modified.toMSecsSinceEpoch()));
return false;
}
return true;
}
const QString &FileLocation::name() const {
return _bookmark ? _bookmark->name(fname) : fname;
}
QByteArray FileLocation::bookmark() const {
return _bookmark ? _bookmark->bookmark() : QByteArray();
}
void FileLocation::setBookmark(const QByteArray &bm) {
_bookmark.reset(bm.isEmpty() ? nullptr : new PsFileBookmark(bm));
}
bool FileLocation::accessEnable() const {
return isEmpty() ? false : (_bookmark ? _bookmark->enable() : true);
}
void FileLocation::accessDisable() const {
return _bookmark ? _bookmark->disable() : (void)0;
}

View File

@ -7,71 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/flags.h"
#include "data/data_file_origin.h"
namespace Storage {
namespace Cache {
struct Key;
} // namespace Cache
} // namespace Storage
enum class ImageRoundRadius {
None,
Large,
Small,
Ellipse,
};
namespace Images {
QPixmap PixmapFast(QImage &&image);
QImage prepareBlur(QImage image);
void prepareRound(
QImage &image,
ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners,
QRect target = QRect());
void prepareRound(
QImage &image,
QImage *cornerMasks,
RectParts corners = RectPart::AllCorners,
QRect target = QRect());
void prepareCircle(QImage &image);
QImage prepareColored(style::color add, QImage image);
QImage prepareOpaque(QImage image);
enum class Option {
None = 0,
Smooth = (1 << 0),
Blurred = (1 << 1),
Circled = (1 << 2),
RoundedLarge = (1 << 3),
RoundedSmall = (1 << 4),
RoundedTopLeft = (1 << 5),
RoundedTopRight = (1 << 6),
RoundedBottomLeft = (1 << 7),
RoundedBottomRight = (1 << 8),
RoundedAll = (None
| RoundedTopLeft
| RoundedTopRight
| RoundedBottomLeft
| RoundedBottomRight),
Colored = (1 << 9),
TransparentBackground = (1 << 10),
};
using Options = base::flags<Option>;
inline constexpr auto is_flag_type(Option) { return true; };
QImage prepare(QImage img, int w, int h, Options options, int outerw, int outerh, const style::color *colored = nullptr);
inline QPixmap pixmap(QImage img, int w, int h, Options options, int outerw, int outerh, const style::color *colored = nullptr) {
return QPixmap::fromImage(prepare(img, w, h, options, outerw, outerh, colored), Qt::ColorOnly);
}
} // namespace Images
class FileLoader;
enum LoadFromCloudSetting {

View File

@ -5,17 +5,7 @@ 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
*/
#include "ui/images.h"
#include "ui/image.h"
#include "mainwidget.h"
#include "storage/localstorage.h"
#include "storage/cache/storage_cache_database.h"
#include "platform/platform_specific.h"
#include "auth_session.h"
#include "history/history_item.h"
#include "history/history.h"
#include "data/data_session.h"
#include "ui/image/image_prepare.h"
namespace Images {
namespace {
@ -366,141 +356,3 @@ QImage prepare(QImage img, int w, int h, Images::Options options, int outerw, in
}
} // namespace Images
ImagePtr::ImagePtr() : _data(Image::Blank().get()) {
}
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();
}
StorageImageLocation StorageImageLocation::Null;
WebFileLocation WebFileLocation::Null;
StorageImageLocation::StorageImageLocation(
int32 width,
int32 height,
int32 dc,
const uint64 &volume,
int32 local,
const uint64 &secret,
const QByteArray &fileReference)
: _widthheight(packIntInt(width, height))
, _dclocal(packIntInt(dc, local))
, _volume(volume)
, _secret(secret)
, _fileReference(fileReference) {
}
StorageImageLocation::StorageImageLocation(
int32 width,
int32 height,
const MTPDfileLocation &location)
: StorageImageLocation(
width,
height,
location.vdc_id.v,
location.vvolume_id.v,
location.vlocal_id.v,
location.vsecret.v,
location.vfile_reference.v) {
}
ReadAccessEnabler::ReadAccessEnabler(const PsFileBookmark *bookmark)
: _bookmark(bookmark)
, _failed(_bookmark ? !_bookmark->enable() : false) {
}
ReadAccessEnabler::ReadAccessEnabler(
const std::shared_ptr<PsFileBookmark> &bookmark)
: _bookmark(bookmark.get())
, _failed(_bookmark ? !_bookmark->enable() : false) {
}
ReadAccessEnabler::~ReadAccessEnabler() {
if (_bookmark && !_failed) _bookmark->disable();
}
FileLocation::FileLocation(const QString &name) : fname(name) {
if (fname.isEmpty()) {
size = 0;
} else {
setBookmark(psPathBookmark(name));
QFileInfo f(name);
if (f.exists()) {
qint64 s = f.size();
if (s > INT_MAX) {
fname = QString();
_bookmark = nullptr;
size = 0;
} else {
modified = f.lastModified();
size = qint32(s);
}
} else {
fname = QString();
_bookmark = nullptr;
size = 0;
}
}
}
bool FileLocation::check() const {
if (fname.isEmpty()) return false;
ReadAccessEnabler enabler(_bookmark);
if (enabler.failed()) {
const_cast<FileLocation*>(this)->_bookmark = nullptr;
}
QFileInfo f(name());
if (!f.isReadable()) return false;
quint64 s = f.size();
if (s > INT_MAX) {
DEBUG_LOG(("File location check: Wrong size %1").arg(s));
return false;
}
if (qint32(s) != size) {
DEBUG_LOG(("File location check: Wrong size %1 when should be %2").arg(s).arg(size));
return false;
}
auto realModified = f.lastModified();
if (realModified != modified) {
DEBUG_LOG(("File location check: Wrong last modified time %1 when should be %2").arg(realModified.toMSecsSinceEpoch()).arg(modified.toMSecsSinceEpoch()));
return false;
}
return true;
}
const QString &FileLocation::name() const {
return _bookmark ? _bookmark->name(fname) : fname;
}
QByteArray FileLocation::bookmark() const {
return _bookmark ? _bookmark->bookmark() : QByteArray();
}
void FileLocation::setBookmark(const QByteArray &bm) {
_bookmark.reset(bm.isEmpty() ? nullptr : new PsFileBookmark(bm));
}
bool FileLocation::accessEnable() const {
return isEmpty() ? false : (_bookmark ? _bookmark->enable() : true);
}
void FileLocation::accessDisable() const {
return _bookmark ? _bookmark->disable() : (void)0;
}

View File

@ -0,0 +1,68 @@
/*
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/flags.h"
namespace Storage {
namespace Cache {
struct Key;
} // namespace Cache
} // namespace Storage
enum class ImageRoundRadius {
None,
Large,
Small,
Ellipse,
};
namespace Images {
QPixmap PixmapFast(QImage &&image);
QImage prepareBlur(QImage image);
void prepareRound(
QImage &image,
ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners,
QRect target = QRect());
void prepareRound(
QImage &image,
QImage *cornerMasks,
RectParts corners = RectPart::AllCorners,
QRect target = QRect());
void prepareCircle(QImage &image);
QImage prepareColored(style::color add, QImage image);
QImage prepareOpaque(QImage image);
enum class Option {
None = 0,
Smooth = (1 << 0),
Blurred = (1 << 1),
Circled = (1 << 2),
RoundedLarge = (1 << 3),
RoundedSmall = (1 << 4),
RoundedTopLeft = (1 << 5),
RoundedTopRight = (1 << 6),
RoundedBottomLeft = (1 << 7),
RoundedBottomRight = (1 << 8),
RoundedAll = (None
| RoundedTopLeft
| RoundedTopRight
| RoundedBottomLeft
| RoundedBottomRight),
Colored = (1 << 9),
TransparentBackground = (1 << 10),
};
using Options = base::flags<Option>;
inline constexpr auto is_flag_type(Option) { return true; };
QImage prepare(QImage img, int w, int h, Options options, int outerw, int outerh, const style::color *colored = nullptr);
} // namespace Images

View File

@ -0,0 +1,721 @@
/*
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
*/
#include "ui/image/image_source.h"
#include "storage/file_download.h"
#include "data/data_session.h"
#include "storage/cache/storage_cache_database.h"
#include "history/history_item.h"
#include "history/history.h"
#include "auth_session.h"
namespace Images {
ImageSource::ImageSource(QImage &&data, const QByteArray &format)
: _data(std::move(data))
, _format(format) {
}
void ImageSource::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
}
void ImageSource::loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
}
QImage ImageSource::takeLoaded() {
return _data;
}
void ImageSource::forget() {
}
void ImageSource::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
}
void ImageSource::automaticLoadSettingsChanged() {
}
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::Null;
}
void ImageSource::refreshFileReference(const QByteArray &data) {
}
std::optional<Storage::Cache::Key> ImageSource::cacheKey() {
return std::nullopt;
}
void ImageSource::setDelayedStorageLocation(
const StorageImageLocation &location) {
}
void ImageSource::performDelayedLoad(Data::FileOrigin origin) {
}
bool ImageSource::isDelayedStorageImage() const {
return false;
}
void ImageSource::setImageBytes(const QByteArray &bytes) {
}
int ImageSource::width() {
return _data.width();
}
int ImageSource::height() {
return _data.height();
}
void ImageSource::setInformation(int size, int width, int 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)) {
}
void LocalFileSource::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
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,
bool loadFirst,
bool prior) {
load(origin, loadFirst, prior);
}
QImage LocalFileSource::takeLoaded() {
return std::move(_data);
}
void LocalFileSource::forget() {
_data = QImage();
}
void LocalFileSource::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
}
void LocalFileSource::automaticLoadSettingsChanged() {
}
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::Null;
}
void LocalFileSource::refreshFileReference(const QByteArray &data) {
}
std::optional<Storage::Cache::Key> LocalFileSource::cacheKey() {
return std::nullopt;
}
void LocalFileSource::setDelayedStorageLocation(
const StorageImageLocation &location) {
}
void LocalFileSource::performDelayedLoad(Data::FileOrigin origin) {
}
bool LocalFileSource::isDelayedStorageImage() const {
return false;
}
void LocalFileSource::setImageBytes(const QByteArray &bytes) {
_bytes = bytes;
load({}, false, true);
}
int LocalFileSource::width() {
ensureDimensionsKnown();
return _width;
}
int LocalFileSource::height() {
ensureDimensionsKnown();
return _height;
}
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({}, false, false);
}
}
QByteArray LocalFileSource::bytesForCache() {
ensureDimensionsKnown();
return (_bytes == "(bad)") ? QByteArray() : _bytes;
}
QImage RemoteSource::takeLoaded() {
if (!loaderValid() || !_loader->finished()) {
return QImage();
}
auto data = _loader->imageData(shrinkBox());
if (data.isNull()) {
destroyLoaderDelayed(CancelledFileLoader);
return QImage();
}
setInformation(_loader->bytes().size(), data.width(), data.height());
destroyLoaderDelayed();
return data;
}
bool RemoteSource::loaderValid() const {
return _loader && _loader != CancelledFileLoader;
}
void RemoteSource::destroyLoaderDelayed(FileLoader *newValue) {
Expects(loaderValid());
_loader->stop();
auto loader = std::unique_ptr<FileLoader>(std::exchange(_loader, newValue));
Auth().downloader().delayedDestroyLoader(std::move(loader));
}
void RemoteSource::loadLocal() {
if (loaderValid()) {
return;
}
_loader = createLoader(std::nullopt, LoadFromLocalOnly, true);
if (_loader) _loader->start();
}
void RemoteSource::setImageBytes(const QByteArray &bytes) {
if (bytes.isEmpty()) {
return;
}
_loader = createLoader({}, LoadFromLocalOnly, true);
_loader->finishWithBytes(bytes);
const auto location = this->location();
if (!location.isNull()
&& !bytes.isEmpty()
&& bytes.size() <= Storage::kMaxFileInMemory) {
Auth().data().cache().putIfEmpty(
Data::StorageCacheKey(location),
Storage::Cache::Database::TaggedValue(
base::duplicate(bytes),
Data::kImageCacheTag));
}
}
bool RemoteSource::loading() {
return loaderValid();
}
void RemoteSource::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (_loader != CancelledFileLoader && item) {
bool loadFromCloud = false;
if (item->history()->peer->isUser()) {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoPrivate);
} else {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoGroups);
}
if (_loader) {
if (loadFromCloud) _loader->permitLoadFromCloud();
} else {
_loader = createLoader(
origin,
loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly,
true);
if (_loader) _loader->start();
}
}
}
void RemoteSource::automaticLoadSettingsChanged() {
if (_loader == CancelledFileLoader) {
_loader = nullptr;
}
}
void RemoteSource::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (!_loader) {
_loader = createLoader(origin, LoadFromCloudOrLocal, false);
}
if (loaderValid()) {
_loader->start(loadFirst, prior);
}
}
void RemoteSource::loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (_loader == CancelledFileLoader) {
_loader = nullptr;
}
return load(origin, loadFirst, prior);
}
RemoteSource::~RemoteSource() {
forget();
}
bool RemoteSource::displayLoading() {
return loaderValid()
&& (!_loader->loadingLocal() || !_loader->autoLoading());
}
void RemoteSource::cancel() {
if (!loaderValid()) return;
const auto loader = std::exchange(_loader, CancelledFileLoader);
loader->cancel();
loader->stop();
Auth().downloader().delayedDestroyLoader(
std::unique_ptr<FileLoader>(loader));
}
void RemoteSource::forget() {
if (loaderValid()) {
destroyLoaderDelayed();
}
}
float64 RemoteSource::progress() {
return loaderValid() ? _loader->currentProgress() : 0.;
}
int RemoteSource::loadOffset() {
return loaderValid() ? _loader->currentOffset() : 0;
}
const StorageImageLocation &RemoteSource::location() {
return StorageImageLocation::Null;
}
void RemoteSource::refreshFileReference(const QByteArray &data) {
}
void RemoteSource::setDelayedStorageLocation(
const StorageImageLocation &location) {
}
void RemoteSource::performDelayedLoad(Data::FileOrigin origin) {
}
bool RemoteSource::isDelayedStorageImage() const {
return false;
}
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;
}
std::optional<Storage::Cache::Key> StorageSource::cacheKey() {
return _location.isNull()
? std::nullopt
: base::make_optional(Data::StorageCacheKey(_location));
}
int StorageSource::width() {
return _location.width();
}
int StorageSource::height() {
return _location.height();
}
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();
}
FileLoader *StorageSource::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
if (_location.isNull()) {
return nullptr;
}
return new mtpFileLoader(
&_location,
origin,
_size,
fromCloud,
autoLoading,
Data::kImageCacheTag);
}
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) {
}
std::optional<Storage::Cache::Key> WebCachedSource::cacheKey() {
return _location.isNull()
? std::nullopt
: base::make_optional(Data::WebDocumentCacheKey(_location));
}
int WebCachedSource::width() {
return _width;
}
int WebCachedSource::height() {
return _height;
}
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;
}
FileLoader *WebCachedSource::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
return _location.isNull()
? nullptr
: new mtpFileLoader(
&_location,
_size,
fromCloud,
autoLoading,
Data::kImageCacheTag);
}
GeoPointSource::GeoPointSource(const GeoPointLocation &location)
: _location(location) {
}
std::optional<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;
}
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();
}
FileLoader *GeoPointSource::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
return new mtpFileLoader(
&_location,
_size,
fromCloud,
autoLoading,
Data::kImageCacheTag);
}
DelayedStorageSource::DelayedStorageSource()
: StorageSource(StorageImageLocation(), 0) {
}
DelayedStorageSource::DelayedStorageSource(int w, int h)
: StorageSource(StorageImageLocation(w, h, 0, 0, 0, 0, {}), 0) {
}
void DelayedStorageSource::setDelayedStorageLocation(
const StorageImageLocation &location) {
_location = location;
}
void DelayedStorageSource::performDelayedLoad(Data::FileOrigin origin) {
if (!_loadRequested) {
return;
}
_loadRequested = false;
if (_loadCancelled) {
return;
}
if (base::take(_loadFromCloud)) {
load(origin, false, true);
} else {
loadLocal();
}
}
void DelayedStorageSource::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (_location.isNull()) {
if (!_loadCancelled && item) {
bool loadFromCloud = false;
if (item->history()->peer->isUser()) {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoPrivate);
} else {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoGroups);
}
if (_loadRequested) {
if (loadFromCloud) _loadFromCloud = loadFromCloud;
} else {
_loadFromCloud = loadFromCloud;
_loadRequested = true;
}
}
} else {
StorageSource::automaticLoad(origin, item);
}
}
void DelayedStorageSource::automaticLoadSettingsChanged() {
if (_loadCancelled) _loadCancelled = false;
StorageSource::automaticLoadSettingsChanged();
}
void DelayedStorageSource::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (_location.isNull()) {
_loadRequested = _loadFromCloud = true;
} else {
StorageSource::load(origin, loadFirst, prior);
}
}
void DelayedStorageSource::loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
_loadCancelled = false;
StorageSource::loadEvenCancelled(origin, loadFirst, prior);
}
bool DelayedStorageSource::displayLoading() {
return _location.isNull() ? true : StorageSource::displayLoading();
}
void DelayedStorageSource::cancel() {
if (_loadRequested) {
_loadRequested = false;
}
StorageSource::cancel();
}
bool DelayedStorageSource::isDelayedStorageImage() const {
return true;
}
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) {
}
std::optional<Storage::Cache::Key> WebUrlSource::cacheKey() {
return Data::UrlCacheKey(_url);
}
int WebUrlSource::width() {
return _width;
}
int WebUrlSource::height() {
return _height;
}
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;
}
FileLoader *WebUrlSource::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
return new webFileLoader(
_url,
QString(),
fromCloud,
autoLoading,
Data::kImageCacheTag);
}
} // namespace Images

View File

@ -7,82 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/image/image.h"
namespace Images {
void ClearRemote();
void ClearAll();
void CheckCacheSize();
ImagePtr Create(const QString &file, QByteArray format);
ImagePtr Create(const QString &url, QSize box);
ImagePtr Create(const QString &url, int width, int height);
ImagePtr Create(const QByteArray &filecontent, QByteArray format);
ImagePtr Create(QImage &&data, QByteArray format);
ImagePtr Create(
const QByteArray &filecontent,
QByteArray format,
QImage &&data);
ImagePtr Create(int width, int height);
ImagePtr Create(const StorageImageLocation &location, int size = 0);
ImagePtr Create( // photoCachedSize
const StorageImageLocation &location,
const QByteArray &bytes);
ImagePtr Create(const MTPWebDocument &location);
ImagePtr Create(const MTPWebDocument &location, QSize box);
ImagePtr Create(
const WebFileLocation &location,
int width,
int height,
int size = 0);
ImagePtr Create(
const WebFileLocation &location,
QSize box,
int size = 0);
ImagePtr Create(const GeoPointLocation &location);
class Source {
public:
virtual ~Source();
virtual void load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) = 0;
virtual void loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) = 0;
virtual QImage takeLoaded() = 0;
virtual void forget() = 0;
virtual void automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) = 0;
virtual void automaticLoadSettingsChanged() = 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 std::optional<Storage::Cache::Key> cacheKey() = 0;
virtual void setDelayedStorageLocation(
const StorageImageLocation &location) = 0;
virtual void performDelayedLoad(Data::FileOrigin origin) = 0;
virtual bool isDelayedStorageImage() const = 0;
virtual void setImageBytes(const QByteArray &bytes) = 0;
virtual int width() = 0;
virtual int height() = 0;
virtual void setInformation(int size, int width, int height) = 0;
virtual QByteArray bytesForCache() = 0;
};
class ImageSource : public Source {
public:
ImageSource(QImage &&data, const QByteArray &format);
@ -388,164 +316,3 @@ private:
};
} // namespace Images
class HistoryItem;
class Image final {
public:
explicit Image(std::unique_ptr<Images::Source> &&source);
void replaceSource(std::unique_ptr<Images::Source> &&source);
static ImagePtr Blank();
const QPixmap &pix(
Data::FileOrigin origin,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixRounded(
Data::FileOrigin origin,
int32 w = 0,
int32 h = 0,
ImageRoundRadius radius = ImageRoundRadius::None,
RectParts corners = RectPart::AllCorners) const;
const QPixmap &pixBlurred(
Data::FileOrigin origin,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixColored(
Data::FileOrigin origin,
style::color add,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixBlurredColored(
Data::FileOrigin origin,
style::color add,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixSingle(
Data::FileOrigin origin,
int32 w,
int32 h,
int32 outerw,
int32 outerh,
ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners,
const style::color *colored = nullptr) const;
const QPixmap &pixBlurredSingle(
Data::FileOrigin origin,
int32 w,
int32 h,
int32 outerw,
int32 outerh,
ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners) const;
const QPixmap &pixCircled(
Data::FileOrigin origin,
int32 w = 0,
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 h = 0,
Images::Options options = 0,
int outerw = -1,
int outerh = -1,
const style::color *colored = nullptr) const;
QPixmap pixColoredNoCache(
Data::FileOrigin origin,
style::color add,
int32 w = 0,
int32 h = 0,
bool smooth = false) const;
QPixmap pixBlurredColoredNoCache(
Data::FileOrigin origin,
style::color add,
int32 w,
int32 h = 0) const;
void automaticLoad(Data::FileOrigin origin, const HistoryItem *item) {
if (!loaded()) {
_source->automaticLoad(origin, item);
}
}
void automaticLoadSettingsChanged() {
_source->automaticLoadSettingsChanged();
}
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();
}
int height() const {
return _source->height();
}
void setInformation(int size, int width, int height) {
_source->setInformation(size, width, height);
}
void load(
Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) {
if (!loaded()) {
_source->load(origin, loadFirst, prior);
}
}
void loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) {
if (!loaded()) {
_source->loadEvenCancelled(origin, loadFirst, prior);
}
}
const StorageImageLocation &location() const {
return _source->location();
}
void refreshFileReference(const QByteArray &data) {
_source->refreshFileReference(data);
}
std::optional<Storage::Cache::Key> cacheKey() const;
QByteArray bytesForCache() const {
return _source->bytesForCache();
}
bool isDelayedStorageImage() const {
return _source->isDelayedStorageImage();
}
bool loaded() const;
bool isNull() const;
void forget() const;
void setDelayedStorageLocation(
Data::FileOrigin origin,
const StorageImageLocation &location);
void setImageBytes(const QByteArray &bytes);
~Image();
private:
void checkSource() const;
void invalidateSizeCache() const;
std::unique_ptr<Images::Source> _source;
mutable QMap<uint64, QPixmap> _sizesCache;
mutable QImage _data;
};

View File

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/dialogs_layout.h"
#include "ui/effects/ripple_animation.h"
#include "ui/effects/radial_animation.h"
#include "ui/image/image_prepare.h"
#include "ui/empty_userpic.h"
#include "data/data_photo.h"
#include "data/data_session.h"

View File

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/toast/toast_widget.h"
#include "ui/image/image_prepare.h"
namespace Ui {
namespace Toast {
namespace internal {

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/ripple_animation.h"
#include "ui/effects/cross_animation.h"
#include "ui/effects/numbers_animation.h"
#include "ui/image/image_prepare.h"
#include "lang/lang_instance.h"
namespace Ui {

View File

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/shadow.h"
#include "ui/effects/panel_animation.h"
#include "ui/image/image_prepare.h"
namespace {

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/popup_menu.h"
#include "ui/widgets/shadow.h"
#include "ui/image/image_prepare.h"
#include "platform/platform_specific.h"
#include "application.h"
#include "mainwindow.h"

View File

@ -20,8 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_widgets.h"
#include "styles/style_chat_helpers.h"
#include "ui/widgets/shadow.h"
#include "ui/image/image.h"
#include "ui/emoji_config.h"
#include "ui/image.h"
#include "window/window_main_menu.h"
#include "auth_session.h"
#include "chat_helpers/stickers.h"

View File

@ -21,9 +21,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/multi_select.h"
#include "ui/image/image_prepare.h"
#include "ui/toast/toast.h"
#include "base/parse_helper.h"
#include "base/zlib_help.h"
#include "ui/toast/toast.h"
#include "core/file_utilities.h"
#include "boxes/edit_color_box.h"
#include "lang/lang_keys.h"

View File

@ -8,10 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/themes/window_theme_preview.h"
#include "window/themes/window_theme.h"
#include "ui/emoji_config.h"
#include "lang/lang_keys.h"
#include "platform/platform_window_title.h"
#include "ui/text_options.h"
#include "ui/image/image_prepare.h"
#include "ui/emoji_config.h"
#include "styles/style_widgets.h"
#include "styles/style_window.h"
#include "styles/style_mediaview.h"

View File

@ -598,6 +598,14 @@
<(src_loc)/ui/effects/send_action_animations.h
<(src_loc)/ui/effects/slide_animation.cpp
<(src_loc)/ui/effects/slide_animation.h
<(src_loc)/ui/image/image.cpp
<(src_loc)/ui/image/image.h
<(src_loc)/ui/image/image_location.cpp
<(src_loc)/ui/image/image_location.h
<(src_loc)/ui/image/image_prepare.cpp
<(src_loc)/ui/image/image_prepare.h
<(src_loc)/ui/image/image_source.cpp
<(src_loc)/ui/image/image_source.h
<(src_loc)/ui/style/style_core.cpp
<(src_loc)/ui/style/style_core.h
<(src_loc)/ui/style/style_core_color.cpp
@ -672,10 +680,6 @@
<(src_loc)/ui/focus_persister.h
<(src_loc)/ui/grouped_layout.cpp
<(src_loc)/ui/grouped_layout.h
<(src_loc)/ui/image.cpp
<(src_loc)/ui/image.h
<(src_loc)/ui/images.cpp
<(src_loc)/ui/images.h
<(src_loc)/ui/resize_area.h
<(src_loc)/ui/rp_widget.cpp
<(src_loc)/ui/rp_widget.h