diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index ce1adc8a6..9e2982dd7 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -451,7 +451,8 @@ void EditCaptionBox::setupPhotoEditorEventHandler() { &file.information->media); image->modifications = mods; - Storage::UpdateImageDetails(file, previewWidth); + const auto sideLimit = PhotoSideLimit(); + Storage::UpdateImageDetails(file, previewWidth, sideLimit); rebuildPreview(); }; const auto fileImage = std::make_shared(*large); diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 83858a27e..957b3560c 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -348,8 +348,9 @@ void SendFilesBox::enqueueNextPrepare() { _list.filesToProcess.pop_front(); const auto weak = Ui::MakeWeak(this); _preparing = true; - crl::async([weak, file = std::move(file)]() mutable { - Storage::PrepareDetails(file, st::sendMediaPreviewSize); + const auto sideLimit = PhotoSideLimit(); // Get on main thread. + crl::async([weak, sideLimit, file = std::move(file)]() mutable { + Storage::PrepareDetails(file, st::sendMediaPreviewSize, sideLimit); crl::on_main([weak, file = std::move(file)]() mutable { if (weak) { weak->addPreparedAsyncFile(std::move(file)); diff --git a/Telegram/SourceFiles/data/data_photo.cpp b/Telegram/SourceFiles/data/data_photo.cpp index a091f5bee..963162fcf 100644 --- a/Telegram/SourceFiles/data/data_photo.cpp +++ b/Telegram/SourceFiles/data/data_photo.cpp @@ -23,7 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace { -constexpr auto kPhotoSideLimit = 1280; +constexpr auto kPhotoSideLimit = 2560; using Data::PhotoMedia; using Data::PhotoSize; diff --git a/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp b/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp index d8564fdb9..8090d0d57 100644 --- a/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp +++ b/Telegram/SourceFiles/editor/photo_editor_layer_widget.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/boxes/confirm_box.h" // InformBox #include "editor/editor_layer_widget.h" #include "editor/photo_editor.h" +#include "storage/localimageloader.h" #include "storage/storage_media_prepare.h" #include "ui/chat/attach/attach_prepare.h" #include "window/window_controller.h" @@ -42,10 +43,11 @@ void OpenWithPreparedFile( return; } + const auto sideLimit = PhotoSideLimit(); auto callback = [=, done = std::move(doneCallback)]( const PhotoModifications &mods) { image->modifications = mods; - Storage::UpdateImageDetails(*file, previewWidth); + Storage::UpdateImageDetails(*file, previewWidth, sideLimit); { using namespace Ui; const auto size = file->preview.size(); diff --git a/Telegram/SourceFiles/settings/settings_experimental.cpp b/Telegram/SourceFiles/settings/settings_experimental.cpp index 036173d44..d0dbbaa09 100644 --- a/Telegram/SourceFiles/settings/settings_experimental.cpp +++ b/Telegram/SourceFiles/settings/settings_experimental.cpp @@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "window/window_controller.h" #include "settings/settings_common.h" +#include "storage/localimageloader.h" #include "styles/style_settings.h" #include "styles/style_layers.h" @@ -142,6 +143,7 @@ void SetupExperimental( addToggle(Ui::GL::kOptionAllowLinuxNvidiaOpenGL); addToggle(Ui::kOptionUseSmallMsgBubbleRadius); addToggle(Media::Player::kOptionDisableAutoplayNext); + addToggle(kOptionSendLargePhotos); addToggle(Settings::kOptionMonoSettingsIcons); addToggle(Webview::kOptionWebviewDebugEnabled); addToggle(kOptionAutoScrollInactiveChat); diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index b48ad1195..9ef459abc 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "core/file_utilities.h" #include "core/mime_type.h" +#include "base/options.h" #include "base/unixtime.h" #include "base/random.h" #include "editor/scene/scene_item_sticker.h" @@ -49,6 +50,13 @@ constexpr auto kRecompressAfterBpp = 4; using Ui::ValidateThumbDimensions; +base::options::toggle SendLargePhotos({ + .id = kOptionSendLargePhotos, + .name = "Send large photos", + .description = "Increase the side limit on compressed images to 2560px.", +}); +std::atomic SendLargePhotosAtomic/* = false*/; + struct PreparedFileThumbnail { uint64 id = 0; QString name; @@ -191,8 +199,22 @@ struct PreparedFileThumbnail { return result; } +[[nodiscard]] int PhotoSideLimit(bool large) { + return large ? 2560 : 1280; +} + +[[nodiscard]] int PhotoSideLimitAtomic() { + return PhotoSideLimit(SendLargePhotosAtomic.load()); +} + } // namespace +const char kOptionSendLargePhotos[] = "send-large-photos"; + +int PhotoSideLimit() { + return PhotoSideLimit(SendLargePhotos.value()); +} + SendMediaPrepare::SendMediaPrepare( const QString &file, const PeerId &peer, @@ -518,7 +540,6 @@ void FileLoadResult::setThumbData(const QByteArray &thumbdata) { } } - FileLoadTask::FileLoadTask( not_null session, const QString &filepath, @@ -543,6 +564,8 @@ FileLoadTask::FileLoadTask( Expects(to.options.scheduled || !to.replaceMediaOf || IsServerMsgId(to.replaceMediaOf)); + + SendLargePhotosAtomic = SendLargePhotos.value(); } FileLoadTask::FileLoadTask( @@ -942,8 +965,9 @@ void FileLoadTask::process(Args &&args) { } auto medium = (w > 320 || h > 320) ? fullimage.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation) : fullimage; - const auto downscaled = (w > 1280 || h > 1280); - auto full = downscaled ? fullimage.scaled(1280, 1280, Qt::KeepAspectRatio, Qt::SmoothTransformation) : fullimage; + const auto limit = PhotoSideLimitAtomic(); + const auto downscaled = (w > limit || h > limit); + auto full = downscaled ? fullimage.scaled(limit, limit, Qt::KeepAspectRatio, Qt::SmoothTransformation) : fullimage; if (downscaled) { fullimagebytes = fullimageformat = QByteArray(); } diff --git a/Telegram/SourceFiles/storage/localimageloader.h b/Telegram/SourceFiles/storage/localimageloader.h index 365ea8112..59e3c1325 100644 --- a/Telegram/SourceFiles/storage/localimageloader.h +++ b/Telegram/SourceFiles/storage/localimageloader.h @@ -24,6 +24,10 @@ constexpr auto kFileSizeLimit = 2'000 * int64(1024 * 1024); // Load files up to 4'000 MB. constexpr auto kFileSizePremiumLimit = 4'000 * int64(1024 * 1024); +extern const char kOptionSendLargePhotos[]; + +[[nodiscard]] int PhotoSideLimit(); + enum class SendMediaType { Photo, Audio, diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.cpp b/Telegram/SourceFiles/storage/storage_media_prepare.cpp index 029461105..a79d3d293 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.cpp +++ b/Telegram/SourceFiles/storage/storage_media_prepare.cpp @@ -47,13 +47,10 @@ bool ValidVideoForAlbum(const PreparedFileInformation::Video &video) { return Ui::ValidateThumbDimensions(width, height); } -QSize PrepareShownDimensions(const QImage &preview) { - constexpr auto kMaxWidth = 1280; - constexpr auto kMaxHeight = 1280; - +QSize PrepareShownDimensions(const QImage &preview, int sideLimit) { const auto result = preview.size(); - return (result.width() > kMaxWidth || result.height() > kMaxHeight) - ? result.scaled(kMaxWidth, kMaxHeight, Qt::KeepAspectRatio) + return (result.width() > sideLimit || result.height() > sideLimit) + ? result.scaled(sideLimit, sideLimit, Qt::KeepAspectRatio) : result; } @@ -63,10 +60,11 @@ void PrepareDetailsInParallel(PreparedList &result, int previewWidth) { if (result.files.empty()) { return; } + const auto sideLimit = PhotoSideLimit(); // Get on main thread. QSemaphore semaphore; for (auto &file : result.files) { crl::async([=, &semaphore, &file] { - PrepareDetails(file, previewWidth); + PrepareDetails(file, previewWidth, sideLimit); semaphore.release(); }); } @@ -272,7 +270,7 @@ std::optional PreparedFileFromFilesDialog( } } -void PrepareDetails(PreparedFile &file, int previewWidth) { +void PrepareDetails(PreparedFile &file, int previewWidth, int sideLimit) { if (!file.path.isEmpty()) { file.information = FileLoadTask::ReadMediaInformation( file.path, @@ -293,7 +291,7 @@ void PrepareDetails(PreparedFile &file, int previewWidth) { &file.information->media)) { Assert(!image->data.isNull()); if (ValidPhotoForAlbum(*image, file.information->filemime)) { - UpdateImageDetails(file, previewWidth); + UpdateImageDetails(file, previewWidth, sideLimit); file.type = PreparedFile::Type::Photo; } else if (image->animated) { file.type = PreparedFile::Type::None; @@ -303,7 +301,10 @@ void PrepareDetails(PreparedFile &file, int previewWidth) { if (ValidVideoForAlbum(*video)) { auto blurred = Images::Blur( Images::Opaque(base::duplicate(video->thumbnail))); - file.shownDimensions = PrepareShownDimensions(video->thumbnail); + file.originalDimensions = video->thumbnail.size(); + file.shownDimensions = PrepareShownDimensions( + video->thumbnail, + sideLimit); file.preview = std::move(blurred).scaledToWidth( previewWidth * cIntRetinaFactor(), Qt::SmoothTransformation); @@ -316,7 +317,10 @@ void PrepareDetails(PreparedFile &file, int previewWidth) { } } -void UpdateImageDetails(PreparedFile &file, int previewWidth) { +void UpdateImageDetails( + PreparedFile &file, + int previewWidth, + int sideLimit) { const auto image = std::get_if(&file.information->media); if (!image) { return; @@ -326,7 +330,8 @@ void UpdateImageDetails(PreparedFile &file, int previewWidth) { ? Editor::ImageModified(image->data, image->modifications) : image->data; Assert(!preview.isNull()); - file.shownDimensions = PrepareShownDimensions(preview); + file.originalDimensions = preview.size(); + file.shownDimensions = PrepareShownDimensions(preview, sideLimit); const auto toWidth = std::min( previewWidth, style::ConvertScale(preview.width()) diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.h b/Telegram/SourceFiles/storage/storage_media_prepare.h index 5b7d6c456..f8e1e8006 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.h +++ b/Telegram/SourceFiles/storage/storage_media_prepare.h @@ -51,8 +51,11 @@ enum class MimeDataState { QImage &&image, QByteArray &&content, int previewWidth); -void PrepareDetails(Ui::PreparedFile &file, int previewWidth); -void UpdateImageDetails(Ui::PreparedFile &file, int previewWidth); +void PrepareDetails(Ui::PreparedFile &file, int previewWidth, int sideLimit); +void UpdateImageDetails( + Ui::PreparedFile &file, + int previewWidth, + int sideLimit); bool ApplyModifications(Ui::PreparedList &list); diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp index 05fdf503f..c4469f8b8 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp @@ -81,8 +81,7 @@ AlbumThumbnail::AlbumThumbnail( const auto filepath = file.path; if (filepath.isEmpty()) { _name = "image.png"; - _status = FormatImageSizeText(_fullPreview.size() - / _fullPreview.devicePixelRatio()); + _status = FormatImageSizeText(file.originalDimensions); } else { auto fileinfo = QFileInfo(filepath); _name = fileinfo.fileName(); diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.cpp index 63d76c07f..7973f0589 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.cpp @@ -103,7 +103,6 @@ void ItemSingleFilePreview::preparePreview(not_null document) { data.name = Text::FormatSongName(filename, songTitle, songPerformer) .string(); - data.statusText = FormatSizeText(document->size); } else { data.name = document->filename(); } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h index 8d4ee6929..ba1b35765 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h @@ -80,6 +80,7 @@ struct PreparedFile { std::unique_ptr information; QImage preview; QSize shownDimensions; + QSize originalDimensions; Type type = Type::File; bool spoiler = false; }; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp index aeda46467..afce50d72 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp @@ -41,8 +41,7 @@ void SingleFilePreview::preparePreview(const PreparedFile &file) { if (filepath.isEmpty()) { auto filename = "image.png"; data.name = filename; - data.statusText = FormatImageSizeText(preview.size() - / preview.devicePixelRatio()); + data.statusText = FormatImageSizeText(file.originalDimensions); data.fileIsImage = true; } else { auto fileinfo = QFileInfo(filepath);