Create ImagePtr-s using a factory method.

This commit is contained in:
John Preston 2018-10-23 13:08:50 +04:00
parent 591fbf0ec6
commit 8b76428c7e
17 changed files with 348 additions and 439 deletions

View File

@ -950,7 +950,7 @@ namespace App {
auto &d = size.c_photoSize(); auto &d = size.c_photoSize();
if (d.vlocation.type() == mtpc_fileLocation) { if (d.vlocation.type() == mtpc_fileLocation) {
auto &l = d.vlocation.c_fileLocation(); auto &l = d.vlocation.c_fileLocation();
return ImagePtr( return Images::Create(
StorageImageLocation( StorageImageLocation(
d.vw.v, d.vw.v,
d.vh.v, d.vh.v,
@ -967,7 +967,7 @@ namespace App {
if (d.vlocation.type() == mtpc_fileLocation) { if (d.vlocation.type() == mtpc_fileLocation) {
auto &l = d.vlocation.c_fileLocation(); auto &l = d.vlocation.c_fileLocation();
auto bytes = qba(d.vbytes); auto bytes = qba(d.vbytes);
return ImagePtr( return Images::Create(
StorageImageLocation( StorageImageLocation(
d.vw.v, d.vw.v,
d.vh.v, d.vh.v,
@ -979,7 +979,7 @@ namespace App {
bytes); bytes);
} else if (d.vlocation.type() == mtpc_fileLocationUnavailable) { } else if (d.vlocation.type() == mtpc_fileLocationUnavailable) {
auto bytes = qba(d.vbytes); auto bytes = qba(d.vbytes);
return ImagePtr( return Images::Create(
StorageImageLocation( StorageImageLocation(
d.vw.v, d.vw.v,
d.vh.v, d.vh.v,

View File

@ -94,7 +94,7 @@ BackgroundBox::Inner::Inner(QWidget *parent) : TWidget(parent)
void BackgroundBox::Inner::gotWallpapers(const MTPVector<MTPWallPaper> &result) { void BackgroundBox::Inner::gotWallpapers(const MTPVector<MTPWallPaper> &result) {
App::WallPapers wallpapers; App::WallPapers wallpapers;
auto oldBackground = ImagePtr(qsl(":/gui/art/bg_initial.jpg")); auto oldBackground = Images::Create(qsl(":/gui/art/bg_initial.jpg"), "JPG");
wallpapers.push_back(App::WallPaper(Window::Theme::kInitialBackground, oldBackground, oldBackground)); wallpapers.push_back(App::WallPaper(Window::Theme::kInitialBackground, oldBackground, oldBackground));
auto &v = result.v; auto &v = result.v;
for_const (auto &w, v) { for_const (auto &w, v) {

View File

@ -679,7 +679,7 @@ ConfirmInviteBox::ConfirmInviteBox(
size, size,
data.vphoto_small); data.vphoto_small);
if (!location.isNull()) { if (!location.isNull()) {
_photo = ImagePtr(location); _photo = Images::Create(location);
if (!_photo->loaded()) { if (!_photo->loaded()) {
subscribe(Auth().downloaderTaskFinished(), [this] { update(); }); subscribe(Auth().downloaderTaskFinished(), [this] { update(); });
_photo->load(Data::FileOrigin()); _photo->load(Data::FileOrigin());

View File

@ -661,7 +661,7 @@ bool DocumentData::loaded(FilePathResolveType type) const {
that->_location = FileLocation(_loader->fileName()); that->_location = FileLocation(_loader->fileName());
that->_data = _loader->bytes(); that->_data = _loader->bytes();
if (that->sticker() && !_loader->imageData().isNull()) { if (that->sticker() && !_loader->imageData().isNull()) {
that->sticker()->img = ImagePtr(_data, _loader->imageFormat(), _loader->imageData()); that->sticker()->img = Images::Create(_data, _loader->imageFormat(), _loader->imageData());
} }
destroyLoaderDelayed(); destroyLoaderDelayed();
} }
@ -954,7 +954,7 @@ ImagePtr DocumentData::makeReplyPreview(Data::FileOrigin origin) {
auto options = Images::Option::Smooth | (isVideoMessage() ? Images::Option::Circled : Images::Option::None) | Images::Option::TransparentBackground; auto options = Images::Option::Smooth | (isVideoMessage() ? Images::Option::Circled : Images::Option::None) | Images::Option::TransparentBackground;
auto outerSize = st::msgReplyBarSize.height(); auto outerSize = st::msgReplyBarSize.height();
auto image = thumb->pixNoCache(origin, thumbSize.width(), thumbSize.height(), options, outerSize, outerSize); auto image = thumb->pixNoCache(origin, thumbSize.width(), thumbSize.height(), options, outerSize, outerSize);
replyPreview = ImagePtr(image.toImage(), "PNG"); replyPreview = Images::Create(image.toImage(), "PNG");
} else { } else {
thumb->load(origin); thumb->load(origin);
} }
@ -977,11 +977,11 @@ void DocumentData::checkSticker() {
if (_data.isEmpty()) { if (_data.isEmpty()) {
const auto &loc = location(true); const auto &loc = location(true);
if (loc.accessEnable()) { if (loc.accessEnable()) {
data->img = ImagePtr(loc.name()); data->img = Images::Create(loc.name(), "WEBP");
loc.accessDisable(); loc.accessDisable();
} }
} else { } else {
data->img = ImagePtr(_data); data->img = Images::Create(_data, "WEBP");
} }
} }
} }

View File

@ -57,8 +57,7 @@ Invoice ComputeInvoiceData(const MTPDmessageMediaInvoice &data) {
result.receiptMsgId = data.vreceipt_msg_id.v; result.receiptMsgId = data.vreceipt_msg_id.v;
} }
if (data.has_photo()) { if (data.has_photo()) {
const auto thumb = ImagePtr(); result.photo = Auth().data().photoFromWeb(data.vphoto);
result.photo = Auth().data().photoFromWeb(data.vphoto, thumb);
} }
return result; return result;
} }

View File

@ -287,7 +287,7 @@ void PeerData::updateUserpic(
const MTPFileLocation &location) { const MTPFileLocation &location) {
const auto size = kUserpicSize; const auto size = kUserpicSize;
const auto loc = StorageImageLocation::FromMTP(size, size, location); const auto loc = StorageImageLocation::FromMTP(size, size, location);
const auto photo = loc.isNull() ? ImagePtr() : ImagePtr(loc); const auto photo = loc.isNull() ? ImagePtr() : Images::Create(loc);
setUserpicChecked(photoId, loc, photo); setUserpicChecked(photoId, loc, photo);
} }
@ -301,7 +301,7 @@ void PeerData::clearUserpic() {
Qt::SmoothTransformation); Qt::SmoothTransformation);
return _userpic return _userpic
? _userpic ? _userpic
: ImagePtr(std::move(image), "PNG"); : Images::Create(std::move(image), "PNG");
} }
return ImagePtr(); return ImagePtr();
}(); }();

View File

@ -120,7 +120,7 @@ ImagePtr PhotoData::makeReplyPreview(Data::FileOrigin origin) {
int w = image->width(), h = image->height(); int w = image->width(), h = image->height();
if (w <= 0) w = 1; if (w <= 0) w = 1;
if (h <= 0) h = 1; if (h <= 0) h = 1;
return ImagePtr( return Images::Create(
(w > h (w > h
? image->pix( ? image->pix(
origin, origin,

View File

@ -813,9 +813,9 @@ not_null<PhotoData*> Session::photo(
data.c_photo().vaccess_hash.v, data.c_photo().vaccess_hash.v,
data.c_photo().vfile_reference.v, data.c_photo().vfile_reference.v,
data.c_photo().vdate.v, data.c_photo().vdate.v,
ImagePtr(base::duplicate(*thumb), "JPG"), Images::Create(base::duplicate(*thumb), "JPG"),
ImagePtr(base::duplicate(*medium), "JPG"), Images::Create(base::duplicate(*medium), "JPG"),
ImagePtr(base::duplicate(*full), "JPG")); Images::Create(base::duplicate(*full), "JPG"));
case mtpc_photoEmpty: case mtpc_photoEmpty:
return photo(data.c_photoEmpty().vid.v); return photo(data.c_photoEmpty().vid.v);
@ -875,20 +875,24 @@ void Session::photoConvert(
PhotoData *Session::photoFromWeb( PhotoData *Session::photoFromWeb(
const MTPWebDocument &data, const MTPWebDocument &data,
ImagePtr thumb) { ImagePtr thumb,
const auto full = ImagePtr(data); bool willBecomeNormal) {
const auto full = Images::Create(data);
if (full->isNull()) { if (full->isNull()) {
return nullptr; return nullptr;
} }
//const auto width = full->width(); auto medium = ImagePtr();
//const auto height = full->height(); if (willBecomeNormal) {
//if (thumb->isNull()) { const auto width = full->width();
// auto thumbsize = shrinkToKeepAspect(width, height, 100, 100); const auto height = full->height();
// thumb = ImagePtr(thumbsize.width(), thumbsize.height()); if (thumb->isNull()) {
//} auto thumbsize = shrinkToKeepAspect(width, height, 100, 100);
thumb = Images::Create(thumbsize.width(), thumbsize.height());
}
//auto mediumsize = shrinkToKeepAspect(width, height, 320, 320); auto mediumsize = shrinkToKeepAspect(width, height, 320, 320);
//auto medium = ImagePtr(mediumsize.width(), mediumsize.height()); medium = Images::Create(mediumsize.width(), mediumsize.height());
}
return photo( return photo(
rand_value<PhotoId>(), rand_value<PhotoId>(),
@ -896,7 +900,7 @@ PhotoData *Session::photoFromWeb(
QByteArray(), QByteArray(),
unixtime(), unixtime(),
thumb, thumb,
ImagePtr(), medium,
full); full);
} }
@ -911,7 +915,7 @@ void Session::photoApplyFields(
void Session::photoApplyFields( void Session::photoApplyFields(
not_null<PhotoData*> photo, not_null<PhotoData*> photo,
const MTPDphoto &data) { const MTPDphoto &data) {
auto thumb = (const MTPPhotoSize*)nullptr; auto thumb = (const MTPPhotoSize*)nullptr;
auto medium = (const MTPPhotoSize*)nullptr; auto medium = (const MTPPhotoSize*)nullptr;
auto full = (const MTPPhotoSize*)nullptr; auto full = (const MTPPhotoSize*)nullptr;
auto thumbLevel = -1; auto thumbLevel = -1;
@ -1027,7 +1031,7 @@ not_null<DocumentData*> Session::document(
fields.vdate.v, fields.vdate.v,
fields.vattributes.v, fields.vattributes.v,
qs(fields.vmime_type), qs(fields.vmime_type),
ImagePtr(std::move(thumb), "JPG"), Images::Create(std::move(thumb), "JPG"),
fields.vdc_id.v, fields.vdc_id.v,
fields.vsize.v, fields.vsize.v,
StorageImageLocation()); StorageImageLocation());

View File

@ -262,7 +262,10 @@ public:
void photoConvert( void photoConvert(
not_null<PhotoData*> original, not_null<PhotoData*> original,
const MTPPhoto &data); const MTPPhoto &data);
PhotoData *photoFromWeb(const MTPWebDocument &data, ImagePtr thumb); PhotoData *photoFromWeb(
const MTPWebDocument &data,
ImagePtr thumb = ImagePtr(),
bool willBecomeNormal = false);
not_null<DocumentData*> document(DocumentId id); not_null<DocumentData*> document(DocumentId id);
not_null<DocumentData*> document(const MTPDocument &data); not_null<DocumentData*> document(const MTPDocument &data);

View File

@ -57,7 +57,7 @@ void LocationClickHandler::setup() {
LocationData::LocationData(const LocationCoords &coords) LocationData::LocationData(const LocationCoords &coords)
: coords(coords) : coords(coords)
, thumb(ComputeLocation(coords)) { , thumb(Images::Create(ComputeLocation(coords))) {
} }
void LocationData::load(Data::FileOrigin origin) { void LocationData::load(Data::FileOrigin origin) {

View File

@ -79,14 +79,15 @@ std::unique_ptr<Result> Result::create(uint64 queryId, const MTPBotInlineResult
if (r.has_description()) result->_description = qs(r.vdescription); if (r.has_description()) result->_description = qs(r.vdescription);
if (r.has_url()) result->_url = qs(r.vurl); if (r.has_url()) result->_url = qs(r.vurl);
if (r.has_thumb()) { if (r.has_thumb()) {
result->_thumb = ImagePtr(r.vthumb, result->thumbBox()); result->_thumb = Images::Create(r.vthumb, result->thumbBox());
} }
if (r.has_content()) { if (r.has_content()) {
result->_content_url = GetContentUrl(r.vcontent); result->_content_url = GetContentUrl(r.vcontent);
if (result->_type == Type::Photo) { if (result->_type == Type::Photo) {
result->_photo = Auth().data().photoFromWeb( result->_photo = Auth().data().photoFromWeb(
r.vcontent, r.vcontent,
result->_thumb); result->_thumb,
true);
} else { } else {
result->_document = Auth().data().documentFromWeb( result->_document = Auth().data().documentFromWeb(
result->adjustAttributes(r.vcontent), result->adjustAttributes(r.vcontent),
@ -237,7 +238,7 @@ std::unique_ptr<Result> Result::create(uint64 queryId, const MTPBotInlineResult
location.height = h; location.height = h;
location.zoom = zoom; location.zoom = zoom;
location.scale = scale; location.scale = scale;
result->_locationThumb = ImagePtr(location); result->_locationThumb = Images::Create(location);
} }
return result; return result;

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/serialize_common.h" #include "storage/serialize_common.h"
#include "auth_session.h" #include "auth_session.h"
#include "ui/image.h"
namespace Serialize { namespace Serialize {
@ -255,7 +256,7 @@ PeerData *readPeer(int streamAppVersion, QDataStream &stream) {
result->setUserpic( result->setUserpic(
photoId, photoId,
photoLoc, photoLoc,
photoLoc.isNull() ? ImagePtr() : ImagePtr(photoLoc)); photoLoc.isNull() ? ImagePtr() : Images::Create(photoLoc));
} }
return result; return result;
} }

View File

@ -137,7 +137,7 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream &
date, date,
attributes, attributes,
mime, mime,
thumb.isNull() ? ImagePtr() : ImagePtr(thumb), thumb.isNull() ? ImagePtr() : Images::Create(thumb),
dc, dc,
size, size,
thumb); thumb);

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h" #include "history/history.h"
#include "auth_session.h" #include "auth_session.h"
namespace Images {
namespace { namespace {
QMap<QString, Image*> LocalFileImages; QMap<QString, Image*> LocalFileImages;
@ -35,8 +36,6 @@ uint64 SinglePixKey(Images::Options options) {
} // namespace } // namespace
namespace Images {
void ClearRemote() { void ClearRemote() {
for (auto image : base::take(StorageImages)) { for (auto image : base::take(StorageImages)) {
delete image; delete image;
@ -68,6 +67,251 @@ void CheckCacheSize() {
} }
} }
ImagePtr Create(const QString &file, QByteArray format) {
if (file.startsWith(qstr("http://"), Qt::CaseInsensitive)
|| file.startsWith(qstr("https://"), Qt::CaseInsensitive)) {
const auto key = file;
auto i = WebUrlImages.constFind(key);
if (i == WebUrlImages.cend()) {
i = WebUrlImages.insert(
key,
new Image(std::make_unique<WebUrlSource>(file)));
}
return ImagePtr(i.value());
} else {
QFileInfo f(file);
const auto key = qsl("//:%1//:%2//:"
).arg(f.size()
).arg(f.lastModified().toTime_t()
) + file;
auto i = LocalFileImages.constFind(key);
if (i == LocalFileImages.cend()) {
i = LocalFileImages.insert(
key,
new Image(std::make_unique<LocalFileSource>(
file,
QByteArray(),
format)));
}
return ImagePtr(i.value());
}
}
ImagePtr Create(const QString &url, QSize box) {
const auto key = qsl("//:%1//:%2//:").arg(box.width()).arg(box.height()) + url;
auto i = WebUrlImages.constFind(key);
if (i == WebUrlImages.cend()) {
i = WebUrlImages.insert(
key,
new Image(std::make_unique<WebUrlSource>(url, box)));
}
return ImagePtr(i.value());
}
ImagePtr Create(const QString &url, int width, int height) {
const auto key = url;
auto i = WebUrlImages.constFind(key);
if (i == WebUrlImages.cend()) {
i = WebUrlImages.insert(
key,
new Image(std::make_unique<WebUrlSource>(url, width, height)));
} else {
i.value()->setInformation(0, width, height);
}
return ImagePtr(i.value());
}
ImagePtr Create(const QByteArray &filecontent, QByteArray format) {
auto image = App::readImage(filecontent, &format, false);
return Create(filecontent, format, std::move(image));
}
ImagePtr Create(QImage &&image, QByteArray format) {
return ImagePtr(new Image(std::make_unique<ImageSource>(
std::move(image),
format)));
}
ImagePtr Create(
const QByteArray &filecontent,
QByteArray format,
QImage &&image) {
return ImagePtr(new Image(std::make_unique<LocalFileSource>(
QString(),
filecontent,
format,
std::move(image))));
}
ImagePtr Create(int width, int height) {
return ImagePtr(new Image(std::make_unique<DelayedStorageSource>(
width,
height)));
}
ImagePtr Create(const StorageImageLocation &location, int size) {
const auto key = storageKey(location);
auto i = StorageImages.constFind(key);
if (i == StorageImages.cend()) {
i = StorageImages.insert(
key,
new Image(std::make_unique<StorageSource>(location, size)));
} else {
i.value()->refreshFileReference(location.fileReference());
}
return ImagePtr(i.value());
}
ImagePtr Create(
const StorageImageLocation &location,
const QByteArray &bytes) {
const auto key = storageKey(location);
auto i = StorageImages.constFind(key);
if (i == StorageImages.cend()) {
i = StorageImages.insert(
key,
new Image(std::make_unique<StorageSource>(
location,
bytes.size())));
} else {
i.value()->refreshFileReference(location.fileReference());
}
i.value()->setImageBytes(bytes);
return ImagePtr(i.value());
}
QSize getImageSize(const QVector<MTPDocumentAttribute> &attributes) {
for (const auto &attribute : attributes) {
if (attribute.type() == mtpc_documentAttributeImageSize) {
auto &size = attribute.c_documentAttributeImageSize();
return QSize(size.vw.v, size.vh.v);
}
}
return QSize();
}
ImagePtr Create(const MTPDwebDocument &document) {
const auto size = getImageSize(document.vattributes.v);
if (size.isEmpty()) {
return Image::Blank();
}
// We don't use size from WebDocument, because it is not reliable.
// It can be > 0 and different from the real size that we get in upload.WebFile result.
auto filesize = 0; // document.vsize.v;
return Create(
WebFileLocation(
Global::WebFileDcId(),
document.vurl.v,
document.vaccess_hash.v),
size.width(),
size.height(),
filesize);
}
ImagePtr Create(const MTPDwebDocumentNoProxy &document) {
const auto size = getImageSize(document.vattributes.v);
if (size.isEmpty()) {
return Image::Blank();
}
return Create(qs(document.vurl), size.width(), size.height());
}
ImagePtr Create(const MTPDwebDocument &document, QSize box) {
//const auto size = getImageSize(document.vattributes.v);
//if (size.isEmpty()) {
// return Image::Blank();
//}
// We don't use size from WebDocument, because it is not reliable.
// It can be > 0 and different from the real size that we get in upload.WebFile result.
auto filesize = 0; // document.vsize.v;
return Create(
WebFileLocation(
Global::WebFileDcId(),
document.vurl.v,
document.vaccess_hash.v),
box,
filesize);
}
ImagePtr Create(const MTPDwebDocumentNoProxy &document, QSize box) {
//const auto size = getImageSize(document.vattributes.v);
//if (size.isEmpty()) {
// return Image::Blank();
//}
return Create(qs(document.vurl), box);
}
ImagePtr Create(const MTPWebDocument &document) {
switch (document.type()) {
case mtpc_webDocument:
return Create(document.c_webDocument());
case mtpc_webDocumentNoProxy:
return Create(document.c_webDocumentNoProxy());
}
Unexpected("Type in getImage(MTPWebDocument).");
}
ImagePtr Create(const MTPWebDocument &document, QSize box) {
switch (document.type()) {
case mtpc_webDocument:
return Create(document.c_webDocument(), box);
case mtpc_webDocumentNoProxy:
return Create(document.c_webDocumentNoProxy(), box);
}
Unexpected("Type in getImage(MTPWebDocument).");
}
ImagePtr Create(
const WebFileLocation &location,
QSize box,
int size) {
const auto key = storageKey(location);
auto i = WebCachedImages.constFind(key);
if (i == WebCachedImages.cend()) {
i = WebCachedImages.insert(
key,
new Image(std::make_unique<WebCachedSource>(
location,
box,
size)));
}
return ImagePtr(i.value());
}
ImagePtr Create(
const WebFileLocation &location,
int width,
int height,
int size) {
const auto key = storageKey(location);
auto i = WebCachedImages.constFind(key);
if (i == WebCachedImages.cend()) {
i = WebCachedImages.insert(
key,
new Image(std::make_unique<WebCachedSource>(
location,
width,
height,
size)));
}
return ImagePtr(i.value());
}
ImagePtr Create(const GeoPointLocation &location) {
const auto key = storageKey(location);
auto i = GeoPointImages.constFind(key);
if (i == GeoPointImages.cend()) {
i = GeoPointImages.insert(
key,
new Image(std::make_unique<GeoPointSource>(location)));
}
return ImagePtr(i.value());
}
Source::~Source() = default; Source::~Source() = default;
ImageSource::ImageSource(QImage &&data, const QByteArray &format) ImageSource::ImageSource(QImage &&data, const QByteArray &format)
@ -782,7 +1026,7 @@ void Image::replaceSource(std::unique_ptr<Images::Source> &&source) {
_source = std::move(source); _source = std::move(source);
} }
Image *Image::Blank() { ImagePtr Image::Blank() {
static const auto blankImage = [] { static const auto blankImage = [] {
const auto factor = cIntRetinaFactor(); const auto factor = cIntRetinaFactor();
auto data = QImage( auto data = QImage(
@ -791,7 +1035,7 @@ Image *Image::Blank() {
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
data.fill(Qt::transparent); data.fill(Qt::transparent);
data.setDevicePixelRatio(cRetinaFactor()); data.setDevicePixelRatio(cRetinaFactor());
return Images::details::Create( return Images::Create(
std::move(data), std::move(data),
"GIF"); "GIF");
}(); }();
@ -799,7 +1043,7 @@ Image *Image::Blank() {
} }
bool Image::isNull() const { bool Image::isNull() const {
return (this == Blank()); return (this == Blank().get());
} }
const QPixmap &Image::pix( const QPixmap &Image::pix(
@ -815,14 +1059,14 @@ const QPixmap &Image::pix(
h *= cIntRetinaFactor(); h *= cIntRetinaFactor();
} }
auto options = Images::Option::Smooth | Images::Option::None; auto options = Images::Option::Smooth | Images::Option::None;
auto k = PixKey(w, h, options); auto k = Images::PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4; Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
} }
} }
return i.value(); return i.value();
@ -856,14 +1100,14 @@ const QPixmap &Image::pixRounded(
} else if (radius == ImageRoundRadius::Ellipse) { } else if (radius == ImageRoundRadius::Ellipse) {
options |= Images::Option::Circled | cornerOptions(corners); options |= Images::Option::Circled | cornerOptions(corners);
} }
auto k = PixKey(w, h, options); auto k = Images::PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4; Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
} }
} }
return i.value(); return i.value();
@ -882,14 +1126,14 @@ const QPixmap &Image::pixCircled(
h *= cIntRetinaFactor(); h *= cIntRetinaFactor();
} }
auto options = Images::Option::Smooth | Images::Option::Circled; auto options = Images::Option::Smooth | Images::Option::Circled;
auto k = PixKey(w, h, options); auto k = Images::PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4; Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
} }
} }
return i.value(); return i.value();
@ -908,14 +1152,14 @@ const QPixmap &Image::pixBlurredCircled(
h *= cIntRetinaFactor(); h *= cIntRetinaFactor();
} }
auto options = Images::Option::Smooth | Images::Option::Circled | Images::Option::Blurred; auto options = Images::Option::Smooth | Images::Option::Circled | Images::Option::Blurred;
auto k = PixKey(w, h, options); auto k = Images::PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4; Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
} }
} }
return i.value(); return i.value();
@ -934,14 +1178,14 @@ const QPixmap &Image::pixBlurred(
h *= cIntRetinaFactor(); h *= cIntRetinaFactor();
} }
auto options = Images::Option::Smooth | Images::Option::Blurred; auto options = Images::Option::Smooth | Images::Option::Blurred;
auto k = PixKey(w, h, options); auto k = Images::PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options); auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4; Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
} }
} }
return i.value(); return i.value();
@ -961,14 +1205,14 @@ const QPixmap &Image::pixColored(
h *= cIntRetinaFactor(); h *= cIntRetinaFactor();
} }
auto options = Images::Option::Smooth | Images::Option::Colored; auto options = Images::Option::Smooth | Images::Option::Colored;
auto k = PixKey(w, h, options); auto k = Images::PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixColoredNoCache(origin, add, w, h, true); auto p = pixColoredNoCache(origin, add, w, h, true);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4; Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
} }
} }
return i.value(); return i.value();
@ -988,14 +1232,14 @@ const QPixmap &Image::pixBlurredColored(
h *= cIntRetinaFactor(); h *= cIntRetinaFactor();
} }
auto options = Images::Option::Blurred | Images::Option::Smooth | Images::Option::Colored; auto options = Images::Option::Blurred | Images::Option::Smooth | Images::Option::Colored;
auto k = PixKey(w, h, options); auto k = Images::PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixBlurredColoredNoCache(origin, add, w, h); auto p = pixBlurredColoredNoCache(origin, add, w, h);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4; Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
} }
} }
return i.value(); return i.value();
@ -1037,17 +1281,17 @@ const QPixmap &Image::pixSingle(
options |= Images::Option::Colored; options |= Images::Option::Colored;
} }
auto k = SinglePixKey(options); auto k = Images::SinglePixKey(options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) { if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) {
if (i != _sizesCache.cend()) { if (i != _sizesCache.cend()) {
GlobalAcquiredSize -= int64(i->width()) * i->height() * 4; Images::GlobalAcquiredSize -= int64(i->width()) * i->height() * 4;
} }
auto p = pixNoCache(origin, w, h, options, outerw, outerh, colored); auto p = pixNoCache(origin, w, h, options, outerw, outerh, colored);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4; Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
} }
} }
return i.value(); return i.value();
@ -1085,17 +1329,17 @@ const QPixmap &Image::pixBlurredSingle(
options |= Images::Option::Circled | cornerOptions(corners); options |= Images::Option::Circled | cornerOptions(corners);
} }
auto k = SinglePixKey(options); auto k = Images::SinglePixKey(options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) { if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) {
if (i != _sizesCache.cend()) { if (i != _sizesCache.cend()) {
GlobalAcquiredSize -= int64(i->width()) * i->height() * 4; Images::GlobalAcquiredSize -= int64(i->width()) * i->height() * 4;
} }
auto p = pixNoCache(origin, w, h, options, outerw, outerh); auto p = pixNoCache(origin, w, h, options, outerw, outerh);
p.setDevicePixelRatio(cRetinaFactor()); p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4; Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
} }
} }
return i.value(); return i.value();
@ -1228,7 +1472,7 @@ void Image::checkSource() const {
invalidateSizeCache(); invalidateSizeCache();
_data = std::move(data); _data = std::move(data);
if (!_data.isNull()) { if (!_data.isNull()) {
GlobalAcquiredSize += int64(_data.width()) * _data.height() * 4; Images::GlobalAcquiredSize += int64(_data.width()) * _data.height() * 4;
} }
} }
} }
@ -1238,7 +1482,7 @@ void Image::forget() const {
_source->forget(); _source->forget();
invalidateSizeCache(); invalidateSizeCache();
if (!_data.isNull()) { if (!_data.isNull()) {
GlobalAcquiredSize -= int64(_data.width()) * _data.height() * 4; Images::GlobalAcquiredSize -= int64(_data.width()) * _data.height() * 4;
_data = QImage(); _data = QImage();
} }
} }
@ -1260,7 +1504,7 @@ void Image::setImageBytes(const QByteArray &bytes) {
void Image::invalidateSizeCache() const { void Image::invalidateSizeCache() const {
for (const auto &image : std::as_const(_sizesCache)) { for (const auto &image : std::as_const(_sizesCache)) {
if (!image.isNull()) { if (!image.isNull()) {
GlobalAcquiredSize -= int64(image.width()) * image.height() * 4; Images::GlobalAcquiredSize -= int64(image.width()) * image.height() * 4;
} }
} }
_sizesCache.clear(); _sizesCache.clear();
@ -1269,252 +1513,3 @@ void Image::invalidateSizeCache() const {
Image::~Image() { Image::~Image() {
forget(); forget();
} }
namespace Images {
namespace details {
Image *Create(const QString &file, QByteArray format) {
if (file.startsWith(qstr("http://"), Qt::CaseInsensitive)
|| file.startsWith(qstr("https://"), Qt::CaseInsensitive)) {
const auto key = file;
auto i = WebUrlImages.constFind(key);
if (i == WebUrlImages.cend()) {
i = WebUrlImages.insert(
key,
new Image(std::make_unique<WebUrlSource>(file)));
}
return i.value();
} else {
QFileInfo f(file);
const auto key = qsl("//:%1//:%2//:"
).arg(f.size()
).arg(f.lastModified().toTime_t()
) + file;
auto i = LocalFileImages.constFind(key);
if (i == LocalFileImages.cend()) {
i = LocalFileImages.insert(
key,
new Image(std::make_unique<LocalFileSource>(
file,
QByteArray(),
format)));
}
return i.value();
}
}
Image *Create(const QString &url, QSize box) {
const auto key = qsl("//:%1//:%2//:").arg(box.width()).arg(box.height()) + url;
auto i = WebUrlImages.constFind(key);
if (i == WebUrlImages.cend()) {
i = WebUrlImages.insert(
key,
new Image(std::make_unique<WebUrlSource>(url, box)));
}
return i.value();
}
Image *Create(const QString &url, int width, int height) {
const auto key = url;
auto i = WebUrlImages.constFind(key);
if (i == WebUrlImages.cend()) {
i = WebUrlImages.insert(
key,
new Image(std::make_unique<WebUrlSource>(url, width, height)));
} else {
i.value()->setInformation(0, width, height);
}
return i.value();
}
Image *Create(const QByteArray &filecontent, QByteArray format) {
auto image = App::readImage(filecontent, &format, false);
return Create(filecontent, format, std::move(image));
}
Image *Create(QImage &&image, QByteArray format) {
return new Image(std::make_unique<ImageSource>(
std::move(image),
format));
}
Image *Create(
const QByteArray &filecontent,
QByteArray format,
QImage &&image) {
return new Image(std::make_unique<LocalFileSource>(
QString(),
filecontent,
format,
std::move(image)));
}
Image *Create(int width, int height) {
return new Image(std::make_unique<DelayedStorageSource>(width, height));
}
Image *Create(const StorageImageLocation &location, int size) {
const auto key = storageKey(location);
auto i = StorageImages.constFind(key);
if (i == StorageImages.cend()) {
i = StorageImages.insert(
key,
new Image(std::make_unique<StorageSource>(location, size)));
} else {
i.value()->refreshFileReference(location.fileReference());
}
return i.value();
}
Image *Create(
const StorageImageLocation &location,
const QByteArray &bytes) {
const auto key = storageKey(location);
auto i = StorageImages.constFind(key);
if (i == StorageImages.cend()) {
i = StorageImages.insert(
key,
new Image(std::make_unique<StorageSource>(
location,
bytes.size())));
} else {
i.value()->refreshFileReference(location.fileReference());
}
i.value()->setImageBytes(bytes);
return i.value();
}
QSize getImageSize(const QVector<MTPDocumentAttribute> &attributes) {
for (const auto &attribute : attributes) {
if (attribute.type() == mtpc_documentAttributeImageSize) {
auto &size = attribute.c_documentAttributeImageSize();
return QSize(size.vw.v, size.vh.v);
}
}
return QSize();
}
Image *Create(const MTPDwebDocument &document) {
const auto size = getImageSize(document.vattributes.v);
if (size.isEmpty()) {
return Image::Blank();
}
// We don't use size from WebDocument, because it is not reliable.
// It can be > 0 and different from the real size that we get in upload.WebFile result.
auto filesize = 0; // document.vsize.v;
return Create(
WebFileLocation(
Global::WebFileDcId(),
document.vurl.v,
document.vaccess_hash.v),
size.width(),
size.height(),
filesize);
}
Image *Create(const MTPDwebDocumentNoProxy &document) {
const auto size = getImageSize(document.vattributes.v);
if (size.isEmpty()) {
return Image::Blank();
}
return Create(qs(document.vurl), size.width(), size.height());
}
Image *Create(const MTPDwebDocument &document, QSize box) {
//const auto size = getImageSize(document.vattributes.v);
//if (size.isEmpty()) {
// return Image::Blank();
//}
// We don't use size from WebDocument, because it is not reliable.
// It can be > 0 and different from the real size that we get in upload.WebFile result.
auto filesize = 0; // document.vsize.v;
return Create(
WebFileLocation(
Global::WebFileDcId(),
document.vurl.v,
document.vaccess_hash.v),
box,
filesize);
}
Image *Create(const MTPDwebDocumentNoProxy &document, QSize box) {
//const auto size = getImageSize(document.vattributes.v);
//if (size.isEmpty()) {
// return Image::Blank();
//}
return Create(qs(document.vurl), box);
}
Image *Create(const MTPWebDocument &document) {
switch (document.type()) {
case mtpc_webDocument:
return Create(document.c_webDocument());
case mtpc_webDocumentNoProxy:
return Create(document.c_webDocumentNoProxy());
}
Unexpected("Type in getImage(MTPWebDocument).");
}
Image *Create(const MTPWebDocument &document, QSize box) {
switch (document.type()) {
case mtpc_webDocument:
return Create(document.c_webDocument(), box);
case mtpc_webDocumentNoProxy:
return Create(document.c_webDocumentNoProxy(), box);
}
Unexpected("Type in getImage(MTPWebDocument).");
}
Image *Create(
const WebFileLocation &location,
QSize box,
int size) {
const auto key = storageKey(location);
auto i = WebCachedImages.constFind(key);
if (i == WebCachedImages.cend()) {
i = WebCachedImages.insert(
key,
new Image(std::make_unique<WebCachedSource>(
location,
box,
size)));
}
return i.value();
}
Image *Create(
const WebFileLocation &location,
int width,
int height,
int size) {
const auto key = storageKey(location);
auto i = WebCachedImages.constFind(key);
if (i == WebCachedImages.cend()) {
i = WebCachedImages.insert(
key,
new Image(std::make_unique<WebCachedSource>(
location,
width,
height,
size)));
}
return i.value();
}
Image *Create(const GeoPointLocation &location) {
const auto key = storageKey(location);
auto i = GeoPointImages.constFind(key);
if (i == GeoPointImages.cend()) {
i = GeoPointImages.insert(
key,
new Image(std::make_unique<GeoPointSource>(location)));
}
return i.value();
}
} // namespace detals
} // namespace Images

View File

@ -13,6 +13,33 @@ void ClearRemote();
void ClearAll(); void ClearAll();
void CheckCacheSize(); void CheckCacheSize();
ImagePtr Create(const QString &file, QByteArray format);
ImagePtr Create(const QString &url, QSize box);
ImagePtr Create(const QString &url, int width, int height);
ImagePtr Create(const QByteArray &filecontent, QByteArray format);
ImagePtr Create(QImage &&data, QByteArray format);
ImagePtr Create(
const QByteArray &filecontent,
QByteArray format,
QImage &&data);
ImagePtr Create(int width, int height);
ImagePtr Create(const StorageImageLocation &location, int size = 0);
ImagePtr Create( // photoCachedSize
const StorageImageLocation &location,
const QByteArray &bytes);
ImagePtr Create(const MTPWebDocument &location);
ImagePtr Create(const MTPWebDocument &location, QSize box);
ImagePtr Create(
const WebFileLocation &location,
int width,
int height,
int size = 0);
ImagePtr Create(
const WebFileLocation &location,
QSize box,
int size = 0);
ImagePtr Create(const GeoPointLocation &location);
class Source { class Source {
public: public:
virtual ~Source(); virtual ~Source();
@ -370,7 +397,7 @@ public:
void replaceSource(std::unique_ptr<Images::Source> &&source); void replaceSource(std::unique_ptr<Images::Source> &&source);
static Image *Blank(); static ImagePtr Blank();
const QPixmap &pix( const QPixmap &pix(
Data::FileOrigin origin, Data::FileOrigin origin,
@ -522,37 +549,3 @@ private:
mutable QImage _data; mutable QImage _data;
}; };
namespace Images {
namespace details {
Image *Create(const QString &file, QByteArray format);
Image *Create(const QString &url, QSize box);
Image *Create(const QString &url, int width, int height);
Image *Create(const QByteArray &filecontent, QByteArray format);
Image *Create(QImage &&data, QByteArray format);
Image *Create(
const QByteArray &filecontent,
QByteArray format,
QImage &&data);
Image *Create(int width, int height);
Image *Create(const StorageImageLocation &location, int size = 0);
Image *Create( // photoCachedSize
const StorageImageLocation &location,
const QByteArray &bytes);
Image *Create(const MTPWebDocument &location);
Image *Create(const MTPWebDocument &location, QSize box);
Image *Create(
const WebFileLocation &location,
int width,
int height,
int size = 0);
Image *Create(
const WebFileLocation &location,
QSize box,
int size = 0);
Image *Create(
const GeoPointLocation &location);
} // namespace details
} // namespace Images

View File

@ -367,83 +367,10 @@ QImage prepare(QImage img, int w, int h, Images::Options options, int outerw, in
} // namespace Images } // namespace Images
ImagePtr::ImagePtr() : _data(Image::Blank()) { ImagePtr::ImagePtr() : _data(Image::Blank().get()) {
} }
ImagePtr::ImagePtr(const QString &file, QByteArray format) ImagePtr::ImagePtr(not_null<Image*> data) : _data(data) {
: _data(Images::details::Create(file, format)) {
}
ImagePtr::ImagePtr(const QString &url, QSize box)
: _data(Images::details::Create(url, box)) {
}
ImagePtr::ImagePtr(const QString &url, int width, int height)
: _data(Images::details::Create(url, width, height)) {
}
ImagePtr::ImagePtr(const QByteArray &filecontent, QByteArray format)
: _data(Images::details::Create(filecontent, format)) {
}
ImagePtr::ImagePtr(
const QByteArray &filecontent,
QByteArray format,
QImage &&data)
: _data(Images::details::Create(filecontent, format, std::move(data))) {
}
ImagePtr::ImagePtr(QImage &&data, QByteArray format)
: _data(Images::details::Create(std::move(data), format)) {
}
ImagePtr::ImagePtr(const StorageImageLocation &location, int32 size)
: _data(Images::details::Create(location, size)) {
}
ImagePtr::ImagePtr(
const StorageImageLocation &location,
const QByteArray &bytes)
: _data(Images::details::Create(location, bytes)) {
}
ImagePtr::ImagePtr(const MTPWebDocument &location)
: _data(Images::details::Create(location)) {
}
ImagePtr::ImagePtr(const MTPWebDocument &location, QSize box)
: _data(Images::details::Create(location, box)) {
}
ImagePtr::ImagePtr(
const WebFileLocation &location,
int width,
int height,
int size)
: _data(Images::details::Create(location, width, height, size)) {
}
ImagePtr::ImagePtr(const WebFileLocation &location, QSize box, int size)
: _data(Images::details::Create(location, box, size)) {
}
ImagePtr::ImagePtr(const GeoPointLocation &location)
: _data(Images::details::Create(location)) {
}
ImagePtr::ImagePtr(
int32 width,
int32 height,
const MTPFileLocation &location,
ImagePtr def)
: _data((location.type() != mtpc_fileLocation)
? def.get()
: (Image*)(Images::details::Create(
StorageImageLocation(width, height, location.c_fileLocation())))) {
}
ImagePtr::ImagePtr(int32 width, int32 height)
: _data(Images::details::Create(width, height)) {
} }
Image *ImagePtr::operator->() const { Image *ImagePtr::operator->() const {

View File

@ -283,21 +283,7 @@ class Image;
class ImagePtr { class ImagePtr {
public: public:
ImagePtr(); ImagePtr();
ImagePtr(const QString &file, QByteArray format = QByteArray()); explicit ImagePtr(not_null<Image*> data);
ImagePtr(const QString &url, QSize box);
ImagePtr(const QString &url, int width, int height);
ImagePtr(const QByteArray &filecontent, QByteArray format = QByteArray());
ImagePtr(const QByteArray &filecontent, QByteArray format, QImage &&data);
ImagePtr(QImage &&data, QByteArray format);
ImagePtr(const StorageImageLocation &location, int32 size = 0);
ImagePtr(const StorageImageLocation &location, const QByteArray &bytes);
ImagePtr(const MTPWebDocument &location);
ImagePtr(const MTPWebDocument &location, QSize box);
ImagePtr(const WebFileLocation &location, int width, int height, int size = 0);
ImagePtr(const WebFileLocation &location, QSize box, int size = 0);
ImagePtr(const GeoPointLocation &location);
ImagePtr(int32 width, int32 height, const MTPFileLocation &location, ImagePtr def = ImagePtr());
ImagePtr(int32 width, int32 height);
Image *operator->() const; Image *operator->() const;
Image *get() const; Image *get() const;