mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-24 09:16:57 +00:00
Unpack lottie gzip to std::string for rlottie.
This commit is contained in:
parent
aa3a079853
commit
f20d9395d1
@ -21,7 +21,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
namespace Lottie {
|
namespace Lottie {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
QByteArray UnpackGzip(const QByteArray &bytes) {
|
std::string UnpackGzip(const QByteArray &bytes) {
|
||||||
|
const auto original = [&] {
|
||||||
|
return std::string(bytes.constData(), bytes.size());
|
||||||
|
};
|
||||||
z_stream stream;
|
z_stream stream;
|
||||||
stream.zalloc = nullptr;
|
stream.zalloc = nullptr;
|
||||||
stream.zfree = nullptr;
|
stream.zfree = nullptr;
|
||||||
@ -30,11 +33,11 @@ QByteArray UnpackGzip(const QByteArray &bytes) {
|
|||||||
stream.next_in = nullptr;
|
stream.next_in = nullptr;
|
||||||
int res = inflateInit2(&stream, 16 + MAX_WBITS);
|
int res = inflateInit2(&stream, 16 + MAX_WBITS);
|
||||||
if (res != Z_OK) {
|
if (res != Z_OK) {
|
||||||
return bytes;
|
return original();
|
||||||
}
|
}
|
||||||
const auto guard = gsl::finally([&] { inflateEnd(&stream); });
|
const auto guard = gsl::finally([&] { inflateEnd(&stream); });
|
||||||
|
|
||||||
auto result = QByteArray(kMaxFileSize + 1, Qt::Uninitialized);
|
auto result = std::string(kMaxFileSize + 1, char(0));
|
||||||
stream.avail_in = bytes.size();
|
stream.avail_in = bytes.size();
|
||||||
stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(bytes.data()));
|
stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(bytes.data()));
|
||||||
stream.avail_out = 0;
|
stream.avail_out = 0;
|
||||||
@ -43,9 +46,9 @@ QByteArray UnpackGzip(const QByteArray &bytes) {
|
|||||||
stream.next_out = reinterpret_cast<Bytef*>(result.data());
|
stream.next_out = reinterpret_cast<Bytef*>(result.data());
|
||||||
int res = inflate(&stream, Z_NO_FLUSH);
|
int res = inflate(&stream, Z_NO_FLUSH);
|
||||||
if (res != Z_OK && res != Z_STREAM_END) {
|
if (res != Z_OK && res != Z_STREAM_END) {
|
||||||
return bytes;
|
return original();
|
||||||
} else if (!stream.avail_out) {
|
} else if (!stream.avail_out) {
|
||||||
return bytes;
|
return original();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.resize(result.size() - stream.avail_out);
|
result.resize(result.size() - stream.avail_out);
|
||||||
@ -75,21 +78,16 @@ auto Init(QByteArray &&content)
|
|||||||
<< content.size();
|
<< content.size();
|
||||||
return Error::ParseFailed;
|
return Error::ParseFailed;
|
||||||
}
|
}
|
||||||
content = UnpackGzip(content);
|
const auto string = UnpackGzip(content);
|
||||||
if (content.size() > kMaxFileSize) {
|
Assert(string.size() <= kMaxFileSize);
|
||||||
qWarning()
|
|
||||||
<< "Lottie Error: Too large file: "
|
auto animation = rlottie::Animation::loadFromData(string, std::string());
|
||||||
<< content.size();
|
|
||||||
return Error::ParseFailed;
|
|
||||||
}
|
|
||||||
auto animation = rlottie::Animation::loadFromData(
|
|
||||||
std::string(content.constData(), content.size()),
|
|
||||||
std::string());
|
|
||||||
if (!animation) {
|
if (!animation) {
|
||||||
qWarning()
|
qWarning()
|
||||||
<< "Lottie Error: Parse failed.";
|
<< "Lottie Error: Parse failed.";
|
||||||
return Error::ParseFailed;
|
return Error::ParseFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = std::make_unique<SharedState>(std::move(animation));
|
auto result = std::make_unique<SharedState>(std::move(animation));
|
||||||
auto information = result->information();
|
auto information = result->information();
|
||||||
if (!information.frameRate
|
if (!information.frameRate
|
||||||
@ -154,8 +152,7 @@ QImage Animation::frame(const FrameRequest &request) const {
|
|||||||
Expects(_renderer != nullptr);
|
Expects(_renderer != nullptr);
|
||||||
|
|
||||||
const auto frame = _state->frameForPaint();
|
const auto frame = _state->frameForPaint();
|
||||||
const auto changed = (frame->request != request)
|
const auto changed = (frame->request != request);
|
||||||
&& (request.strict || !frame->request.strict);
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
frame->request = request;
|
frame->request = request;
|
||||||
_renderer->updateFrameRequest(_state, request);
|
_renderer->updateFrameRequest(_state, request);
|
||||||
|
@ -49,13 +49,6 @@ enum class Error {
|
|||||||
struct FrameRequest {
|
struct FrameRequest {
|
||||||
QSize resize;
|
QSize resize;
|
||||||
std::optional<QColor> colored;
|
std::optional<QColor> colored;
|
||||||
bool strict = true;
|
|
||||||
|
|
||||||
static FrameRequest NonStrict() {
|
|
||||||
auto result = FrameRequest();
|
|
||||||
result.strict = false;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return resize.isEmpty();
|
return resize.isEmpty();
|
||||||
|
@ -180,7 +180,7 @@ SharedState::SharedState(std::unique_ptr<rlottie::Animation> animation)
|
|||||||
calculateProperties();
|
calculateProperties();
|
||||||
if (isValid()) {
|
if (isValid()) {
|
||||||
auto cover = QImage();
|
auto cover = QImage();
|
||||||
renderFrame(cover, FrameRequest::NonStrict(), 0);
|
renderFrame(cover, FrameRequest(), 0);
|
||||||
init(std::move(cover));
|
init(std::move(cover));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ struct Frame {
|
|||||||
crl::time displayed = kTimeUnknown;
|
crl::time displayed = kTimeUnknown;
|
||||||
crl::time display = kTimeUnknown;
|
crl::time display = kTimeUnknown;
|
||||||
|
|
||||||
FrameRequest request = FrameRequest::NonStrict();
|
FrameRequest request;
|
||||||
QImage prepared;
|
QImage prepared;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user