diff --git a/ui/image/image_prepare.cpp b/ui/image/image_prepare.cpp index aaa4469..1b25717 100644 --- a/ui/image/image_prepare.cpp +++ b/ui/image/image_prepare.cpp @@ -13,6 +13,10 @@ #include "styles/palette.h" #include "styles/style_basic.h" +#include +#include +#include + namespace Images { namespace { @@ -111,6 +115,50 @@ std::array PrepareCorners( return result; } +ReadResult Read(ReadArgs &&args) { + if (args.content.isEmpty()) { + auto file = QFile(args.path); + if (file.size() > kReadBytesLimit + || !file.open(QIODevice::ReadOnly)) { + return {}; + } + args.content = file.readAll(); + } + if (args.content.isEmpty()) { + return {}; + } + auto result = ReadResult(); + { + auto buffer = QBuffer(&args.content); + auto reader = QImageReader(&buffer); + reader.setAutoTransform(true); + if (!reader.canRead()) { + return {}; + } + const auto size = reader.size(); + if (size.width() * size.height() > kReadMaxArea) { + return {}; + } + if (!reader.read(&result.image) || result.image.isNull()) { + return {}; + } + result.animated = reader.supportsAnimation() + && (reader.imageCount() > 1); + result.format = reader.format().toLower(); + } + if (args.returnContent) { + result.content = args.content; + } else { + args.content = QByteArray(); + } + if (args.forceOpaque + && result.format != qstr("jpg") + && result.format != qstr("jpeg")) { + result.image = prepareOpaque(std::move(result.image)); + } + return result; +} + QImage prepareBlur(QImage img) { if (img.isNull()) { return img; diff --git a/ui/image/image_prepare.h b/ui/image/image_prepare.h index 60261b7..5683027 100644 --- a/ui/image/image_prepare.h +++ b/ui/image/image_prepare.h @@ -39,6 +39,26 @@ namespace Images { int radius, const style::color &color); + +// Try to read images up to 64MB. +inline constexpr auto kReadBytesLimit = 64 * 1024 * 1024; +inline constexpr auto kReadMaxArea = 12'032 * 9'024; + +struct ReadArgs { + QString path; + QByteArray content; + QSize maxSize; + bool forceOpaque = false; + bool returnContent = false; +}; +struct ReadResult { + QImage image; + QByteArray content; + QByteArray format; + bool animated = false; +}; +[[nodiscard]] ReadResult Read(ReadArgs &&args); + QImage prepareBlur(QImage image); void prepareRound( QImage &image,