From 72a9d61b9717d18204a0b5cb5503cb44def1e2df Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 5 Jul 2019 18:13:27 +0200 Subject: [PATCH] Fix glitches on macOS stickers. --- Telegram/SourceFiles/lottie/lottie_cache.cpp | 52 ++++++++++++++----- Telegram/SourceFiles/lottie/lottie_common.cpp | 11 ++++ Telegram/SourceFiles/lottie/lottie_common.h | 11 +--- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/Telegram/SourceFiles/lottie/lottie_cache.cpp b/Telegram/SourceFiles/lottie/lottie_cache.cpp index b34eaf77aa..c2f025e43a 100644 --- a/Telegram/SourceFiles/lottie/lottie_cache.cpp +++ b/Telegram/SourceFiles/lottie/lottie_cache.cpp @@ -254,12 +254,34 @@ void Encode( EncodeAlpha(to, cache); } +int YLineSize(int width) { + return ((width + kAlignStorage - 1) / kAlignStorage) * kAlignStorage; +} + +int UVLineSize(int width) { + return (((width / 2) + kAlignStorage - 1) / kAlignStorage) * kAlignStorage; +} + +int YSize(int width, int height) { + return YLineSize(width) * height; +} + +int UVSize(int width, int height) { + return UVLineSize(width) * (height / 2); +} + +int ASize(int width, int height) { + return (width * height) / 2; +} + } // namespace void EncodedStorage::allocate(int width, int height) { Expects((width % 2) == 0 && (height % 2) == 0); - if (_width != width || _height != height) { + if (YSize(width, height) != YSize(_width, _height) + || UVSize(width, height) != UVSize(_width, _height) + || ASize(width, height) != ASize(_width, _height)) { _width = width; _height = height; reallocate(); @@ -267,8 +289,10 @@ void EncodedStorage::allocate(int width, int height) { } void EncodedStorage::reallocate() { - const auto total = _width * _height * 2; - _data = QByteArray(total + kAlignStorage - 1, Qt::Uninitialized); + const auto total = YSize(_width, _height) + + 2 * UVSize(_width, _height) + + ASize(_width, _height); + _data = QByteArray(total + kAlignStorage - 1, 0); } int EncodedStorage::width() const { @@ -280,7 +304,9 @@ int EncodedStorage::height() const { } int EncodedStorage::size() const { - return _width * _height * 2; + return YSize(_width, _height) + + 2 * UVSize(_width, _height) + + ASize(_width, _height); } char *EncodedStorage::data() { @@ -304,39 +330,39 @@ const uint8_t *EncodedStorage::yData() const { } int EncodedStorage::yBytesPerLine() const { - return _width; + return YLineSize(_width); } uint8_t *EncodedStorage::uData() { - return yData() + (_width * _height); + return yData() + YSize(_width, _height); } const uint8_t *EncodedStorage::uData() const { - return yData() + (_width * _height); + return yData() + YSize(_width, _height); } int EncodedStorage::uBytesPerLine() const { - return _width / 2; + return UVLineSize(_width); } uint8_t *EncodedStorage::vData() { - return uData() + (_width * _height / 4); + return uData() + UVSize(_width, _height); } const uint8_t *EncodedStorage::vData() const { - return uData() + (_width * _height / 4); + return uData() + UVSize(_width, _height); } int EncodedStorage::vBytesPerLine() const { - return _width / 2; + return UVLineSize(_width); } uint8_t *EncodedStorage::aData() { - return uData() + (_width * _height) / 2; + return uData() + 2 * UVSize(_width, _height); } const uint8_t *EncodedStorage::aData() const { - return uData() + (_width * _height) / 2; + return uData() + 2 * UVSize(_width, _height); } int EncodedStorage::aBytesPerLine() const { diff --git a/Telegram/SourceFiles/lottie/lottie_common.cpp b/Telegram/SourceFiles/lottie/lottie_common.cpp index 32dadff9cc..32068634d8 100644 --- a/Telegram/SourceFiles/lottie/lottie_common.cpp +++ b/Telegram/SourceFiles/lottie/lottie_common.cpp @@ -23,6 +23,17 @@ QByteArray ReadFile(const QString &filepath) { } // namespace +QSize FrameRequest::size(const QSize &original) const { + Expects(!empty()); + + const auto result = original.scaled(box, Qt::KeepAspectRatio); + const auto skipw = result.width() % 8; + const auto skiph = result.height() % 8; + return QSize( + std::max(result.width() - skipw, 8), + std::max(result.height() - skiph, 8)); +} + QByteArray ReadContent(const QByteArray &data, const QString &filepath) { return data.isEmpty() ? ReadFile(filepath) : base::duplicate(data); } diff --git a/Telegram/SourceFiles/lottie/lottie_common.h b/Telegram/SourceFiles/lottie/lottie_common.h index 9c2c7b3b12..6d1e5631a5 100644 --- a/Telegram/SourceFiles/lottie/lottie_common.h +++ b/Telegram/SourceFiles/lottie/lottie_common.h @@ -39,16 +39,7 @@ struct FrameRequest { [[nodiscard]] bool empty() const { return box.isEmpty(); } - [[nodiscard]] QSize size(const QSize &original) const { - Expects(!empty()); - - const auto result = original.scaled(box, Qt::KeepAspectRatio); - const auto skipw = result.width() % 2; - const auto skiph = result.height() % 2; - return QSize( - std::max(result.width() - skipw, 2), - std::max(result.height() - skiph, 2)); - } + [[nodiscard]] QSize size(const QSize &original) const; [[nodiscard]] bool operator==(const FrameRequest &other) const { return (box == other.box)