Update layer to 92: minithumbnails support.

GitOrigin-RevId: a2e3bba42504cdaf91db1e0113bc98c450ba78c9
This commit is contained in:
levlam 2019-03-01 22:51:33 +03:00
parent e8a77c6ff2
commit 43483e743d
28 changed files with 246 additions and 91 deletions

View File

@ -170,6 +170,9 @@ inputFileGenerated original_path:string conversion:string expected_size:int32 =
//@description Photo description @type Thumbnail type (see https://core.telegram.org/constructor/photoSize) @photo Information about the photo file @width Photo width @height Photo height //@description Photo description @type Thumbnail type (see https://core.telegram.org/constructor/photoSize) @photo Information about the photo file @width Photo width @height Photo height
photoSize type:string photo:file width:int32 height:int32 = PhotoSize; photoSize type:string photo:file width:int32 height:int32 = PhotoSize;
//@description A very poor quality and low resolution image thumbnail @width Thumbnail width, usually doesn't exceed 40 @height Thumbnail height, usually doesn't exceed 40 @data The thumbnail
minithumbnail width:int32 height:int32 data:bytes = Minithumbnail;
//@class MaskPoint @description Part of the face, relative to which a mask should be placed //@class MaskPoint @description Part of the face, relative to which a mask should be placed
@ -198,19 +201,20 @@ pollOption text:string voter_count:int32 vote_percentage:int32 is_chosen:Bool is
//@description Describes an animation file. The animation must be encoded in GIF or MPEG4 format @duration Duration of the animation, in seconds; as defined by the sender @width Width of the animation @height Height of the animation //@description Describes an animation file. The animation must be encoded in GIF or MPEG4 format @duration Duration of the animation, in seconds; as defined by the sender @width Width of the animation @height Height of the animation
//@file_name Original name of the file; as defined by the sender @mime_type MIME type of the file, usually "image/gif" or "video/mp4" @thumbnail Animation thumbnail; may be null @animation File containing the animation //@file_name Original name of the file; as defined by the sender @mime_type MIME type of the file, usually "image/gif" or "video/mp4"
animation duration:int32 width:int32 height:int32 file_name:string mime_type:string thumbnail:photoSize animation:file = Animation; //@minithumbnail Animation minithumbnail; may be null @thumbnail Animation thumbnail; may be null @animation File containing the animation
animation duration:int32 width:int32 height:int32 file_name:string mime_type:string minithumbnail:minithumbnail thumbnail:photoSize animation:file = Animation;
//@description Describes an audio file. Audio is usually in MP3 format @duration Duration of the audio, in seconds; as defined by the sender @title Title of the audio; as defined by the sender @performer Performer of the audio; as defined by the sender //@description Describes an audio file. Audio is usually in MP3 format @duration Duration of the audio, in seconds; as defined by the sender @title Title of the audio; as defined by the sender @performer Performer of the audio; as defined by the sender
//@file_name Original name of the file; as defined by the sender @mime_type The MIME type of the file; as defined by the sender @album_cover_thumbnail The thumbnail of the album cover; as defined by the sender. The full size thumbnail should be extracted from the downloaded file; may be null @audio File containing the audio //@file_name Original name of the file; as defined by the sender @mime_type The MIME type of the file; as defined by the sender @album_cover_minithumbnail The minithumbnail of the album cover; may be null @album_cover_thumbnail The thumbnail of the album cover; as defined by the sender. The full size thumbnail should be extracted from the downloaded file; may be null @audio File containing the audio
audio duration:int32 title:string performer:string file_name:string mime_type:string album_cover_thumbnail:photoSize audio:file = Audio; audio duration:int32 title:string performer:string file_name:string mime_type:string album_cover_minithumbnail:minithumbnail album_cover_thumbnail:photoSize audio:file = Audio;
//@description Describes a document of any type @file_name Original name of the file; as defined by the sender @mime_type MIME type of the file; as defined by the sender //@description Describes a document of any type @file_name Original name of the file; as defined by the sender @mime_type MIME type of the file; as defined by the sender
//@thumbnail Document thumbnail; as defined by the sender; may be null @document File containing the document //@minithumbnail Document minithumbnail; may be null @thumbnail Document thumbnail; as defined by the sender; may be null @document File containing the document
document file_name:string mime_type:string thumbnail:photoSize document:file = Document; document file_name:string mime_type:string minithumbnail:minithumbnail thumbnail:photoSize document:file = Document;
//@description Describes a photo @has_stickers True, if stickers were added to the photo @sizes Available variants of the photo, in different sizes //@description Describes a photo @has_stickers True, if stickers were added to the photo @minithumbnail Photo minithumbnail; may be null @sizes Available variants of the photo, in different sizes
photo has_stickers:Bool sizes:vector<photoSize> = Photo; photo has_stickers:Bool minithumbnail:minithumbnail sizes:vector<photoSize> = Photo;
//@description Describes a sticker @set_id The identifier of the sticker set to which the sticker belongs; 0 if none @width Sticker width; as defined by the sender @height Sticker height; as defined by the sender //@description Describes a sticker @set_id The identifier of the sticker set to which the sticker belongs; 0 if none @width Sticker width; as defined by the sender @height Sticker height; as defined by the sender
//@emoji Emoji corresponding to the sticker @is_mask True, if the sticker is a mask @mask_position Position where the mask should be placed; may be null @thumbnail Sticker thumbnail in WEBP or JPEG format; may be null @sticker File containing the sticker //@emoji Emoji corresponding to the sticker @is_mask True, if the sticker is a mask @mask_position Position where the mask should be placed; may be null @thumbnail Sticker thumbnail in WEBP or JPEG format; may be null @sticker File containing the sticker
@ -218,11 +222,11 @@ sticker set_id:int64 width:int32 height:int32 emoji:string is_mask:Bool mask_pos
//@description Describes a video file @duration Duration of the video, in seconds; as defined by the sender @width Video width; as defined by the sender @height Video height; as defined by the sender //@description Describes a video file @duration Duration of the video, in seconds; as defined by the sender @width Video width; as defined by the sender @height Video height; as defined by the sender
//@file_name Original name of the file; as defined by the sender @mime_type MIME type of the file; as defined by the sender @has_stickers True, if stickers were added to the photo //@file_name Original name of the file; as defined by the sender @mime_type MIME type of the file; as defined by the sender @has_stickers True, if stickers were added to the photo
//@supports_streaming True, if the video should be tried to be streamed @thumbnail Video thumbnail; as defined by the sender; may be null @video File containing the video //@supports_streaming True, if the video should be tried to be streamed @minithumbnail Video minithumbnail; may be null @thumbnail Video thumbnail; as defined by the sender; may be null @video File containing the video
video duration:int32 width:int32 height:int32 file_name:string mime_type:string has_stickers:Bool supports_streaming:Bool thumbnail:photoSize video:file = Video; video duration:int32 width:int32 height:int32 file_name:string mime_type:string has_stickers:Bool supports_streaming:Bool minithumbnail:minithumbnail thumbnail:photoSize video:file = Video;
//@description Describes a video note. The video must be equal in width and height, cropped to a circle, and stored in MPEG4 format @duration Duration of the video, in seconds; as defined by the sender @length Video width and height; as defined by the sender @thumbnail Video thumbnail; as defined by the sender; may be null @video File containing the video //@description Describes a video note. The video must be equal in width and height, cropped to a circle, and stored in MPEG4 format @duration Duration of the video, in seconds; as defined by the sender @length Video width and height; as defined by the sender @minithumbnail Video minithumbnail; may be null @thumbnail Video thumbnail; as defined by the sender; may be null @video File containing the video
videoNote duration:int32 length:int32 thumbnail:photoSize video:file = VideoNote; videoNote duration:int32 length:int32 minithumbnail:minithumbnail thumbnail:photoSize video:file = VideoNote;
//@description Describes a voice note. The voice note must be encoded with the Opus codec, and stored inside an OGG container. Voice notes can have only a single audio channel @duration Duration of the voice note, in seconds; as defined by the sender //@description Describes a voice note. The voice note must be encoded with the Opus codec, and stored inside an OGG container. Voice notes can have only a single audio channel @duration Duration of the voice note, in seconds; as defined by the sender
//@waveform A waveform representation of the voice note in 5-bit format @mime_type MIME type of the file; as defined by the sender @voice File containing the voice note //@waveform A waveform representation of the voice note in 5-bit format @mime_type MIME type of the file; as defined by the sender @voice File containing the voice note

