diff --git a/td/telegram/DocumentsManager.cpp b/td/telegram/DocumentsManager.cpp index 21becb10..0501830d 100644 --- a/td/telegram/DocumentsManager.cpp +++ b/td/telegram/DocumentsManager.cpp @@ -135,7 +135,7 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo FileType file_type = FileType::Document; Slice default_extension; bool supports_streaming = false; - bool has_webp_thumbnail = false; + PhotoFormat thumbnail_format = PhotoFormat::Jpeg; if (type_attributes == 1 || default_document_type != Document::Type::General) { // not a general document if (animated != nullptr || default_document_type == Document::Type::Animation) { document_type = Document::Type::Animation; @@ -163,7 +163,9 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo default_extension = Slice("webp"); owner_dialog_id = DialogId(); file_name.clear(); - has_webp_thumbnail = td_->stickers_manager_->has_webp_thumbnail(sticker); + if (td_->stickers_manager_->has_webp_thumbnail(sticker) && remote_document.secret_file == nullptr) { + thumbnail_format = PhotoFormat::Webp; + } } else if (video != nullptr || default_document_type == Document::Type::Video || default_document_type == Document::Type::VideoNote) { bool is_video_note = default_document_type == Document::Type::VideoNote; @@ -190,7 +192,6 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo << ", has_stickers = " << has_stickers; } - bool has_png_thumbnail = false; if (is_background) { if (document_type != Document::Type::General) { LOG(ERROR) << "Receive background of type " << document_type; @@ -199,7 +200,7 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo file_type = FileType::Background; if (is_pattern) { default_extension = Slice("png"); - has_png_thumbnail = true; + thumbnail_format = PhotoFormat::Png; } else { default_extension = Slice("jpg"); } @@ -258,9 +259,9 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo if (document_type != Document::Type::VoiceNote) { for (auto &thumb : document->thumbs_) { - auto photo_size = get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, id, access_hash, - file_reference, DcId::create(dc_id), owner_dialog_id, std::move(thumb), - has_webp_thumbnail, has_png_thumbnail); + auto photo_size = + get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, id, access_hash, file_reference, + DcId::create(dc_id), owner_dialog_id, std::move(thumb), thumbnail_format); if (photo_size.get_offset() == 0) { thumbnail = std::move(photo_size.get<0>()); } else { diff --git a/td/telegram/Photo.cpp b/td/telegram/Photo.cpp index 6a5dc6d1..be62eca7 100644 --- a/td/telegram/Photo.cpp +++ b/td/telegram/Photo.cpp @@ -95,18 +95,32 @@ td_api::object_ptr get_minithumbnail_object(const string return nullptr; } +static StringBuilder &operator<<(StringBuilder &string_builder, PhotoFormat format) { + switch (format) { + case PhotoFormat::Jpeg: + return string_builder << "jpg"; + case PhotoFormat::Png: + return string_builder << "png"; + case PhotoFormat::Webp: + return string_builder << "webp"; + case PhotoFormat::Tgs: + return string_builder << "tgs"; + default: + UNREACHABLE(); + return string_builder; + } +} + static FileId register_photo(FileManager *file_manager, const PhotoSizeSource &source, int64 id, int64 access_hash, std::string file_reference, tl_object_ptr &&location, - DialogId owner_dialog_id, int32 file_size, DcId dc_id, bool is_webp = false, - bool is_png = false) { + DialogId owner_dialog_id, int32 file_size, DcId dc_id, PhotoFormat format) { int32 local_id = location->local_id_; int64 volume_id = location->volume_id_; - LOG(DEBUG) << "Receive " << (is_webp ? "webp" : (is_png ? "png" : "jpeg")) << " photo of type " - << source.get_file_type() << " in [" << dc_id << "," << volume_id << "," << local_id << "]. Id: (" << id - << ", " << access_hash << ")"; - auto suggested_name = PSTRING() << static_cast(volume_id) << "_" << static_cast(local_id) - << (is_webp ? ".webp" : (is_png ? ".png" : ".jpg")); + LOG(DEBUG) << "Receive " << format << " photo of type " << source.get_file_type() << " in [" << dc_id << "," + << volume_id << "," << local_id << "]. Id: (" << id << ", " << access_hash << ")"; + auto suggested_name = PSTRING() << static_cast(volume_id) << "_" << static_cast(local_id) << '.' + << format; auto file_location_source = owner_dialog_id.get_type() == DialogType::SecretChat ? FileLocationSource::FromUser : FileLocationSource::FromServer; return file_manager->register_remote( @@ -127,10 +141,12 @@ ProfilePhoto get_profile_photo(FileManager *file_manager, UserId user_id, int64 auto dc_id = DcId::create(profile_photo->dc_id_); result.id = profile_photo->photo_id_; - result.small_file_id = register_photo(file_manager, {DialogId(user_id), user_access_hash, false}, result.id, 0, - "", std::move(profile_photo->photo_small_), DialogId(), 0, dc_id); - result.big_file_id = register_photo(file_manager, {DialogId(user_id), user_access_hash, true}, result.id, 0, "", - std::move(profile_photo->photo_big_), DialogId(), 0, dc_id); + result.small_file_id = + register_photo(file_manager, {DialogId(user_id), user_access_hash, false}, result.id, 0, "", + std::move(profile_photo->photo_small_), DialogId(), 0, dc_id, PhotoFormat::Jpeg); + result.big_file_id = + register_photo(file_manager, {DialogId(user_id), user_access_hash, true}, result.id, 0, "", + std::move(profile_photo->photo_big_), DialogId(), 0, dc_id, PhotoFormat::Jpeg); break; } default: @@ -190,10 +206,11 @@ DialogPhoto get_dialog_photo(FileManager *file_manager, DialogId dialog_id, int6 auto chat_photo = move_tl_object_as(chat_photo_ptr); auto dc_id = DcId::create(chat_photo->dc_id_); - result.small_file_id = register_photo(file_manager, {dialog_id, dialog_access_hash, false}, 0, 0, "", - std::move(chat_photo->photo_small_), DialogId(), 0, dc_id); + result.small_file_id = + register_photo(file_manager, {dialog_id, dialog_access_hash, false}, 0, 0, "", + std::move(chat_photo->photo_small_), DialogId(), 0, dc_id, PhotoFormat::Jpeg); result.big_file_id = register_photo(file_manager, {dialog_id, dialog_access_hash, true}, 0, 0, "", - std::move(chat_photo->photo_big_), DialogId(), 0, dc_id); + std::move(chat_photo->photo_big_), DialogId(), 0, dc_id, PhotoFormat::Jpeg); break; } @@ -283,7 +300,7 @@ PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice Variant get_photo_size(FileManager *file_manager, PhotoSizeSource source, int64 id, int64 access_hash, std::string file_reference, DcId dc_id, DialogId owner_dialog_id, tl_object_ptr &&size_ptr, - bool is_webp, bool is_png) { + PhotoFormat format) { CHECK(size_ptr != nullptr); tl_object_ptr location; @@ -336,7 +353,7 @@ Variant get_photo_size(FileManager *file_manager, PhotoSizeSo } res.file_id = register_photo(file_manager, source, id, access_hash, file_reference, std::move(location), - owner_dialog_id, res.size, dc_id, is_webp, is_png); + owner_dialog_id, res.size, dc_id, format); if (!content.empty()) { file_manager->set_content(res.file_id, std::move(content)); @@ -535,7 +552,7 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr && for (auto &size_ptr : photo->sizes_) { auto photo_size = get_photo_size(file_manager, {FileType::Photo, 0}, photo->id_, photo->access_hash_, photo->file_reference_.as_slice().str(), DcId::create(photo->dc_id_), - owner_dialog_id, std::move(size_ptr), false, false); + owner_dialog_id, std::move(size_ptr), PhotoFormat::Jpeg); if (photo_size.get_offset() == 0) { PhotoSize &size = photo_size.get<0>(); if (size.type == 0 || size.type == 't' || size.type == 'i') { diff --git a/td/telegram/Photo.h b/td/telegram/Photo.h index f4c66a1d..484b6cca 100644 --- a/td/telegram/Photo.h +++ b/td/telegram/Photo.h @@ -90,12 +90,14 @@ bool operator!=(const DialogPhoto &lhs, const DialogPhoto &rhs); StringBuilder &operator<<(StringBuilder &string_builder, const DialogPhoto &dialog_photo); +enum class PhotoFormat : int32 { Jpeg, Png, Webp, Tgs }; + PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes, DialogId owner_dialog_id, int32 width, int32 height); Variant get_photo_size(FileManager *file_manager, PhotoSizeSource source, int64 id, int64 access_hash, string file_reference, DcId dc_id, DialogId owner_dialog_id, tl_object_ptr &&size_ptr, - bool is_webp, bool is_png); + PhotoFormat format); PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id, tl_object_ptr web_document_ptr); td_api::object_ptr get_photo_size_object(FileManager *file_manager, const PhotoSize *photo_size); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 3eebe977..593af40d 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1584,9 +1584,10 @@ std::pair StickersManager::on_get_sticker_document( PhotoSize thumbnail; for (auto &thumb : document->thumbs_) { - auto photo_size = get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, document_id, - document->access_hash_, document->file_reference_.as_slice().str(), dc_id, - DialogId(), std::move(thumb), has_webp_thumbnail(sticker), false); + auto photo_size = + get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, document_id, document->access_hash_, + document->file_reference_.as_slice().str(), dc_id, DialogId(), std::move(thumb), + has_webp_thumbnail(sticker) ? PhotoFormat::Webp : PhotoFormat::Jpeg); if (photo_size.get_offset() == 0) { thumbnail = std::move(photo_size.get<0>()); break; @@ -2084,7 +2085,8 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptrthumb_ != nullptr) { auto photo_size = get_photo_size(td_->file_manager_.get(), {set_id.get(), s->access_hash}, 0, 0, "", - DcId::create(set->thumb_dc_id_), DialogId(), std::move(set->thumb_), true, false); + DcId::create(set->thumb_dc_id_), DialogId(), std::move(set->thumb_), + is_animated ? PhotoFormat::Tgs : PhotoFormat::Webp); if (photo_size.get_offset() == 0) { thumbnail = std::move(photo_size.get<0>()); } else {