"Fossies" - the Fresh Open Source Software Archive

Member "tdesktop-2.6.1/Telegram/SourceFiles/chat_helpers/stickers_lottie.cpp" (24 Feb 2021, 5106 Bytes) of package /linux/misc/tdesktop-2.6.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "stickers_lottie.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2 This file is part of Telegram Desktop,
    3 the official desktop application for the Telegram messaging service.
    4 
    5 For license and copyright information please follow this link:
    6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
    7 */
    8 #include "chat_helpers/stickers_lottie.h"
    9 
   10 #include "lottie/lottie_single_player.h"
   11 #include "lottie/lottie_multi_player.h"
   12 #include "data/stickers/data_stickers_set.h"
   13 #include "data/data_document.h"
   14 #include "data/data_document_media.h"
   15 #include "data/data_session.h"
   16 #include "data/data_file_origin.h"
   17 #include "storage/cache/storage_cache_database.h"
   18 #include "main/main_session.h"
   19 
   20 namespace ChatHelpers {
   21 namespace {
   22 
   23 constexpr auto kDontCacheLottieAfterArea = 512 * 512;
   24 
   25 } // namespace
   26 
   27 template <typename Method>
   28 auto LottieCachedFromContent(
   29         Method &&method,
   30         Storage::Cache::Key baseKey,
   31         uint8 keyShift,
   32         not_null<Main::Session*> session,
   33         const QByteArray &content,
   34         QSize box) {
   35     const auto key = Storage::Cache::Key{
   36         baseKey.high,
   37         baseKey.low + keyShift
   38     };
   39     const auto get = [=](FnMut<void(QByteArray &&cached)> handler) {
   40         session->data().cacheBigFile().get(
   41             key,
   42             std::move(handler));
   43     };
   44     const auto weak = base::make_weak(session.get());
   45     const auto put = [=](QByteArray &&cached) {
   46         crl::on_main(weak, [=, data = std::move(cached)]() mutable {
   47             weak->data().cacheBigFile().put(key, std::move(data));
   48         });
   49     };
   50     return method(
   51         get,
   52         put,
   53         content,
   54         Lottie::FrameRequest{ box });
   55 }
   56 
   57 template <typename Method>
   58 auto LottieFromDocument(
   59         Method &&method,
   60         not_null<Data::DocumentMedia*> media,
   61         uint8 keyShift,
   62         QSize box) {
   63     const auto document = media->owner();
   64     const auto data = media->bytes();
   65     const auto filepath = document->filepath();
   66     if (box.width() * box.height() > kDontCacheLottieAfterArea) {
   67         // Don't use frame caching for large stickers.
   68         return method(
   69             Lottie::ReadContent(data, filepath),
   70             Lottie::FrameRequest{ box });
   71     }
   72     if (const auto baseKey = document->bigFileBaseCacheKey()) {
   73         return LottieCachedFromContent(
   74             std::forward<Method>(method),
   75             baseKey,
   76             keyShift,
   77             &document->session(),
   78             Lottie::ReadContent(data, filepath),
   79             box);
   80     }
   81     return method(
   82         Lottie::ReadContent(data, filepath),
   83         Lottie::FrameRequest{ box });
   84 }
   85 
   86 std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
   87         not_null<Data::DocumentMedia*> media,
   88         StickerLottieSize sizeTag,
   89         QSize box,
   90         Lottie::Quality quality,
   91         std::shared_ptr<Lottie::FrameRenderer> renderer) {
   92     return LottiePlayerFromDocument(
   93         media,
   94         nullptr,
   95         sizeTag,
   96         box,
   97         quality,
   98         std::move(renderer));
   99 }
  100 
  101 std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
  102         not_null<Data::DocumentMedia*> media,
  103         const Lottie::ColorReplacements *replacements,
  104         StickerLottieSize sizeTag,
  105         QSize box,
  106         Lottie::Quality quality,
  107         std::shared_ptr<Lottie::FrameRenderer> renderer) {
  108     const auto method = [&](auto &&...args) {
  109         return std::make_unique<Lottie::SinglePlayer>(
  110             std::forward<decltype(args)>(args)...,
  111             quality,
  112             replacements,
  113             std::move(renderer));
  114     };
  115     const auto tag = replacements ? replacements->tag : uint8(0);
  116     const auto keyShift = ((tag << 4) & 0xF0) | (uint8(sizeTag) & 0x0F);
  117     return LottieFromDocument(method, media, uint8(keyShift), box);
  118 }
  119 
  120 not_null<Lottie::Animation*> LottieAnimationFromDocument(
  121         not_null<Lottie::MultiPlayer*> player,
  122         not_null<Data::DocumentMedia*> media,
  123         StickerLottieSize sizeTag,
  124         QSize box) {
  125     const auto method = [&](auto &&...args) {
  126         return player->append(std::forward<decltype(args)>(args)...);
  127     };
  128     return LottieFromDocument(method, media, uint8(sizeTag), box);
  129 }
  130 
  131 bool HasLottieThumbnail(
  132         Data::StickersSetThumbnailView *thumb,
  133         Data::DocumentMedia *media) {
  134     if (thumb) {
  135         return !thumb->content().isEmpty();
  136     } else if (!media) {
  137         return false;
  138     }
  139     const auto document = media->owner();
  140     if (const auto info = document->sticker()) {
  141         if (!info->animated) {
  142             return false;
  143         }
  144         media->automaticLoad(document->stickerSetOrigin(), nullptr);
  145         if (!media->loaded()) {
  146             return false;
  147         }
  148         return document->bigFileBaseCacheKey().valid();
  149     }
  150     return false;
  151 }
  152 
  153 std::unique_ptr<Lottie::SinglePlayer> LottieThumbnail(
  154         Data::StickersSetThumbnailView *thumb,
  155         Data::DocumentMedia *media,
  156         StickerLottieSize sizeTag,
  157         QSize box,
  158         std::shared_ptr<Lottie::FrameRenderer> renderer) {
  159     const auto baseKey = thumb
  160         ? thumb->owner()->thumbnailLocation().file().bigFileBaseCacheKey()
  161         : media
  162         ? media->owner()->bigFileBaseCacheKey()
  163         : Storage::Cache::Key();
  164     if (!baseKey) {
  165         return nullptr;
  166     }
  167     const auto content = thumb
  168         ? thumb->content()
  169         : Lottie::ReadContent(media->bytes(), media->owner()->filepath());
  170     if (content.isEmpty()) {
  171         return nullptr;
  172     }
  173     const auto method = [](auto &&...args) {
  174         return std::make_unique<Lottie::SinglePlayer>(
  175             std::forward<decltype(args)>(args)...);
  176     };
  177     const auto session = thumb
  178         ? &thumb->owner()->session()
  179         : media
  180         ? &media->owner()->session()
  181         : nullptr;
  182     return LottieCachedFromContent(
  183         method,
  184         baseKey,
  185         uint8(sizeTag),
  186         session,
  187         content,
  188         box);
  189 }
  190 
  191 } // namespace ChatHelpers