Binary file not shown.

View File

@ -172,6 +172,7 @@ photo#9c477dd8 flags:# has_stickers:flags.0?true id:long access_hash:long file_r
photoSizeEmpty#e17e23c type:string = PhotoSize; photoSizeEmpty#e17e23c type:string = PhotoSize;
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize; photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize; photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
geoPointEmpty#1117dd5f = GeoPoint; geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint; geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint;
@ -230,7 +231,7 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs; messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs;
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages; messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages; messages.messagesSlice#a6c47aaa flags:# inexact:flags.1?true count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages; messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesNotModified#74535f21 count:int = messages.Messages; messages.messagesNotModified#74535f21 count:int = messages.Messages;

Binary file not shown.

View File

@ -162,6 +162,7 @@ tl_object_ptr<td_api::animation> AnimationsManager::get_animation_object(FileId
animation->is_changed = false; animation->is_changed = false;
return make_tl_object<td_api::animation>(animation->duration, animation->dimensions.width, return make_tl_object<td_api::animation>(animation->duration, animation->dimensions.width,
animation->dimensions.height, animation->file_name, animation->mime_type, animation->dimensions.height, animation->file_name, animation->mime_type,
get_minithumbnail_object(animation->minithumbnail),
get_photo_size_object(td_->file_manager_.get(), &animation->thumbnail), get_photo_size_object(td_->file_manager_.get(), &animation->thumbnail),
td_->file_manager_->get_file_object(file_id)); td_->file_manager_->get_file_object(file_id));
} }
@ -195,6 +196,10 @@ FileId AnimationsManager::on_get_animation(unique_ptr<Animation> new_animation,
a->duration = new_animation->duration; a->duration = new_animation->duration;
a->is_changed = true; a->is_changed = true;
} }
if (a->minithumbnail != new_animation->minithumbnail) {
a->minithumbnail = std::move(new_animation->minithumbnail);
a->is_changed = true;
}
if (a->thumbnail != new_animation->thumbnail) { if (a->thumbnail != new_animation->thumbnail) {
if (!a->thumbnail.file_id.is_valid()) { if (!a->thumbnail.file_id.is_valid()) {
LOG(DEBUG) << "Animation " << file_id << " thumbnail has changed"; LOG(DEBUG) << "Animation " << file_id << " thumbnail has changed";
@ -283,14 +288,15 @@ bool AnimationsManager::merge_animations(FileId new_id, FileId old_id, bool can_
return true; return true;
} }
void AnimationsManager::create_animation(FileId file_id, PhotoSize thumbnail, string file_name, string mime_type, void AnimationsManager::create_animation(FileId file_id, string minithumbnail, PhotoSize thumbnail, string file_name,
int32 duration, Dimensions dimensions, bool replace) { string mime_type, int32 duration, Dimensions dimensions, bool replace) {
auto a = make_unique<Animation>(); auto a = make_unique<Animation>();
a->file_id = file_id; a->file_id = file_id;
a->file_name = std::move(file_name); a->file_name = std::move(file_name);
a->mime_type = std::move(mime_type); a->mime_type = std::move(mime_type);
a->duration = max(duration, 0); a->duration = max(duration, 0);
a->dimensions = dimensions; a->dimensions = dimensions;
a->minithumbnail = std::move(minithumbnail);
a->thumbnail = std::move(thumbnail); a->thumbnail = std::move(thumbnail);
on_get_animation(std::move(a), replace); on_get_animation(std::move(a), replace);
} }

View File

@ -35,8 +35,8 @@ class AnimationsManager : public Actor {
tl_object_ptr<td_api::animation> get_animation_object(FileId file_id, const char *source); tl_object_ptr<td_api::animation> get_animation_object(FileId file_id, const char *source);
void create_animation(FileId file_id, PhotoSize thumbnail, string file_name, string mime_type, int32 duration, void create_animation(FileId file_id, string minithumbnail, PhotoSize thumbnail, string file_name, string mime_type,
Dimensions dimensions, bool replace); int32 duration, Dimensions dimensions, bool replace);
tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id, tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id,
tl_object_ptr<telegram_api::InputFile> input_file, tl_object_ptr<telegram_api::InputFile> input_file,
@ -95,6 +95,7 @@ class AnimationsManager : public Actor {
string mime_type; string mime_type;
int32 duration = 0; int32 duration = 0;
Dimensions dimensions; Dimensions dimensions;
string minithumbnail;
PhotoSize thumbnail; PhotoSize thumbnail;
FileId file_id; FileId file_id;

View File

@ -26,6 +26,7 @@ void AnimationsManager::store_animation(FileId file_id, StorerT &storer) const {
store(animation->dimensions, storer); store(animation->dimensions, storer);
store(animation->file_name, storer); store(animation->file_name, storer);
store(animation->mime_type, storer); store(animation->mime_type, storer);
store(animation->minithumbnail, storer);
store(animation->thumbnail, storer); store(animation->thumbnail, storer);
store(file_id, storer); store(file_id, storer);
} }
@ -39,6 +40,9 @@ FileId AnimationsManager::parse_animation(ParserT &parser) {
parse(animation->dimensions, parser); parse(animation->dimensions, parser);
parse(animation->file_name, parser); parse(animation->file_name, parser);
parse(animation->mime_type, parser); parse(animation->mime_type, parser);
if (parser.version() >= static_cast<int32>(Version::SupportMinithumbnails)) {
parse(animation->minithumbnail, parser);
}
parse(animation->thumbnail, parser); parse(animation->thumbnail, parser);
parse(animation->file_id, parser); parse(animation->file_id, parser);
return on_get_animation(std::move(animation), false); return on_get_animation(std::move(animation), false);

View File

@ -36,9 +36,10 @@ tl_object_ptr<td_api::audio> AudiosManager::get_audio_object(FileId file_id) {
auto &audio = audios_[file_id]; auto &audio = audios_[file_id];
CHECK(audio != nullptr); CHECK(audio != nullptr);
audio->is_changed = false; audio->is_changed = false;
return make_tl_object<td_api::audio>( return make_tl_object<td_api::audio>(audio->duration, audio->title, audio->performer, audio->file_name,
audio->duration, audio->title, audio->performer, audio->file_name, audio->mime_type, audio->mime_type, get_minithumbnail_object(audio->minithumbnail),
get_photo_size_object(td_->file_manager_.get(), &audio->thumbnail), td_->file_manager_->get_file_object(file_id)); get_photo_size_object(td_->file_manager_.get(), &audio->thumbnail),
td_->file_manager_->get_file_object(file_id));
} }
FileId AudiosManager::on_get_audio(unique_ptr<Audio> new_audio, bool replace) { FileId AudiosManager::on_get_audio(unique_ptr<Audio> new_audio, bool replace) {
@ -66,6 +67,10 @@ FileId AudiosManager::on_get_audio(unique_ptr<Audio> new_audio, bool replace) {
a->file_name = std::move(new_audio->file_name); a->file_name = std::move(new_audio->file_name);
a->is_changed = true; a->is_changed = true;
} }
if (a->minithumbnail != new_audio->minithumbnail) {
a->minithumbnail = std::move(new_audio->minithumbnail);
a->is_changed = true;
}
if (a->thumbnail != new_audio->thumbnail) { if (a->thumbnail != new_audio->thumbnail) {
if (!a->thumbnail.file_id.is_valid()) { if (!a->thumbnail.file_id.is_valid()) {
LOG(DEBUG) << "Audio " << file_id << " thumbnail has changed"; LOG(DEBUG) << "Audio " << file_id << " thumbnail has changed";
@ -163,8 +168,8 @@ void AudiosManager::delete_audio_thumbnail(FileId file_id) {
audio->thumbnail = PhotoSize(); audio->thumbnail = PhotoSize();
} }
void AudiosManager::create_audio(FileId file_id, PhotoSize thumbnail, string file_name, string mime_type, void AudiosManager::create_audio(FileId file_id, string minithumbnail, PhotoSize thumbnail, string file_name,
int32 duration, string title, string performer, bool replace) { string mime_type, int32 duration, string title, string performer, bool replace) {
auto a = make_unique<Audio>(); auto a = make_unique<Audio>();
a->file_id = file_id; a->file_id = file_id;
a->file_name = std::move(file_name); a->file_name = std::move(file_name);
@ -172,6 +177,7 @@ void AudiosManager::create_audio(FileId file_id, PhotoSize thumbnail, string fil
a->duration = max(duration, 0); a->duration = max(duration, 0);
a->title = std::move(title); a->title = std::move(title);
a->performer = std::move(performer); a->performer = std::move(performer);
a->minithumbnail = std::move(minithumbnail);
a->thumbnail = std::move(thumbnail); a->thumbnail = std::move(thumbnail);
on_get_audio(std::move(a), replace); on_get_audio(std::move(a), replace);
} }

View File

@ -30,8 +30,8 @@ class AudiosManager {
tl_object_ptr<td_api::audio> get_audio_object(FileId file_id); tl_object_ptr<td_api::audio> get_audio_object(FileId file_id);
void create_audio(FileId file_id, PhotoSize thumbnail, string file_name, string mime_type, int32 duration, void create_audio(FileId file_id, string minithumbnail, PhotoSize thumbnail, string file_name, string mime_type,
string title, string performer, bool replace); int32 duration, string title, string performer, bool replace);
tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id, tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id,
tl_object_ptr<telegram_api::InputFile> input_file, tl_object_ptr<telegram_api::InputFile> input_file,
@ -65,6 +65,7 @@ class AudiosManager {
int32 duration = 0; int32 duration = 0;
string title; string title;
string performer; string performer;
string minithumbnail;
PhotoSize thumbnail; PhotoSize thumbnail;
FileId file_id; FileId file_id;

View File

@ -26,6 +26,7 @@ void AudiosManager::store_audio(FileId file_id, StorerT &storer) const {
store(audio->duration, storer); store(audio->duration, storer);
store(audio->title, storer); store(audio->title, storer);
store(audio->performer, storer); store(audio->performer, storer);
store(audio->minithumbnail, storer);
store(audio->thumbnail, storer); store(audio->thumbnail, storer);
store(file_id, storer); store(file_id, storer);
} }
@ -38,6 +39,9 @@ FileId AudiosManager::parse_audio(ParserT &parser) {
parse(audio->duration, parser); parse(audio->duration, parser);
parse(audio->title, parser); parse(audio->title, parser);
parse(audio->performer, parser); parse(audio->performer, parser);
if (parser.version() >= static_cast<int32>(Version::SupportMinithumbnails)) {
parse(audio->minithumbnail, parser);
}
parse(audio->thumbnail, parser); parse(audio->thumbnail, parser);
parse(audio->file_id, parser); parse(audio->file_id, parser);
return on_get_audio(std::move(audio), false); return on_get_audio(std::move(audio), false);

View File

@ -56,6 +56,7 @@ tl_object_ptr<td_api::document> DocumentsManager::get_document_object(FileId fil
LOG_CHECK(document != nullptr) << tag("file_id", file_id); LOG_CHECK(document != nullptr) << tag("file_id", file_id);
document->is_changed = false; document->is_changed = false;
return make_tl_object<td_api::document>(document->file_name, document->mime_type, return make_tl_object<td_api::document>(document->file_name, document->mime_type,
get_minithumbnail_object(document->minithumbnail),
get_photo_size_object(td_->file_manager_.get(), &document->thumbnail), get_photo_size_object(td_->file_manager_.get(), &document->thumbnail),
td_->file_manager_->get_file_object(file_id)); td_->file_manager_->get_file_object(file_id));
} }
@ -193,6 +194,7 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
int32 size; int32 size;
string mime_type; string mime_type;
string file_reference; string file_reference;
string minithumbnail;
PhotoSize thumbnail; PhotoSize thumbnail;
FileEncryptionKey encryption_key; FileEncryptionKey encryption_key;
bool is_web = false; bool is_web = false;
@ -209,8 +211,13 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
file_reference = document->file_reference_.as_slice().str(); file_reference = document->file_reference_.as_slice().str();
if (document_type != Document::Type::VoiceNote) { if (document_type != Document::Type::VoiceNote) {
thumbnail = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, "", owner_dialog_id, auto photo_size = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, "", owner_dialog_id,
std::move(document->thumb_), has_webp_thumbnail); std::move(document->thumb_), has_webp_thumbnail);
if (photo_size.get_offset() == 0) {
thumbnail = std::move(photo_size.get<0>());
} else {
minithumbnail = std::move(photo_size.get<1>());
}
} }
} else if (remote_document.secret_file != nullptr) { } else if (remote_document.secret_file != nullptr) {
CHECK(remote_document.secret_document != nullptr); CHECK(remote_document.secret_document != nullptr);
@ -229,8 +236,8 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
} }
if (document_type != Document::Type::VoiceNote) { if (document_type != Document::Type::VoiceNote) {
thumbnail = get_thumbnail_photo_size(td_->file_manager_.get(), std::move(document->thumb_), owner_dialog_id, thumbnail = get_secret_thumbnail_photo_size(td_->file_manager_.get(), std::move(document->thumb_),
document->thumb_w_, document->thumb_h_); owner_dialog_id, document->thumb_w_, document->thumb_h_);
} }
} else { } else {
is_web = true; is_web = true;
@ -324,8 +331,9 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
switch (document_type) { switch (document_type) {
case Document::Type::Animation: case Document::Type::Animation:
// TODO use has_stickers // TODO use has_stickers
td_->animations_manager_->create_animation(file_id, std::move(thumbnail), std::move(file_name), td_->animations_manager_->create_animation(file_id, std::move(minithumbnail), std::move(thumbnail),
std::move(mime_type), video_duration, dimensions, !is_web); std::move(file_name), std::move(mime_type), video_duration, dimensions,
!is_web);
break; break;
case Document::Type::Audio: { case Document::Type::Audio: {
int32 duration = 0; int32 duration = 0;
@ -336,12 +344,13 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
title = std::move(audio->title_); title = std::move(audio->title_);
performer = std::move(audio->performer_); performer = std::move(audio->performer_);
} }
td_->audios_manager_->create_audio(file_id, std::move(thumbnail), std::move(file_name), std::move(mime_type), td_->audios_manager_->create_audio(file_id, std::move(minithumbnail), std::move(thumbnail), std::move(file_name),
duration, std::move(title), std::move(performer), !is_web); std::move(mime_type), duration, std::move(title), std::move(performer),
!is_web);
break; break;
} }
case Document::Type::General: case Document::Type::General:
td_->documents_manager_->create_document(file_id, std::move(thumbnail), std::move(file_name), create_document(file_id, std::move(minithumbnail), std::move(thumbnail), std::move(file_name),
std::move(mime_type), !is_web); std::move(mime_type), !is_web);
break; break;
case Document::Type::Sticker: case Document::Type::Sticker:
@ -349,12 +358,13 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
load_data_multipromise_ptr); load_data_multipromise_ptr);
break; break;
case Document::Type::Video: case Document::Type::Video:
td_->videos_manager_->create_video(file_id, std::move(thumbnail), has_stickers, vector<FileId>(), td_->videos_manager_->create_video(file_id, std::move(minithumbnail), std::move(thumbnail), has_stickers,
std::move(file_name), std::move(mime_type), video_duration, dimensions, vector<FileId>(), std::move(file_name), std::move(mime_type), video_duration,
supports_streaming, !is_web); dimensions, supports_streaming, !is_web);
break; break;
case Document::Type::VideoNote: case Document::Type::VideoNote:
td_->video_notes_manager_->create_video_note(file_id, std::move(thumbnail), video_duration, dimensions, !is_web); td_->video_notes_manager_->create_video_note(file_id, std::move(minithumbnail), std::move(thumbnail),
video_duration, dimensions, !is_web);
break; break;
case Document::Type::VoiceNote: { case Document::Type::VoiceNote: {
int32 duration = 0; int32 duration = 0;
@ -392,6 +402,10 @@ FileId DocumentsManager::on_get_document(unique_ptr<GeneralDocument> new_documen
d->file_name = new_document->file_name; d->file_name = new_document->file_name;
d->is_changed = true; d->is_changed = true;
} }
if (d->minithumbnail != new_document->minithumbnail) {
d->minithumbnail = std::move(new_document->minithumbnail);
d->is_changed = true;
}
if (d->thumbnail != new_document->thumbnail) { if (d->thumbnail != new_document->thumbnail) {
if (!d->thumbnail.file_id.is_valid()) { if (!d->thumbnail.file_id.is_valid()) {
LOG(DEBUG) << "Document " << file_id << " thumbnail has changed"; LOG(DEBUG) << "Document " << file_id << " thumbnail has changed";
@ -407,12 +421,13 @@ FileId DocumentsManager::on_get_document(unique_ptr<GeneralDocument> new_documen
return file_id; return file_id;
} }
void DocumentsManager::create_document(FileId file_id, PhotoSize thumbnail, string file_name, string mime_type, void DocumentsManager::create_document(FileId file_id, string minithumbnail, PhotoSize thumbnail, string file_name,
bool replace) { string mime_type, bool replace) {
auto d = make_unique<GeneralDocument>(); auto d = make_unique<GeneralDocument>();
d->file_id = file_id; d->file_id = file_id;
d->file_name = std::move(file_name); d->file_name = std::move(file_name);
d->mime_type = std::move(mime_type); d->mime_type = std::move(mime_type);
d->minithumbnail = std::move(minithumbnail);
d->thumbnail = std::move(thumbnail); d->thumbnail = std::move(thumbnail);
on_get_document(std::move(d), replace); on_get_document(std::move(d), replace);
} }

View File

@ -80,7 +80,8 @@ class DocumentsManager {
MultiPromiseActor *load_data_multipromise_ptr = nullptr, MultiPromiseActor *load_data_multipromise_ptr = nullptr,
Document::Type default_document_type = Document::Type::General); Document::Type default_document_type = Document::Type::General);
void create_document(FileId file_id, PhotoSize thumbnail, string file_name, string mime_type, bool replace); void create_document(FileId file_id, string minithumbnail, PhotoSize thumbnail, string file_name, string mime_type,
bool replace);
bool has_input_media(FileId file_id, FileId thumbnail_file_id, bool is_secret) const; bool has_input_media(FileId file_id, FileId thumbnail_file_id, bool is_secret) const;
@ -113,6 +114,7 @@ class DocumentsManager {
public: public:
string file_name; string file_name;
string mime_type; string mime_type;
string minithumbnail;
PhotoSize thumbnail; PhotoSize thumbnail;
FileId file_id; FileId file_id;

View File

@ -24,6 +24,7 @@ void DocumentsManager::store_document(FileId file_id, StorerT &storer) const {
const GeneralDocument *document = it->second.get(); const GeneralDocument *document = it->second.get();
store(document->file_name, storer); store(document->file_name, storer);
store(document->mime_type, storer); store(document->mime_type, storer);
store(document->minithumbnail, storer);
store(document->thumbnail, storer); store(document->thumbnail, storer);
store(file_id, storer); store(file_id, storer);
} }
@ -33,6 +34,9 @@ FileId DocumentsManager::parse_document(ParserT &parser) {
auto document = make_unique<GeneralDocument>(); auto document = make_unique<GeneralDocument>();
parse(document->file_name, parser); parse(document->file_name, parser);
parse(document->mime_type, parser); parse(document->mime_type, parser);
if (parser.version() >= static_cast<int32>(Version::SupportMinithumbnails)) {
parse(document->minithumbnail, parser);
}
parse(document->thumbnail, parser); parse(document->thumbnail, parser);
parse(document->file_id, parser); parse(document->file_id, parser);
LOG(DEBUG) << "Parsed document " << document->file_id; LOG(DEBUG) << "Parsed document " << document->file_id;

View File

@ -851,6 +851,11 @@ td_api::object_ptr<td_api::file> copy(const td_api::file &obj) {
} }
} }
template <>
tl_object_ptr<td_api::minithumbnail> copy(const td_api::minithumbnail &obj) {
return make_tl_object<td_api::minithumbnail>(obj.width_, obj.height_, obj.data_);
}
template <> template <>
tl_object_ptr<td_api::photoSize> copy(const td_api::photoSize &obj) { tl_object_ptr<td_api::photoSize> copy(const td_api::photoSize &obj) {
return make_tl_object<td_api::photoSize>(obj.type_, copy(obj.photo_), obj.width_, obj.height_); return make_tl_object<td_api::photoSize>(obj.type_, copy(obj.photo_), obj.width_, obj.height_);
@ -885,23 +890,26 @@ tl_object_ptr<td_api::maskPosition> copy(const td_api::maskPosition &obj) {
template <> template <>
tl_object_ptr<td_api::animation> copy(const td_api::animation &obj) { tl_object_ptr<td_api::animation> copy(const td_api::animation &obj) {
return make_tl_object<td_api::animation>(obj.duration_, obj.width_, obj.height_, obj.file_name_, obj.mime_type_, return make_tl_object<td_api::animation>(obj.duration_, obj.width_, obj.height_, obj.file_name_, obj.mime_type_,
copy(obj.thumbnail_), copy(obj.animation_)); copy(obj.minithumbnail_), copy(obj.thumbnail_), copy(obj.animation_));
} }
template <> template <>
tl_object_ptr<td_api::audio> copy(const td_api::audio &obj) { tl_object_ptr<td_api::audio> copy(const td_api::audio &obj) {
return make_tl_object<td_api::audio>(obj.duration_, obj.title_, obj.performer_, obj.file_name_, obj.mime_type_, return make_tl_object<td_api::audio>(obj.duration_, obj.title_, obj.performer_, obj.file_name_, obj.mime_type_,
copy(obj.album_cover_thumbnail_), copy(obj.audio_)); copy(obj.album_cover_minithumbnail_), copy(obj.album_cover_thumbnail_),
copy(obj.audio_));
} }
template <> template <>
tl_object_ptr<td_api::document> copy(const td_api::document &obj) { tl_object_ptr<td_api::document> copy(const td_api::document &obj) {
return make_tl_object<td_api::document>(obj.file_name_, obj.mime_type_, copy(obj.thumbnail_), copy(obj.document_)); return make_tl_object<td_api::document>(obj.file_name_, obj.mime_type_, copy(obj.minithumbnail_),
copy(obj.thumbnail_), copy(obj.document_));
} }
template <> template <>
tl_object_ptr<td_api::photo> copy(const td_api::photo &obj) { tl_object_ptr<td_api::photo> copy(const td_api::photo &obj) {
return make_tl_object<td_api::photo>(obj.has_stickers_, transform(obj.sizes_, copy_photo_size)); return make_tl_object<td_api::photo>(obj.has_stickers_, copy(obj.minithumbnail_),
transform(obj.sizes_, copy_photo_size));
} }
template <> template <>
@ -913,8 +921,8 @@ tl_object_ptr<td_api::sticker> copy(const td_api::sticker &obj) {
template <> template <>
tl_object_ptr<td_api::video> copy(const td_api::video &obj) { tl_object_ptr<td_api::video> copy(const td_api::video &obj) {
return make_tl_object<td_api::video>(obj.duration_, obj.width_, obj.height_, obj.file_name_, obj.mime_type_, return make_tl_object<td_api::video>(obj.duration_, obj.width_, obj.height_, obj.file_name_, obj.mime_type_,
obj.has_stickers_, obj.supports_streaming_, copy(obj.thumbnail_), obj.has_stickers_, obj.supports_streaming_, copy(obj.minithumbnail_),
copy(obj.video_)); copy(obj.thumbnail_), copy(obj.video_));
} }
template <> template <>

View File

@ -1499,7 +1499,7 @@ static Result<InputMessageContent> create_input_message_content(
auto input_animation = static_cast<td_api::inputMessageAnimation *>(input_message_content.get()); auto input_animation = static_cast<td_api::inputMessageAnimation *>(input_message_content.get());
td->animations_manager_->create_animation( td->animations_manager_->create_animation(
file_id, thumbnail, std::move(file_name), std::move(mime_type), input_animation->duration_, file_id, string(), thumbnail, std::move(file_name), std::move(mime_type), input_animation->duration_,
get_dimensions(input_animation->width_, input_animation->height_), false); get_dimensions(input_animation->width_, input_animation->height_), false);
content = make_unique<MessageAnimation>(file_id, std::move(caption)); content = make_unique<MessageAnimation>(file_id, std::move(caption));
@ -1515,7 +1515,7 @@ static Result<InputMessageContent> create_input_message_content(
return Status::Error(400, "Audio performer must be encoded in UTF-8"); return Status::Error(400, "Audio performer must be encoded in UTF-8");
} }
td->audios_manager_->create_audio(file_id, thumbnail, std::move(file_name), std::move(mime_type), td->audios_manager_->create_audio(file_id, string(), thumbnail, std::move(file_name), std::move(mime_type),
input_audio->duration_, std::move(input_audio->title_), input_audio->duration_, std::move(input_audio->title_),
std::move(input_audio->performer_), false); std::move(input_audio->performer_), false);
@ -1523,7 +1523,8 @@ static Result<InputMessageContent> create_input_message_content(
break; break;
} }
case td_api::inputMessageDocument::ID: case td_api::inputMessageDocument::ID:
td->documents_manager_->create_document(file_id, thumbnail, std::move(file_name), std::move(mime_type), false); td->documents_manager_->create_document(file_id, string(), thumbnail, std::move(file_name), std::move(mime_type),
false);
content = make_unique<MessageDocument>(file_id, std::move(caption)); content = make_unique<MessageDocument>(file_id, std::move(caption));
break; break;
@ -1579,7 +1580,7 @@ static Result<InputMessageContent> create_input_message_content(
ttl = input_video->ttl_; ttl = input_video->ttl_;
bool has_stickers = !sticker_file_ids.empty(); bool has_stickers = !sticker_file_ids.empty();
td->videos_manager_->create_video(file_id, thumbnail, has_stickers, std::move(sticker_file_ids), td->videos_manager_->create_video(file_id, string(), thumbnail, has_stickers, std::move(sticker_file_ids),
std::move(file_name), std::move(mime_type), input_video->duration_, std::move(file_name), std::move(mime_type), input_video->duration_,
get_dimensions(input_video->width_, input_video->height_), get_dimensions(input_video->width_, input_video->height_),
input_video->supports_streaming_, false); input_video->supports_streaming_, false);
@ -1595,7 +1596,7 @@ static Result<InputMessageContent> create_input_message_content(
return Status::Error(400, "Wrong video note length"); return Status::Error(400, "Wrong video note length");
} }
td->video_notes_manager_->create_video_note(file_id, thumbnail, input_video_note->duration_, td->video_notes_manager_->create_video_note(file_id, string(), thumbnail, input_video_note->duration_,
get_dimensions(length, length), false); get_dimensions(length, length), false);
content = make_unique<MessageVideoNote>(file_id, false); content = make_unique<MessageVideoNote>(file_id, false);
@ -2869,6 +2870,9 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo
if (old_photo->id != new_photo->id || old_->caption != new_->caption) { if (old_photo->id != new_photo->id || old_->caption != new_->caption) {
need_update = true; need_update = true;
} }
if (old_photo->minithumbnail != new_photo->minithumbnail) {
need_update = true;
}
if (old_photo->photos != new_photo->photos) { if (old_photo->photos != new_photo->photos) {
if (need_merge_files && if (need_merge_files &&
(old_photo->photos.size() == 1 || (old_photo->photos.size() == 2 && old_photo->photos[0].type == 't')) && (old_photo->photos.size() == 1 || (old_photo->photos.size() == 2 && old_photo->photos[0].type == 't')) &&

View File

@ -14,6 +14,7 @@
#include "td/telegram/files/FileManager.h" #include "td/telegram/files/FileManager.h"
#include "td/telegram/net/DcId.h" #include "td/telegram/net/DcId.h"
#include "td/utils/base64.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/format.h" #include "td/utils/format.h"
#include "td/utils/HttpUrl.h" #include "td/utils/HttpUrl.h"
@ -61,6 +62,39 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Dimensions &dimen
return string_builder << "(" << dimensions.width << ", " << dimensions.height << ")"; return string_builder << "(" << dimensions.width << ", " << dimensions.height << ")";
} }
td_api::object_ptr<td_api::minithumbnail> get_minithumbnail_object(const string &packed) {
if (packed.size() < 3) {
return nullptr;
}
if (packed[0] == '\x01') {
static const string header =
base64_decode(
"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDACgcHiMeGSgjISMtKygwPGRBPDc3PHtYXUlkkYCZlo+AjIqgtObDoKrarYqMyP/L2u71////"
"m8H///"
"/6/+b9//j/2wBDASstLTw1PHZBQXb4pYyl+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj/"
"wAARCAAAAAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/"
"8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0R"
"FRkd"
"ISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2"
"uHi4"
"+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/"
"8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkN"
"ERUZ"
"HSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2"
"Nna4"
"uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwA=")
.move_as_ok();
static const string footer = base64_decode("/9k=").move_as_ok();
auto result = td_api::make_object<td_api::minithumbnail>();
result->width_ = static_cast<unsigned char>(packed[1]);
result->height_ = static_cast<unsigned char>(packed[2]);
result->data_ = PSTRING() << header.substr(0, 164) << packed[1] << header[165] << packed[2] << header.substr(167)
<< packed.substr(3) << footer;
return result;
}
return nullptr;
}
static FileId register_photo(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash, static FileId register_photo(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash,
std::string upload_file_reference, std::string upload_file_reference,
tl_object_ptr<telegram_api::FileLocation> &&location_ptr, DialogId owner_dialog_id, tl_object_ptr<telegram_api::FileLocation> &&location_ptr, DialogId owner_dialog_id,
@ -228,8 +262,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DialogPhoto &dial
<< ", big_file_id = " << dialog_photo.big_file_id << ">"; << ", big_file_id = " << dialog_photo.big_file_id << ">";
} }
PhotoSize get_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes, DialogId owner_dialog_id, int32 width, PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes, DialogId owner_dialog_id,
int32 height) { int32 width, int32 height) {
if (bytes.empty()) { if (bytes.empty()) {
return PhotoSize(); return PhotoSize();
} }
@ -252,7 +286,7 @@ PhotoSize get_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes,
return res; return res;
} }
PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash, Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash,
std::string upload_file_reference, DialogId owner_dialog_id, std::string upload_file_reference, DialogId owner_dialog_id,
tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp) { tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp) {
tl_object_ptr<telegram_api::FileLocation> location_ptr; tl_object_ptr<telegram_api::FileLocation> location_ptr;
@ -263,7 +297,7 @@ PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id
switch (size_ptr->get_id()) { switch (size_ptr->get_id()) {
case telegram_api::photoSizeEmpty::ID: case telegram_api::photoSizeEmpty::ID:
return res; return std::move(res);
case telegram_api::photoSize::ID: { case telegram_api::photoSize::ID: {
auto size = move_tl_object_as<telegram_api::photoSize>(size_ptr); auto size = move_tl_object_as<telegram_api::photoSize>(size_ptr);
@ -287,6 +321,10 @@ PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id
break; break;
} }
case telegram_api::photoStrippedSize::ID: {
auto size = move_tl_object_as<telegram_api::photoStrippedSize>(size_ptr);
return size->bytes_.as_slice().str();
}
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
@ -306,7 +344,7 @@ PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id
res.type = static_cast<int32>(type[0]); res.type = static_cast<int32>(type[0]);
} }
return res; return std::move(res);
} }
PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id, PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id,
@ -465,7 +503,7 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr<telegram_api::encrypted
res.date = 0; res.date = 0;
if (!photo->thumb_.empty()) { if (!photo->thumb_.empty()) {
res.photos.push_back(get_thumbnail_photo_size(file_manager, std::move(photo->thumb_), owner_dialog_id, res.photos.push_back(get_secret_thumbnail_photo_size(file_manager, std::move(photo->thumb_), owner_dialog_id,
photo->thumb_w_, photo->thumb_h_)); photo->thumb_w_, photo->thumb_h_));
} }
@ -487,9 +525,14 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr<telegram_api::photo> &&
res.has_stickers = (photo->flags_ & telegram_api::photo::HAS_STICKERS_MASK) != 0; res.has_stickers = (photo->flags_ & telegram_api::photo::HAS_STICKERS_MASK) != 0;
for (auto &size_ptr : photo->sizes_) { for (auto &size_ptr : photo->sizes_) {
res.photos.push_back(get_photo_size(file_manager, FileType::Photo, photo->id_, photo->access_hash_, auto photo_size =
photo->file_reference_.as_slice().str(), owner_dialog_id, std::move(size_ptr), get_photo_size(file_manager, FileType::Photo, photo->id_, photo->access_hash_,
false)); photo->file_reference_.as_slice().str(), owner_dialog_id, std::move(size_ptr), false);
if (photo_size.get_offset() == 0) {
res.photos.push_back(std::move(photo_size.get<0>()));
} else {
res.minithumbnail = std::move(photo_size.get<1>());
}
} }
return res; return res;
@ -513,7 +556,8 @@ tl_object_ptr<td_api::photo> get_photo_object(FileManager *file_manager, const P
return nullptr; return nullptr;
} }
return td_api::make_object<td_api::photo>(photo->has_stickers, get_photo_sizes_object(file_manager, photo->photos)); return td_api::make_object<td_api::photo>(photo->has_stickers, get_minithumbnail_object(photo->minithumbnail),
get_photo_sizes_object(file_manager, photo->photos));
} }
tl_object_ptr<td_api::userProfilePhoto> get_user_profile_photo_object(FileManager *file_manager, const Photo *photo) { tl_object_ptr<td_api::userProfilePhoto> get_user_profile_photo_object(FileManager *file_manager, const Photo *photo) {
@ -718,6 +762,8 @@ tl_object_ptr<telegram_api::userProfilePhoto> convert_photo_to_profile_photo(
} }
break; break;
} }
case telegram_api::photoStrippedSize::ID:
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;

View File

@ -11,14 +11,15 @@
#include "td/telegram/files/FileType.h" #include "td/telegram/files/FileType.h"
#include "td/telegram/SecretInputMedia.h" #include "td/telegram/SecretInputMedia.h"
#include "td/utils/buffer.h"
#include "td/utils/common.h"
#include "td/utils/StringBuilder.h"
#include "td/telegram/secret_api.h" #include "td/telegram/secret_api.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.h"
#include "td/utils/buffer.h"
#include "td/utils/common.h"
#include "td/utils/StringBuilder.h"
#include "td/utils/Variant.h"
namespace td { namespace td {
class FileManager; class FileManager;
@ -47,6 +48,7 @@ struct PhotoSize {
struct Photo { struct Photo {
int64 id = 0; int64 id = 0;
int32 date = 0; int32 date = 0;
string minithumbnail;
vector<PhotoSize> photos; vector<PhotoSize> photos;
bool has_stickers = false; bool has_stickers = false;
@ -60,6 +62,8 @@ bool operator!=(const Dimensions &lhs, const Dimensions &rhs);
StringBuilder &operator<<(StringBuilder &string_builder, const Dimensions &dimensions); StringBuilder &operator<<(StringBuilder &string_builder, const Dimensions &dimensions);
td_api::object_ptr<td_api::minithumbnail> get_minithumbnail_object(const string &packed);
ProfilePhoto get_profile_photo(FileManager *file_manager, ProfilePhoto get_profile_photo(FileManager *file_manager,
tl_object_ptr<telegram_api::UserProfilePhoto> &&profile_photo_ptr); tl_object_ptr<telegram_api::UserProfilePhoto> &&profile_photo_ptr);
tl_object_ptr<td_api::profilePhoto> get_profile_photo_object(FileManager *file_manager, tl_object_ptr<td_api::profilePhoto> get_profile_photo_object(FileManager *file_manager,
@ -80,9 +84,9 @@ bool operator!=(const DialogPhoto &lhs, const DialogPhoto &rhs);
StringBuilder &operator<<(StringBuilder &string_builder, const DialogPhoto &dialog_photo); StringBuilder &operator<<(StringBuilder &string_builder, const DialogPhoto &dialog_photo);
PhotoSize get_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes, DialogId owner_dialog_id, int32 width, PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes, DialogId owner_dialog_id,
int32 height); int32 width, int32 height);
PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash, Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash,
std::string upload_file_reference, DialogId owner_dialog_id, std::string upload_file_reference, DialogId owner_dialog_id,
tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp); tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp);
PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id, PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id,

View File

@ -72,8 +72,10 @@ void parse(PhotoSize &photo_size, ParserT &parser) {
template <class StorerT> template <class StorerT>
void store(const Photo &photo, StorerT &storer) { void store(const Photo &photo, StorerT &storer) {
bool has_minithumbnail = !photo.minithumbnail.empty();
BEGIN_STORE_FLAGS(); BEGIN_STORE_FLAGS();
STORE_FLAG(photo.has_stickers); STORE_FLAG(photo.has_stickers);
STORE_FLAG(has_minithumbnail);
END_STORE_FLAGS(); END_STORE_FLAGS();
store(photo.id, storer); store(photo.id, storer);
store(photo.date, storer); store(photo.date, storer);
@ -81,12 +83,17 @@ void store(const Photo &photo, StorerT &storer) {
if (photo.has_stickers) { if (photo.has_stickers) {
store(photo.sticker_file_ids, storer); store(photo.sticker_file_ids, storer);
} }
if (has_minithumbnail) {
store(photo.minithumbnail, storer);
}
} }
template <class ParserT> template <class ParserT>
void parse(Photo &photo, ParserT &parser) { void parse(Photo &photo, ParserT &parser) {
bool has_minithumbnail;
BEGIN_PARSE_FLAGS(); BEGIN_PARSE_FLAGS();
PARSE_FLAG(photo.has_stickers); PARSE_FLAG(photo.has_stickers);
PARSE_FLAG(has_minithumbnail);
END_PARSE_FLAGS(); END_PARSE_FLAGS();
parse(photo.id, parser); parse(photo.id, parser);
parse(photo.date, parser); parse(photo.date, parser);
@ -94,6 +101,9 @@ void parse(Photo &photo, ParserT &parser) {
if (photo.has_stickers) { if (photo.has_stickers) {
parse(photo.sticker_file_ids, parser); parse(photo.sticker_file_ids, parser);
} }
if (has_minithumbnail) {
parse(photo.minithumbnail, parser);
}
} }
} // namespace td } // namespace td

View File

@ -1165,8 +1165,14 @@ std::pair<int64, FileId> StickersManager::on_get_sticker_document(tl_object_ptr<
document->file_reference_.as_slice().str()), document->file_reference_.as_slice().str()),
FileLocationSource::FromServer, DialogId(), document->size_, 0, PSTRING() << document_id << ".webp"); FileLocationSource::FromServer, DialogId(), document->size_, 0, PSTRING() << document_id << ".webp");
PhotoSize thumbnail = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, "", DialogId(), auto photo_size = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, "", DialogId(),
std::move(document->thumb_), has_webp_thumbnail(sticker)); std::move(document->thumb_), has_webp_thumbnail(sticker));
PhotoSize thumbnail;
if (photo_size.get_offset() == 0) {
thumbnail = std::move(photo_size.get<0>());
} else {
LOG(ERROR) << "Receive minithumbnail for a sticker";
}
create_sticker(sticker_id, std::move(thumbnail), dimensions, from_message, std::move(sticker), nullptr); create_sticker(sticker_id, std::move(thumbnail), dimensions, from_message, std::move(sticker), nullptr);
return {document_id, sticker_id}; return {document_id, sticker_id};
@ -3220,7 +3226,7 @@ Result<std::tuple<FileId, bool, bool>> StickersManager::prepare_input_file(
} }
auto file_id = r_file_id.move_as_ok(); auto file_id = r_file_id.move_as_ok();
td_->documents_manager_->create_document(file_id, PhotoSize(), "sticker.png", "image/png", false); td_->documents_manager_->create_document(file_id, string(), PhotoSize(), "sticker.png", "image/png", false);
FileView file_view = td_->file_manager_->get_file_view(file_id); FileView file_view = td_->file_manager_->get_file_view(file_id);
if (file_view.is_encrypted()) { if (file_view.is_encrypted()) {

View File

@ -29,6 +29,7 @@ enum class Version : int32 {
AddMessageUnsupportedVersion, AddMessageUnsupportedVersion,
SupportInstantView2_0, SupportInstantView2_0,
AddNotificationGroupInfoMaxRemovedMessageId, AddNotificationGroupInfoMaxRemovedMessageId,
SupportMinithumbnails,
Next Next
}; };

View File

@ -39,6 +39,7 @@ tl_object_ptr<td_api::videoNote> VideoNotesManager::get_video_note_object(FileId
video_note->is_changed = false; video_note->is_changed = false;
return make_tl_object<td_api::videoNote>(video_note->duration, video_note->dimensions.width, return make_tl_object<td_api::videoNote>(video_note->duration, video_note->dimensions.width,
get_minithumbnail_object(video_note->minithumbnail),
get_photo_size_object(td_->file_manager_.get(), &video_note->thumbnail), get_photo_size_object(td_->file_manager_.get(), &video_note->thumbnail),
td_->file_manager_->get_file_object(file_id)); td_->file_manager_->get_file_object(file_id));
} }
@ -57,6 +58,10 @@ FileId VideoNotesManager::on_get_video_note(unique_ptr<VideoNote> new_video_note
v->dimensions = new_video_note->dimensions; v->dimensions = new_video_note->dimensions;
v->is_changed = true; v->is_changed = true;
} }
if (v->minithumbnail != new_video_note->minithumbnail) {
v->minithumbnail = std::move(new_video_note->minithumbnail);
v->is_changed = true;
}
if (v->thumbnail != new_video_note->thumbnail) { if (v->thumbnail != new_video_note->thumbnail) {
if (!v->thumbnail.file_id.is_valid()) { if (!v->thumbnail.file_id.is_valid()) {
LOG(DEBUG) << "Video note " << file_id << " thumbnail has changed"; LOG(DEBUG) << "Video note " << file_id << " thumbnail has changed";
@ -142,8 +147,8 @@ bool VideoNotesManager::merge_video_notes(FileId new_id, FileId old_id, bool can
return true; return true;
} }
void VideoNotesManager::create_video_note(FileId file_id, PhotoSize thumbnail, int32 duration, Dimensions dimensions, void VideoNotesManager::create_video_note(FileId file_id, string minithumbnail, PhotoSize thumbnail, int32 duration,
bool replace) { Dimensions dimensions, bool replace) {
auto v = make_unique<VideoNote>(); auto v = make_unique<VideoNote>();
v->file_id = file_id; v->file_id = file_id;
v->duration = max(duration, 0); v->duration = max(duration, 0);
@ -152,6 +157,7 @@ void VideoNotesManager::create_video_note(FileId file_id, PhotoSize thumbnail, i
} else { } else {
LOG(INFO) << "Receive wrong video note dimensions " << dimensions; LOG(INFO) << "Receive wrong video note dimensions " << dimensions;
} }
v->minithumbnail = std::move(minithumbnail);
v->thumbnail = std::move(thumbnail); v->thumbnail = std::move(thumbnail);
on_get_video_note(std::move(v), replace); on_get_video_note(std::move(v), replace);
} }

View File

@ -30,7 +30,8 @@ class VideoNotesManager {
tl_object_ptr<td_api::videoNote> get_video_note_object(FileId file_id); tl_object_ptr<td_api::videoNote> get_video_note_object(FileId file_id);
void create_video_note(FileId file_id, PhotoSize thumbnail, int32 duration, Dimensions dimensions, bool replace); void create_video_note(FileId file_id, string minithumbnail, PhotoSize thumbnail, int32 duration,
Dimensions dimensions, bool replace);
tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id, tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id,
tl_object_ptr<telegram_api::InputFile> input_file, tl_object_ptr<telegram_api::InputFile> input_file,
@ -59,6 +60,7 @@ class VideoNotesManager {
public: public:
int32 duration = 0; int32 duration = 0;
Dimensions dimensions; Dimensions dimensions;
string minithumbnail;
PhotoSize thumbnail; PhotoSize thumbnail;
FileId file_id; FileId file_id;

View File

@ -23,6 +23,7 @@ void VideoNotesManager::store_video_note(FileId file_id, StorerT &storer) const
const VideoNote *video_note = it->second.get(); const VideoNote *video_note = it->second.get();
store(video_note->duration, storer); store(video_note->duration, storer);
store(video_note->dimensions, storer); store(video_note->dimensions, storer);
store(video_note->minithumbnail, storer);
store(video_note->thumbnail, storer); store(video_note->thumbnail, storer);
store(file_id, storer); store(file_id, storer);
} }
@ -32,6 +33,9 @@ FileId VideoNotesManager::parse_video_note(ParserT &parser) {
auto video_note = make_unique<VideoNote>(); auto video_note = make_unique<VideoNote>();
parse(video_note->duration, parser); parse(video_note->duration, parser);
parse(video_note->dimensions, parser); parse(video_note->dimensions, parser);
if (parser.version() >= static_cast<int32>(Version::SupportMinithumbnails)) {
parse(video_note->minithumbnail, parser);
}
parse(video_note->thumbnail, parser); parse(video_note->thumbnail, parser);
parse(video_note->file_id, parser); parse(video_note->file_id, parser);
return on_get_video_note(std::move(video_note), false); return on_get_video_note(std::move(video_note), false);

View File

@ -40,7 +40,7 @@ tl_object_ptr<td_api::video> VideosManager::get_video_object(FileId file_id) {
return make_tl_object<td_api::video>( return make_tl_object<td_api::video>(
video->duration, video->dimensions.width, video->dimensions.height, video->file_name, video->mime_type, video->duration, video->dimensions.width, video->dimensions.height, video->file_name, video->mime_type,
video->has_stickers, video->supports_streaming, video->has_stickers, video->supports_streaming, get_minithumbnail_object(video->minithumbnail),
get_photo_size_object(td_->file_manager_.get(), &video->thumbnail), td_->file_manager_->get_file_object(file_id)); get_photo_size_object(td_->file_manager_.get(), &video->thumbnail), td_->file_manager_->get_file_object(file_id));
} }
@ -70,6 +70,10 @@ FileId VideosManager::on_get_video(unique_ptr<Video> new_video, bool replace) {
v->file_name = std::move(new_video->file_name); v->file_name = std::move(new_video->file_name);
v->is_changed = true; v->is_changed = true;
} }
if (v->minithumbnail != new_video->minithumbnail) {
v->minithumbnail = std::move(new_video->minithumbnail);
v->is_changed = true;
}
if (v->thumbnail != new_video->thumbnail) { if (v->thumbnail != new_video->thumbnail) {
if (!v->thumbnail.file_id.is_valid()) { if (!v->thumbnail.file_id.is_valid()) {
LOG(DEBUG) << "Video " << file_id << " thumbnail has changed"; LOG(DEBUG) << "Video " << file_id << " thumbnail has changed";
@ -168,7 +172,7 @@ bool VideosManager::merge_videos(FileId new_id, FileId old_id, bool can_delete_o
return true; return true;
} }
void VideosManager::create_video(FileId file_id, PhotoSize thumbnail, bool has_stickers, void VideosManager::create_video(FileId file_id, string minithumbnail, PhotoSize thumbnail, bool has_stickers,
vector<FileId> &&sticker_file_ids, string file_name, string mime_type, int32 duration, vector<FileId> &&sticker_file_ids, string file_name, string mime_type, int32 duration,
Dimensions dimensions, bool supports_streaming, bool replace) { Dimensions dimensions, bool supports_streaming, bool replace) {
auto v = make_unique<Video>(); auto v = make_unique<Video>();
@ -177,6 +181,7 @@ void VideosManager::create_video(FileId file_id, PhotoSize thumbnail, bool has_s
v->mime_type = std::move(mime_type); v->mime_type = std::move(mime_type);
v->duration = max(duration, 0); v->duration = max(duration, 0);
v->dimensions = dimensions; v->dimensions = dimensions;
v->minithumbnail = std::move(minithumbnail);
v->thumbnail = std::move(thumbnail); v->thumbnail = std::move(thumbnail);
v->supports_streaming = supports_streaming; v->supports_streaming = supports_streaming;
v->has_stickers = has_stickers; v->has_stickers = has_stickers;

View File

@ -30,9 +30,9 @@ class VideosManager {
tl_object_ptr<td_api::video> get_video_object(FileId file_id); tl_object_ptr<td_api::video> get_video_object(FileId file_id);
void create_video(FileId file_id, PhotoSize thumbnail, bool has_stickers, vector<FileId> &&sticker_file_ids, void create_video(FileId file_id, string minithumbnail, PhotoSize thumbnail, bool has_stickers,
string file_name, string mime_type, int32 duration, Dimensions dimensions, bool supports_streaming, vector<FileId> &&sticker_file_ids, string file_name, string mime_type, int32 duration,
bool replace); Dimensions dimensions, bool supports_streaming, bool replace);
tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id, tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id,
tl_object_ptr<telegram_api::InputFile> input_file, tl_object_ptr<telegram_api::InputFile> input_file,
@ -66,6 +66,7 @@ class VideosManager {
string mime_type; string mime_type;
int32 duration = 0; int32 duration = 0;
Dimensions dimensions; Dimensions dimensions;
string minithumbnail;
PhotoSize thumbnail; PhotoSize thumbnail;
bool supports_streaming = false; bool supports_streaming = false;

View File

@ -29,6 +29,7 @@ void VideosManager::store_video(FileId file_id, StorerT &storer) const {
store(video->mime_type, storer); store(video->mime_type, storer);
store(video->duration, storer); store(video->duration, storer);
store(video->dimensions, storer); store(video->dimensions, storer);
store(video->minithumbnail, storer);
store(video->thumbnail, storer); store(video->thumbnail, storer);
store(file_id, storer); store(file_id, storer);
if (video->has_stickers) { if (video->has_stickers) {
@ -47,6 +48,9 @@ FileId VideosManager::parse_video(ParserT &parser) {
parse(video->mime_type, parser); parse(video->mime_type, parser);
parse(video->duration, parser); parse(video->duration, parser);
parse(video->dimensions, parser); parse(video->dimensions, parser);
if (parser.version() >= static_cast<int32>(Version::SupportMinithumbnails)) {
parse(video->minithumbnail, parser);
}
parse(video->thumbnail, parser); parse(video->thumbnail, parser);
parse(video->file_id, parser); parse(video->file_id, parser);
if (video->has_stickers) { if (video->has_stickers) {

View File

@ -97,11 +97,17 @@ void WallpaperManager::on_get_wallpapers(Result<vector<telegram_api::object_ptr<
switch (wallpaper_ptr->get_id()) { switch (wallpaper_ptr->get_id()) {
case telegram_api::wallPaper::ID: { case telegram_api::wallPaper::ID: {
auto wallpaper = move_tl_object_as<telegram_api::wallPaper>(wallpaper_ptr); auto wallpaper = move_tl_object_as<telegram_api::wallPaper>(wallpaper_ptr);
vector<PhotoSize> sizes = transform(std::move(wallpaper->sizes_), vector<PhotoSize> sizes;
[file_manager](tl_object_ptr<telegram_api::PhotoSize> &&photo_size) { sizes.reserve(wallpaper->sizes_.size());
return get_photo_size(file_manager, FileType::Wallpaper, 0, 0, "", for (auto &size : wallpaper->sizes_) {
DialogId(), std::move(photo_size), false); auto photo_size =
}); get_photo_size(file_manager, FileType::Wallpaper, 0, 0, "", DialogId(), std::move(size), false);
if (photo_size.get_offset() == 0) {
sizes.push_back(std::move(photo_size.get<0>()));
} else {
LOG(ERROR) << "Receive minithumbnail for a wallpaper";
}
}
return Wallpaper{wallpaper->id_, std::move(sizes), wallpaper->color_}; return Wallpaper{wallpaper->id_, std::move(sizes), wallpaper->color_};
} }
case telegram_api::wallPaperSolid::ID: { case telegram_api::wallPaperSolid::ID: {

View File

@ -21,7 +21,7 @@ class HeaderStorer {
} }
template <class StorerT> template <class StorerT>
void store(StorerT &storer) const { void store(StorerT &storer) const {
constexpr int32 LAYER = 91; constexpr int32 LAYER = 92;
using td::store; using td::store;
// invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X; // invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;