From 4d9464ed87c15396a281894994763c57f9819f26 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 4 Feb 2019 18:53:00 +0300 Subject: [PATCH] Remove flags checking for backgrounds. Also limit image size to 2960px. Fixes #5641. --- Telegram/SourceFiles/boxes/background_box.cpp | 9 ++- Telegram/SourceFiles/data/data_document.cpp | 5 ++ Telegram/SourceFiles/data/data_document.h | 1 + Telegram/SourceFiles/mainwidget.cpp | 9 ++- .../window/themes/window_theme.cpp | 57 +++++++++---------- .../SourceFiles/window/themes/window_theme.h | 1 + 6 files changed, 46 insertions(+), 36 deletions(-) diff --git a/Telegram/SourceFiles/boxes/background_box.cpp b/Telegram/SourceFiles/boxes/background_box.cpp index e46471e279..6b5971b555 100644 --- a/Telegram/SourceFiles/boxes/background_box.cpp +++ b/Telegram/SourceFiles/boxes/background_box.cpp @@ -573,8 +573,7 @@ void BackgroundPreviewBox::checkLoadedDocument() { || _generating) { return; } - _generating = Data::ReadImageAsync(document, [=]( - QImage &&image) mutable { + const auto generateCallback = [=](QImage &&image) { auto [left, right] = base::make_binary_guard(); _generating = std::move(left); crl::async([ @@ -598,7 +597,11 @@ void BackgroundPreviewBox::checkLoadedDocument() { update(); }); }); - }); + }; + _generating = Data::ReadImageAsync( + document, + Window::Theme::ProcessBackgroundImage, + generateCallback); } bool BackgroundPreviewBox::Start( diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 67bc9a7f5e..356c552c81 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -1597,11 +1597,13 @@ vst vstm vstx vsw vsx vtx website ws wsc wsf wsh xbap xll xnk"); base::binary_guard ReadImageAsync( not_null document, + FnMut postprocess, FnMut done) { auto [left, right] = base::make_binary_guard(); crl::async([ bytes = document->data(), path = document->filepath(), + postprocess = std::move(postprocess), guard = std::move(left), callback = std::move(done) ]() mutable { @@ -1616,6 +1618,9 @@ base::binary_guard ReadImageAsync( auto image = bytes.isEmpty() ? QImage() : App::readImage(bytes, &format, false, nullptr); + if (postprocess) { + image = postprocess(std::move(image)); + } crl::on_main([ guard = std::move(guard), image = std::move(image), diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index 69995e8d82..41ede516ec 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -378,6 +378,7 @@ bool IsValidMediaFile(const QString &filepath); bool IsExecutableName(const QString &filepath); base::binary_guard ReadImageAsync( not_null document, + FnMut postprocess, FnMut done); } // namespace Data diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 52039f9b60..be4ebf6c32 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1629,14 +1629,17 @@ void MainWidget::checkChatBackground() { return; } - _background->generating = Data::ReadImageAsync(document, [=]( - QImage &&image) { + const auto generateCallback = [=](QImage &&image) { const auto background = base::take(_background); const auto ready = image.isNull() ? Data::DefaultWallPaper() : background->data; setReadyChatBackground(ready, std::move(image)); - }); + }; + _background->generating = Data::ReadImageAsync( + document, + Window::Theme::ProcessBackgroundImage, + generateCallback); } Image *MainWidget::newBackgroundThumb() { diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp index 088ea91d86..6f76102170 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme.cpp @@ -38,26 +38,6 @@ constexpr auto kCustomBackground = FromLegacyBackgroundId(-1); constexpr auto kLegacy1DefaultBackground = FromLegacyBackgroundId(0); constexpr auto kDefaultBackground = FromLegacyBackgroundId(105); -[[nodiscard]] bool ValidateFlags(MTPDwallPaper::Flags flags) { - using Flag = MTPDwallPaper::Flag; - const auto all = Flag(0) - | Flag::f_creator - | Flag::f_default - | Flag::f_pattern - | Flag::f_settings; - return !(flags & ~all); -} - -[[nodiscard]] bool ValidateFlags(MTPDwallPaperSettings::Flags flags) { - using Flag = MTPDwallPaperSettings::Flag; - const auto all = Flag(0) - | Flag::f_background_color - | Flag::f_blur - | Flag::f_intensity - | Flag::f_motion; - return !(flags & ~all); -} - quint32 SerializeMaybeColor(std::optional color) { return color ? ((quint32(std::clamp(color->red(), 0, 255)) << 16) @@ -351,9 +331,6 @@ std::optional WallPaper::FromSerialized( result._settings = MTPDwallPaperSettings::Flags::from_raw(settings); result._backgroundColor = MaybeColorFromSerialized(backgroundColor); result._intensity = intensity; - if (!ValidateFlags(result._flags) || !ValidateFlags(result._settings)) { - return std::nullopt; - } return result; } @@ -367,9 +344,6 @@ std::optional WallPaper::FromLegacySerialized( result._flags = MTPDwallPaper::Flags::from_raw(flags); result._slug = slug; result._backgroundColor = ColorFromString(slug); - if (!ValidateFlags(result._flags)) { - return std::nullopt; - } return result; } @@ -897,10 +871,7 @@ void ChatBackground::start() { } void ChatBackground::set(const Data::WallPaper &paper, QImage image) { - if (image.format() != QImage::Format_ARGB32_Premultiplied) { - image = std::move(image).convertToFormat( - QImage::Format_ARGB32_Premultiplied); - } + image = ProcessBackgroundImage(std::move(image)); const auto needResetAdjustable = Data::IsDefaultWallPaper(paper) && !Data::IsDefaultWallPaper(_paper) @@ -1578,6 +1549,32 @@ QColor AdjustedColor(QColor original, QColor background) { ).toRgb(); } +QImage ProcessBackgroundImage(QImage image) { + constexpr auto kMaxSize = 2960; + + if (image.format() != QImage::Format_ARGB32_Premultiplied) { + image = std::move(image).convertToFormat( + QImage::Format_ARGB32_Premultiplied); + } + if (image.width() > 40 * image.height()) { + const auto width = 40 * image.height(); + const auto height = image.height(); + image = image.copy((image.width() - width) / 2, 0, width, height); + } else if (image.height() > 40 * image.width()) { + const auto width = image.width(); + const auto height = 40 * image.width(); + image = image.copy(0, (image.height() - height) / 2, width, height); + } + if (image.width() > kMaxSize || image.height() > kMaxSize) { + image = image.scaled( + kMaxSize, + kMaxSize, + Qt::KeepAspectRatio, + Qt::SmoothTransformation); + } + return image; +} + void ComputeBackgroundRects(QRect wholeFill, QSize imageSize, QRect &to, QRect &from) { if (uint64(imageSize.width()) * wholeFill.height() > uint64(imageSize.height()) * wholeFill.width()) { float64 pxsize = wholeFill.height() / float64(imageSize.height()); diff --git a/Telegram/SourceFiles/window/themes/window_theme.h b/Telegram/SourceFiles/window/themes/window_theme.h index e8c5559488..6e965f7458 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.h +++ b/Telegram/SourceFiles/window/themes/window_theme.h @@ -155,6 +155,7 @@ bool LoadFromFile(const QString &file, Instance *out, QByteArray *outContent); bool IsPaletteTestingPath(const QString &path); QColor CountAverageColor(const QImage &image); QColor AdjustedColor(QColor original, QColor background); +QImage ProcessBackgroundImage(QImage image); struct BackgroundUpdate { enum class Type {