Store StickerData::image in unique_ptr.

This commit is contained in:
John Preston 2018-11-09 19:16:47 +04:00
parent e5949dbb86
commit f1c06d6743
6 changed files with 79 additions and 61 deletions

View File

@ -41,8 +41,8 @@ Core::MediaActiveCache<DocumentData> &ActiveCache() {
} }
int64 ComputeUsage(StickerData *sticker) { int64 ComputeUsage(StickerData *sticker) {
return (sticker != nullptr && !sticker->img->isNull()) return (sticker != nullptr && sticker->image != nullptr)
? sticker->img->width() * sticker->img->height() * 4 ? sticker->image->width() * sticker->image->height() * 4
: 0; : 0;
} }
@ -585,12 +585,9 @@ void DocumentData::unload() {
// Forget thumb only when image cache limit exceeds. // Forget thumb only when image cache limit exceeds.
//thumb->unload(); //thumb->unload();
if (sticker()) { if (sticker()) {
if (!sticker()->img->isNull()) { if (sticker()->image) {
ActiveCache().decrement(ComputeUsage(sticker())); ActiveCache().decrement(ComputeUsage(sticker()));
sticker()->image = nullptr;
// Should be std::unique_ptr<Image>.
delete sticker()->img.get();
sticker()->img = ImagePtr();
} }
} }
_replyPreview = nullptr; _replyPreview = nullptr;
@ -736,16 +733,17 @@ bool DocumentData::loaded(FilePathResolveType type) const {
that->_data = _loader->bytes(); that->_data = _loader->bytes();
ActiveCache().increment(that->_data.size()); ActiveCache().increment(that->_data.size());
if (that->sticker() if (that->sticker()
&& that->sticker()->img->isNull() && !that->sticker()->image
&& !_loader->imageData().isNull()) { && !_loader->imageData().isNull()) {
that->sticker()->img = Images::Create( that->sticker()->image = std::make_unique<Image>(
_data, std::make_unique<Images::LocalFileSource>(
_loader->imageFormat(), QString(),
_loader->imageData()); _data,
_loader->imageFormat(),
_loader->imageData()));
ActiveCache().increment(ComputeUsage(that->sticker())); ActiveCache().increment(ComputeUsage(that->sticker()));
} }
if (!that->_data.isEmpty() if (!that->_data.isEmpty() || that->getStickerImage()) {
|| (that->sticker() && !that->sticker()->img->isNull())) {
ActiveCache().up(that); ActiveCache().up(that);
} }
@ -1066,15 +1064,26 @@ void DocumentData::checkSticker() {
if (!data) return; if (!data) return;
automaticLoad(stickerSetOrigin(), nullptr); automaticLoad(stickerSetOrigin(), nullptr);
if (data->img->isNull() && loaded()) { if (!data->image && loaded()) {
if (_data.isEmpty()) { if (_data.isEmpty()) {
const auto &loc = location(true); const auto &loc = location(true);
if (loc.accessEnable()) { if (loc.accessEnable()) {
data->img = Images::Create(loc.name(), "WEBP"); data->image = std::make_unique<Image>(
std::make_unique<Images::LocalFileSource>(
loc.name(),
QByteArray(),
"WEBP"));
loc.accessDisable(); loc.accessDisable();
} }
} else { } else {
data->img = Images::Create(_data, "WEBP"); auto format = QByteArray("WEBP");
auto image = App::readImage(_data, &format, false);
data->image = std::make_unique<Image>(
std::make_unique<Images::LocalFileSource>(
QString(),
_data,
format,
std::move(image)));
} }
if (const auto usage = ComputeUsage(data)) { if (const auto usage = ComputeUsage(data)) {
ActiveCache().increment(usage); ActiveCache().increment(usage);
@ -1091,13 +1100,21 @@ void DocumentData::checkStickerThumb() {
} }
} }
ImagePtr DocumentData::getStickerThumb() { Image *DocumentData::getStickerImage() {
if (hasGoodStickerThumb()) { checkSticker();
return thumb; if (const auto data = sticker()) {
} else if (const auto data = sticker()) { return data->image.get();
return data->img;
} }
return ImagePtr(); return nullptr;
}
Image *DocumentData::getStickerThumb() {
if (hasGoodStickerThumb()) {
return thumb->isNull() ? nullptr : thumb.get();
} else if (const auto data = sticker()) {
return data->image.get();
}
return nullptr;
} }
Data::FileOrigin DocumentData::stickerSetOrigin() const { Data::FileOrigin DocumentData::stickerSetOrigin() const {

View File

@ -47,7 +47,7 @@ struct DocumentAdditionalData {
struct StickerData : public DocumentAdditionalData { struct StickerData : public DocumentAdditionalData {
Data::FileOrigin setOrigin() const; Data::FileOrigin setOrigin() const;
ImagePtr img; std::unique_ptr<Image> image;
QString alt; QString alt;
MTPInputStickerSet set = MTP_inputStickerSetEmpty(); MTPInputStickerSet set = MTP_inputStickerSetEmpty();
StorageImageLocation loc; // doc thumb location StorageImageLocation loc; // doc thumb location
@ -131,7 +131,8 @@ public:
StickerData *sticker() const; StickerData *sticker() const;
void checkSticker(); void checkSticker();
void checkStickerThumb(); void checkStickerThumb();
ImagePtr getStickerThumb(); Image *getStickerThumb();
Image *getStickerImage();
Data::FileOrigin stickerSetOrigin() const; Data::FileOrigin stickerSetOrigin() const;
Data::FileOrigin stickerOrGifOrigin() const; Data::FileOrigin stickerOrGifOrigin() const;
bool isStickerSetInstalled() const; bool isStickerSetInstalled() const;

View File

@ -2998,19 +2998,23 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, T
} }
if (rtl()) usex = width() - usex - usew; if (rtl()) usex = width() - usex - usew;
if (selected) { const auto &pixmap = [&]() -> const QPixmap & {
if (sticker->img->isNull()) { const auto o = item->fullId();
p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), _data->thumb->pixBlurredColored(item->fullId(), st::msgStickerOverlay, _pixw, _pixh)); const auto w = _pixw;
} else { const auto h = _pixh;
p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), sticker->img->pixColored(item->fullId(), st::msgStickerOverlay, _pixw, _pixh)); const auto &c = st::msgStickerOverlay;
if (const auto image = _data->getStickerImage()) {
return selected
? image->pixColored(o, c, w, h)
: image->pix(o, w, h);
} }
} else { return selected
if (sticker->img->isNull()) { ? _data->thumb->pixBlurredColored(o, c, w, h)
p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), _data->thumb->pixBlurred(item->fullId(), _pixw, _pixh)); : _data->thumb->pixBlurred(o, w, h);
} else { }();
p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), sticker->img->pix(item->fullId(), _pixw, _pixh)); p.drawPixmap(
} QPoint{ usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2 },
} pixmap);
if (!inWebPage) { if (!inWebPage) {
auto fullRight = usex + usew; auto fullRight = usex + usew;

View File

@ -445,15 +445,15 @@ QSize Sticker::getThumbSize() const {
void Sticker::prepareThumb() const { void Sticker::prepareThumb() const {
if (const auto document = getShownDocument()) { if (const auto document = getShownDocument()) {
document->checkStickerThumb(); document->checkStickerThumb();
if (const auto sticker = document->getStickerThumb()) {
const auto sticker = document->getStickerThumb(); if (!_thumbLoaded && sticker->loaded()) {
if (!_thumbLoaded && !sticker->isNull() && sticker->loaded()) { const auto thumbSize = getThumbSize();
const auto thumbSize = getThumbSize(); _thumb = sticker->pix(
_thumb = sticker->pix( document->stickerSetOrigin(),
document->stickerSetOrigin(), thumbSize.width(),
thumbSize.width(), thumbSize.height());
thumbSize.height()); _thumbLoaded = true;
_thumbLoaded = true; }
} }
} else { } else {
const auto origin = fileOrigin(); const auto origin = fileOrigin();

View File

@ -1617,9 +1617,8 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
} }
if (_doc) { if (_doc) {
if (_doc->sticker()) { if (_doc->sticker()) {
_doc->checkSticker(); if (const auto image = _doc->getStickerImage()) {
if (!_doc->sticker()->img->isNull()) { _current = image->pix(fileOrigin());
_current = _doc->sticker()->img->pix(fileOrigin());
} else { } else {
_current = _doc->thumb->pixBlurred( _current = _doc->thumb->pixBlurred(
fileOrigin(), fileOrigin(),
@ -2107,7 +2106,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
if (imgRect.intersects(r)) { if (imgRect.intersects(r)) {
auto rounding = (_doc && _doc->isVideoMessage()) ? ImageRoundRadius::Ellipse : ImageRoundRadius::None; auto rounding = (_doc && _doc->isVideoMessage()) ? ImageRoundRadius::Ellipse : ImageRoundRadius::None;
auto toDraw = _current.isNull() ? _gif->current(_gif->width() / cIntRetinaFactor(), _gif->height() / cIntRetinaFactor(), _gif->width() / cIntRetinaFactor(), _gif->height() / cIntRetinaFactor(), rounding, RectPart::AllCorners, ms) : _current; auto toDraw = _current.isNull() ? _gif->current(_gif->width() / cIntRetinaFactor(), _gif->height() / cIntRetinaFactor(), _gif->width() / cIntRetinaFactor(), _gif->height() / cIntRetinaFactor(), rounding, RectPart::AllCorners, ms) : _current;
if (!_gif && (!_doc || !_doc->sticker() || _doc->sticker()->img->isNull()) && toDraw.hasAlpha()) { if (!_gif && (!_doc || !_doc->getStickerImage()) && toDraw.hasAlpha()) {
p.fillRect(imgRect, _transparentBrush); p.fillRect(imgRect, _transparentBrush);
} }
if (toDraw.width() != _w * cIntRetinaFactor()) { if (toDraw.width() != _w * cIntRetinaFactor()) {
@ -2719,8 +2718,8 @@ void MediaView::preloadData(int delta) {
if (auto photo = base::get_if<not_null<PhotoData*>>(&entity.data)) { if (auto photo = base::get_if<not_null<PhotoData*>>(&entity.data)) {
(*photo)->download(fileOrigin()); (*photo)->download(fileOrigin());
} else if (auto document = base::get_if<not_null<DocumentData*>>(&entity.data)) { } else if (auto document = base::get_if<not_null<DocumentData*>>(&entity.data)) {
if (auto sticker = (*document)->sticker()) { if (const auto image = (*document)->getStickerImage()) {
sticker->img->load(fileOrigin()); image->load(fileOrigin());
} else { } else {
(*document)->thumb->load(fileOrigin()); (*document)->thumb->load(fileOrigin());
(*document)->automaticLoad(fileOrigin(), entity.item); (*document)->automaticLoad(fileOrigin(), entity.item);

View File

@ -1009,17 +1009,14 @@ QPixmap MediaPreviewWidget::currentImage() const {
if (_document) { if (_document) {
if (_document->sticker()) { if (_document->sticker()) {
if (_cacheStatus != CacheLoaded) { if (_cacheStatus != CacheLoaded) {
_document->checkSticker(); if (const auto image = _document->getStickerImage()) {
if (_document->sticker()->img->isNull()) {
if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) {
QSize s = currentDimensions();
_cache = _document->thumb->pixBlurred(_origin, s.width(), s.height());
_cacheStatus = CacheThumbLoaded;
}
} else {
QSize s = currentDimensions(); QSize s = currentDimensions();
_cache = _document->sticker()->img->pix(_origin, s.width(), s.height()); _cache = image->pix(_origin, s.width(), s.height());
_cacheStatus = CacheLoaded; _cacheStatus = CacheLoaded;
} else if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) {
QSize s = currentDimensions();
_cache = _document->thumb->pixBlurred(_origin, s.width(), s.height());
_cacheStatus = CacheThumbLoaded;
} }
} }
} else { } else {