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();
if (d.vlocation.type() == mtpc_fileLocation) {
auto &l = d.vlocation.c_fileLocation();
return ImagePtr(
return Images::Create(
StorageImageLocation(
d.vw.v,
d.vh.v,
@ -967,7 +967,7 @@ namespace App {
if (d.vlocation.type() == mtpc_fileLocation) {
auto &l = d.vlocation.c_fileLocation();
auto bytes = qba(d.vbytes);
return ImagePtr(
return Images::Create(
StorageImageLocation(
d.vw.v,
d.vh.v,
@ -979,7 +979,7 @@ namespace App {
bytes);
} else if (d.vlocation.type() == mtpc_fileLocationUnavailable) {
auto bytes = qba(d.vbytes);
return ImagePtr(
return Images::Create(
StorageImageLocation(
d.vw.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) {
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));
auto &v = result.v;
for_const (auto &w, v) {

View File

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

View File

@ -661,7 +661,7 @@ bool DocumentData::loaded(FilePathResolveType type) const {
that->_location = FileLocation(_loader->fileName());
that->_data = _loader->bytes();
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();
}
@ -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 outerSize = st::msgReplyBarSize.height();
auto image = thumb->pixNoCache(origin, thumbSize.width(), thumbSize.height(), options, outerSize, outerSize);
replyPreview = ImagePtr(image.toImage(), "PNG");
replyPreview = Images::Create(image.toImage(), "PNG");
} else {
thumb->load(origin);
}
@ -977,11 +977,11 @@ void DocumentData::checkSticker() {
if (_data.isEmpty()) {
const auto &loc = location(true);
if (loc.accessEnable()) {
data->img = ImagePtr(loc.name());
data->img = Images::Create(loc.name(), "WEBP");
loc.accessDisable();
}
} 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;
}
if (data.has_photo()) {
const auto thumb = ImagePtr();
result.photo = Auth().data().photoFromWeb(data.vphoto, thumb);
result.photo = Auth().data().photoFromWeb(data.vphoto);
}
return result;
}

View File

@ -287,7 +287,7 @@ void PeerData::updateUserpic(
const MTPFileLocation &location) {
const auto size = kUserpicSize;
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);
}
@ -301,7 +301,7 @@ void PeerData::clearUserpic() {
Qt::SmoothTransformation);
return _userpic
? _userpic
: ImagePtr(std::move(image), "PNG");
: Images::Create(std::move(image), "PNG");
}
return ImagePtr();
}();

View File

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

View File

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

View File

@ -262,7 +262,10 @@ public:
void photoConvert(
not_null<PhotoData*> original,
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(const MTPDocument &data);

View File

@ -57,7 +57,7 @@ void LocationClickHandler::setup() {
LocationData::LocationData(const LocationCoords &coords)
: coords(coords)
, thumb(ComputeLocation(coords)) {
, thumb(Images::Create(ComputeLocation(coords))) {
}
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_url()) result->_url = qs(r.vurl);
if (r.has_thumb()) {
result->_thumb = ImagePtr(r.vthumb, result->thumbBox());
result->_thumb = Images::Create(r.vthumb, result->thumbBox());
}
if (r.has_content()) {
result->_content_url = GetContentUrl(r.vcontent);
if (result->_type == Type::Photo) {
result->_photo = Auth().data().photoFromWeb(
r.vcontent,
result->_thumb);
result->_thumb,
true);
} else {
result->_document = Auth().data().documentFromWeb(
result->adjustAttributes(r.vcontent),
@ -237,7 +238,7 @@ std::unique_ptr<Result> Result::create(uint64 queryId, const MTPBotInlineResult
location.height = h;
location.zoom = zoom;
location.scale = scale;
result->_locationThumb = ImagePtr(location);
result->_locationThumb = Images::Create(location);
}
return result;

View File

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

View File

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

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "auth_session.h"
namespace Images {
namespace {
QMap<QString, Image*> LocalFileImages;
@ -35,8 +36,6 @@ uint64 SinglePixKey(Images::Options options) {
} // namespace
namespace Images {
void ClearRemote() {
for (auto image : base::take(StorageImages)) {
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;
ImageSource::ImageSource(QImage &&data, const QByteArray &format)
@ -782,7 +1026,7 @@ void Image::replaceSource(std::unique_ptr<Images::Source> &&source) {
_source = std::move(source);
}
Image *Image::Blank() {
ImagePtr Image::Blank() {
static const auto blankImage = [] {
const auto factor = cIntRetinaFactor();
auto data = QImage(
@ -791,7 +1035,7 @@ Image *Image::Blank() {
QImage::Format_ARGB32_Premultiplied);
data.fill(Qt::transparent);
data.setDevicePixelRatio(cRetinaFactor());
return Images::details::Create(
return Images::Create(
std::move(data),
"GIF");
}();
@ -799,7 +1043,7 @@ Image *Image::Blank() {
}
bool Image::isNull() const {
return (this == Blank());
return (this == Blank().get());
}
const QPixmap &Image::pix(
@ -815,14 +1059,14 @@ const QPixmap &Image::pix(
h *= cIntRetinaFactor();
}
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);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
@ -856,14 +1100,14 @@ const QPixmap &Image::pixRounded(
} else if (radius == ImageRoundRadius::Ellipse) {
options |= Images::Option::Circled | cornerOptions(corners);
}
auto k = PixKey(w, h, options);
auto k = Images::PixKey(w, h, options);
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
@ -882,14 +1126,14 @@ const QPixmap &Image::pixCircled(
h *= cIntRetinaFactor();
}
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);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
@ -908,14 +1152,14 @@ const QPixmap &Image::pixBlurredCircled(
h *= cIntRetinaFactor();
}
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);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
@ -934,14 +1178,14 @@ const QPixmap &Image::pixBlurred(
h *= cIntRetinaFactor();
}
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);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
@ -961,14 +1205,14 @@ const QPixmap &Image::pixColored(
h *= cIntRetinaFactor();
}
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);
if (i == _sizesCache.cend()) {
auto p = pixColoredNoCache(origin, add, w, h, true);
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
@ -988,14 +1232,14 @@ const QPixmap &Image::pixBlurredColored(
h *= cIntRetinaFactor();
}
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);
if (i == _sizesCache.cend()) {
auto p = pixBlurredColoredNoCache(origin, add, w, h);
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
@ -1037,17 +1281,17 @@ const QPixmap &Image::pixSingle(
options |= Images::Option::Colored;
}
auto k = SinglePixKey(options);
auto k = Images::SinglePixKey(options);
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) {
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);
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
@ -1085,17 +1329,17 @@ const QPixmap &Image::pixBlurredSingle(
options |= Images::Option::Circled | cornerOptions(corners);
}
auto k = SinglePixKey(options);
auto k = Images::SinglePixKey(options);
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend() || i->width() != (outerw * cIntRetinaFactor()) || i->height() != (outerh * cIntRetinaFactor())) {
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);
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
Images::GlobalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
@ -1228,7 +1472,7 @@ void Image::checkSource() const {
invalidateSizeCache();
_data = std::move(data);
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();
invalidateSizeCache();
if (!_data.isNull()) {
GlobalAcquiredSize -= int64(_data.width()) * _data.height() * 4;
Images::GlobalAcquiredSize -= int64(_data.width()) * _data.height() * 4;
_data = QImage();
}
}
@ -1260,7 +1504,7 @@ void Image::setImageBytes(const QByteArray &bytes) {
void Image::invalidateSizeCache() const {
for (const auto &image : std::as_const(_sizesCache)) {
if (!image.isNull()) {
GlobalAcquiredSize -= int64(image.width()) * image.height() * 4;
Images::GlobalAcquiredSize -= int64(image.width()) * image.height() * 4;
}
}
_sizesCache.clear();
@ -1269,252 +1513,3 @@ void Image::invalidateSizeCache() const {
Image::~Image() {
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 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 {
public:
virtual ~Source();
@ -370,7 +397,7 @@ public:
void replaceSource(std::unique_ptr<Images::Source> &&source);
static Image *Blank();
static ImagePtr Blank();
const QPixmap &pix(
Data::FileOrigin origin,
@ -522,37 +549,3 @@ private:
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
ImagePtr::ImagePtr() : _data(Image::Blank()) {
ImagePtr::ImagePtr() : _data(Image::Blank().get()) {
}
ImagePtr::ImagePtr(const QString &file, QByteArray format)
: _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)) {
ImagePtr::ImagePtr(not_null<Image*> data) : _data(data) {
}
Image *ImagePtr::operator->() const {

View File

@ -283,21 +283,7 @@ class Image;
class ImagePtr {
public:
ImagePtr();
ImagePtr(const QString &file, QByteArray format = QByteArray());
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);
explicit ImagePtr(not_null<Image*> data);
Image *operator->() const;
Image *get() const;