init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
663
Telegram/SourceFiles/ui/image/image_location.h
Normal file
663
Telegram/SourceFiles/ui/image/image_location.h
Normal file
@@ -0,0 +1,663 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "data/data_peer_id.h"
|
||||
|
||||
class FileLoader;
|
||||
|
||||
namespace Storage {
|
||||
namespace Cache {
|
||||
struct Key;
|
||||
} // namespace Cache
|
||||
} // namespace Storage
|
||||
|
||||
namespace Data {
|
||||
struct UpdatedFileReferences;
|
||||
} // namespace Data
|
||||
|
||||
enum LoadFromCloudSetting {
|
||||
LoadFromCloudOrLocal,
|
||||
LoadFromLocalOnly,
|
||||
};
|
||||
|
||||
enum LoadToCacheSetting {
|
||||
LoadToFileOnly,
|
||||
LoadToCacheAsWell,
|
||||
};
|
||||
|
||||
using InMemoryKey = std::pair<uint64, uint64>;
|
||||
|
||||
namespace std {
|
||||
|
||||
template<>
|
||||
struct hash<InMemoryKey> {
|
||||
size_t operator()(InMemoryKey value) const {
|
||||
auto seed = hash<uint64>()(value.first);
|
||||
seed ^= hash<uint64>()(value.second)
|
||||
+ std::size_t(0x9e3779b9)
|
||||
+ (seed << 6) + (seed >> 2);
|
||||
return seed;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
class StorageFileLocation {
|
||||
public:
|
||||
// Those are used in serialization, don't change.
|
||||
enum class Type : uint8 {
|
||||
Legacy = 0x00,
|
||||
Encrypted = 0x01,
|
||||
Document = 0x02,
|
||||
Secure = 0x03,
|
||||
Takeout = 0x04,
|
||||
Photo = 0x05,
|
||||
PeerPhoto = 0x06,
|
||||
StickerSetThumb = 0x07,
|
||||
GroupCallStream = 0x08,
|
||||
};
|
||||
|
||||
StorageFileLocation() = default;
|
||||
StorageFileLocation(
|
||||
int32 dcId,
|
||||
UserId self,
|
||||
const MTPInputFileLocation &tl);
|
||||
|
||||
[[nodiscard]] StorageFileLocation convertToModernPeerPhoto(
|
||||
uint64 id,
|
||||
uint64 accessHash,
|
||||
uint64 photoId) const;
|
||||
|
||||
[[nodiscard]] int32 dcId() const;
|
||||
[[nodiscard]] uint64 objectId() const;
|
||||
[[nodiscard]] MTPInputFileLocation tl(UserId self) const;
|
||||
|
||||
[[nodiscard]] QByteArray serialize() const;
|
||||
[[nodiscard]] int serializeSize() const;
|
||||
[[nodiscard]] static std::optional<StorageFileLocation> FromSerialized(
|
||||
const QByteArray &serialized);
|
||||
|
||||
[[nodiscard]] Type type() const;
|
||||
[[nodiscard]] bool valid() const;
|
||||
[[nodiscard]] bool isLegacy() const;
|
||||
[[nodiscard]] Storage::Cache::Key cacheKey() const;
|
||||
[[nodiscard]] Storage::Cache::Key bigFileBaseCacheKey() const;
|
||||
|
||||
// We have to allow checking this because of a serialization bug.
|
||||
[[nodiscard]] bool isDocumentThumbnail() const;
|
||||
|
||||
[[nodiscard]] QByteArray fileReference() const;
|
||||
bool refreshFileReference(const Data::UpdatedFileReferences &updates);
|
||||
bool refreshFileReference(const QByteArray &data);
|
||||
|
||||
[[nodiscard]] static const StorageFileLocation &Invalid();
|
||||
|
||||
friend bool operator==(
|
||||
const StorageFileLocation &a,
|
||||
const StorageFileLocation &b);
|
||||
friend bool operator<(
|
||||
const StorageFileLocation &a,
|
||||
const StorageFileLocation &b);
|
||||
|
||||
private:
|
||||
uint16 _dcId = 0;
|
||||
Type _type = Type::Legacy;
|
||||
uint8 _sizeLetter = 0;
|
||||
int32 _localId = 0;
|
||||
uint64 _id = 0;
|
||||
uint64 _accessHash = 0;
|
||||
uint64 _volumeId = 0;
|
||||
PeerId _inMessagePeerId = 0;
|
||||
uint32 _inMessageId = 0;
|
||||
QByteArray _fileReference;
|
||||
|
||||
};
|
||||
|
||||
inline bool operator!=(
|
||||
const StorageFileLocation &a,
|
||||
const StorageFileLocation &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator>(
|
||||
const StorageFileLocation &a,
|
||||
const StorageFileLocation &b) {
|
||||
return (b < a);
|
||||
}
|
||||
|
||||
inline bool operator<=(
|
||||
const StorageFileLocation &a,
|
||||
const StorageFileLocation &b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
inline bool operator>=(
|
||||
const StorageFileLocation &a,
|
||||
const StorageFileLocation &b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
class StorageImageLocation {
|
||||
public:
|
||||
StorageImageLocation() = default;
|
||||
StorageImageLocation(
|
||||
const StorageFileLocation &file,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
[[nodiscard]] QByteArray serialize() const;
|
||||
[[nodiscard]] int serializeSize() const;
|
||||
[[nodiscard]] static std::optional<StorageImageLocation> FromSerialized(
|
||||
const QByteArray &serialized);
|
||||
|
||||
[[nodiscard]] StorageImageLocation convertToModernPeerPhoto(
|
||||
uint64 id,
|
||||
uint64 accessHash,
|
||||
uint64 photoId) const {
|
||||
return StorageImageLocation(
|
||||
_file.convertToModernPeerPhoto(id, accessHash, photoId),
|
||||
_width,
|
||||
_height);
|
||||
}
|
||||
|
||||
[[nodiscard]] const StorageFileLocation &file() const {
|
||||
return _file;
|
||||
}
|
||||
[[nodiscard]] int width() const {
|
||||
return _width;
|
||||
}
|
||||
[[nodiscard]] int height() const {
|
||||
return _height;
|
||||
}
|
||||
|
||||
void setSize(int width, int height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
|
||||
[[nodiscard]] StorageFileLocation::Type type() const {
|
||||
return _file.type();
|
||||
}
|
||||
[[nodiscard]] bool valid() const {
|
||||
return _file.valid();
|
||||
}
|
||||
[[nodiscard]] bool isLegacy() const {
|
||||
return _file.isLegacy();
|
||||
}
|
||||
[[nodiscard]] QByteArray fileReference() const {
|
||||
return _file.fileReference();
|
||||
}
|
||||
bool refreshFileReference(const QByteArray &data) {
|
||||
return _file.refreshFileReference(data);
|
||||
}
|
||||
bool refreshFileReference(const Data::UpdatedFileReferences &updates) {
|
||||
return _file.refreshFileReference(updates);
|
||||
}
|
||||
|
||||
[[nodiscard]] static const StorageImageLocation &Invalid() {
|
||||
static auto result = StorageImageLocation();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend inline bool operator==(
|
||||
const StorageImageLocation &a,
|
||||
const StorageImageLocation &b) {
|
||||
return (a._file == b._file);
|
||||
}
|
||||
friend inline bool operator<(
|
||||
const StorageImageLocation &a,
|
||||
const StorageImageLocation &b) {
|
||||
return (a._file < b._file);
|
||||
}
|
||||
|
||||
private:
|
||||
StorageFileLocation _file;
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
|
||||
};
|
||||
|
||||
inline bool operator!=(
|
||||
const StorageImageLocation &a,
|
||||
const StorageImageLocation &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator>(
|
||||
const StorageImageLocation &a,
|
||||
const StorageImageLocation &b) {
|
||||
return (b < a);
|
||||
}
|
||||
|
||||
inline bool operator<=(
|
||||
const StorageImageLocation &a,
|
||||
const StorageImageLocation &b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
inline bool operator>=(
|
||||
const StorageImageLocation &a,
|
||||
const StorageImageLocation &b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
class WebFileLocation {
|
||||
public:
|
||||
WebFileLocation() = default;
|
||||
WebFileLocation(const QByteArray &url, uint64 accessHash)
|
||||
: _accessHash(accessHash)
|
||||
, _url(url) {
|
||||
}
|
||||
bool isNull() const {
|
||||
return _url.isEmpty();
|
||||
}
|
||||
uint64 accessHash() const {
|
||||
return _accessHash;
|
||||
}
|
||||
const QByteArray &url() const {
|
||||
return _url;
|
||||
}
|
||||
|
||||
static WebFileLocation Null;
|
||||
|
||||
private:
|
||||
uint64 _accessHash = 0;
|
||||
QByteArray _url;
|
||||
|
||||
friend inline bool operator==(
|
||||
const WebFileLocation &a,
|
||||
const WebFileLocation &b) {
|
||||
return (a._accessHash == b._accessHash)
|
||||
&& (a._url == b._url);
|
||||
}
|
||||
friend inline bool operator<(
|
||||
const WebFileLocation &a,
|
||||
const WebFileLocation &b) {
|
||||
return std::tie(a._accessHash, a._url)
|
||||
< std::tie(b._accessHash, b._url);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline bool operator!=(const WebFileLocation &a, const WebFileLocation &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator>(const WebFileLocation &a, const WebFileLocation &b) {
|
||||
return (b < a);
|
||||
}
|
||||
|
||||
inline bool operator<=(const WebFileLocation &a, const WebFileLocation &b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
inline bool operator>=(const WebFileLocation &a, const WebFileLocation &b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
struct GeoPointLocation {
|
||||
float64 lat = 0.;
|
||||
float64 lon = 0.;
|
||||
uint64 access = 0;
|
||||
int32 width = 0;
|
||||
int32 height = 0;
|
||||
int32 zoom = 0;
|
||||
int32 scale = 0;
|
||||
};
|
||||
|
||||
inline bool operator==(
|
||||
const GeoPointLocation &a,
|
||||
const GeoPointLocation &b) {
|
||||
return (a.lat == b.lat)
|
||||
&& (a.lon == b.lon)
|
||||
&& (a.access == b.access)
|
||||
&& (a.width == b.width)
|
||||
&& (a.height == b.height)
|
||||
&& (a.zoom == b.zoom)
|
||||
&& (a.scale == b.scale);
|
||||
}
|
||||
|
||||
inline bool operator<(
|
||||
const GeoPointLocation &a,
|
||||
const GeoPointLocation &b) {
|
||||
return std::tie(
|
||||
a.access,
|
||||
a.lat,
|
||||
a.lon,
|
||||
a.width,
|
||||
a.height,
|
||||
a.zoom,
|
||||
a.scale)
|
||||
< std::tie(
|
||||
b.access,
|
||||
b.lat,
|
||||
b.lon,
|
||||
b.width,
|
||||
b.height,
|
||||
b.zoom,
|
||||
b.scale);
|
||||
}
|
||||
|
||||
inline bool operator!=(
|
||||
const GeoPointLocation &a,
|
||||
const GeoPointLocation &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator>(
|
||||
const GeoPointLocation &a,
|
||||
const GeoPointLocation &b) {
|
||||
return (b < a);
|
||||
}
|
||||
|
||||
inline bool operator<=(
|
||||
const GeoPointLocation &a,
|
||||
const GeoPointLocation &b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
inline bool operator>=(
|
||||
const GeoPointLocation &a,
|
||||
const GeoPointLocation &b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
struct PlainUrlLocation {
|
||||
QString url;
|
||||
|
||||
friend inline bool operator==(
|
||||
const PlainUrlLocation &a,
|
||||
const PlainUrlLocation &b) {
|
||||
return (a.url == b.url);
|
||||
}
|
||||
friend inline bool operator<(
|
||||
const PlainUrlLocation &a,
|
||||
const PlainUrlLocation &b) {
|
||||
return (a.url < b.url);
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator!=(
|
||||
const PlainUrlLocation &a,
|
||||
const PlainUrlLocation &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator>(
|
||||
const PlainUrlLocation &a,
|
||||
const PlainUrlLocation &b) {
|
||||
return (b < a);
|
||||
}
|
||||
|
||||
inline bool operator<=(
|
||||
const PlainUrlLocation &a,
|
||||
const PlainUrlLocation &b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
inline bool operator>=(
|
||||
const PlainUrlLocation &a,
|
||||
const PlainUrlLocation &b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
struct AudioAlbumThumbLocation {
|
||||
uint64 documentId = 0;
|
||||
|
||||
friend inline auto operator<=>(
|
||||
AudioAlbumThumbLocation,
|
||||
AudioAlbumThumbLocation) = default;
|
||||
};
|
||||
|
||||
struct InMemoryLocation {
|
||||
QByteArray bytes;
|
||||
|
||||
friend inline bool operator==(
|
||||
const InMemoryLocation &a,
|
||||
const InMemoryLocation &b) {
|
||||
return (a.bytes == b.bytes);
|
||||
}
|
||||
friend inline bool operator<(
|
||||
const InMemoryLocation &a,
|
||||
const InMemoryLocation &b) {
|
||||
return (a.bytes < b.bytes);
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator!=(
|
||||
const InMemoryLocation &a,
|
||||
const InMemoryLocation &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator>(
|
||||
const InMemoryLocation &a,
|
||||
const InMemoryLocation &b) {
|
||||
return (b < a);
|
||||
}
|
||||
|
||||
inline bool operator<=(
|
||||
const InMemoryLocation &a,
|
||||
const InMemoryLocation &b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
inline bool operator>=(
|
||||
const InMemoryLocation &a,
|
||||
const InMemoryLocation &b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
class DownloadLocation {
|
||||
public:
|
||||
std::variant<
|
||||
StorageFileLocation,
|
||||
WebFileLocation,
|
||||
GeoPointLocation,
|
||||
PlainUrlLocation,
|
||||
AudioAlbumThumbLocation,
|
||||
InMemoryLocation> data;
|
||||
|
||||
[[nodiscard]] QByteArray serialize() const;
|
||||
[[nodiscard]] int serializeSize() const;
|
||||
[[nodiscard]] static std::optional<DownloadLocation> FromSerialized(
|
||||
const QByteArray &serialized);
|
||||
|
||||
[[nodiscard]] DownloadLocation convertToModernPeerPhoto(
|
||||
uint64 id,
|
||||
uint64 accessHash,
|
||||
uint64 photoId) const;
|
||||
|
||||
[[nodiscard]] Storage::Cache::Key cacheKey() const;
|
||||
[[nodiscard]] Storage::Cache::Key bigFileBaseCacheKey() const;
|
||||
[[nodiscard]] bool valid() const;
|
||||
[[nodiscard]] bool isLegacy() const;
|
||||
[[nodiscard]] QByteArray fileReference() const;
|
||||
bool refreshFileReference(const QByteArray &data);
|
||||
bool refreshFileReference(const Data::UpdatedFileReferences &updates);
|
||||
|
||||
friend inline bool operator==(
|
||||
const DownloadLocation &a,
|
||||
const DownloadLocation &b) {
|
||||
return (a.data == b.data);
|
||||
}
|
||||
friend inline bool operator<(
|
||||
const DownloadLocation &a,
|
||||
const DownloadLocation &b) {
|
||||
return (a.data < b.data);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline bool operator!=(
|
||||
const DownloadLocation &a,
|
||||
const DownloadLocation &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator>(
|
||||
const DownloadLocation &a,
|
||||
const DownloadLocation &b) {
|
||||
return (b < a);
|
||||
}
|
||||
|
||||
inline bool operator<=(
|
||||
const DownloadLocation &a,
|
||||
const DownloadLocation &b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
inline bool operator>=(
|
||||
const DownloadLocation &a,
|
||||
const DownloadLocation &b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
class ImageLocation {
|
||||
public:
|
||||
ImageLocation() = default;
|
||||
ImageLocation(
|
||||
const DownloadLocation &file,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
[[nodiscard]] QByteArray serialize() const;
|
||||
[[nodiscard]] int serializeSize() const;
|
||||
[[nodiscard]] static std::optional<ImageLocation> FromSerialized(
|
||||
const QByteArray &serialized);
|
||||
|
||||
[[nodiscard]] ImageLocation convertToModernPeerPhoto(
|
||||
uint64 id,
|
||||
uint64 accessHash,
|
||||
uint64 photoId) const {
|
||||
return ImageLocation(
|
||||
_file.convertToModernPeerPhoto(id, accessHash, photoId),
|
||||
_width,
|
||||
_height);
|
||||
}
|
||||
|
||||
[[nodiscard]] const DownloadLocation &file() const {
|
||||
return _file;
|
||||
}
|
||||
[[nodiscard]] int width() const {
|
||||
return _width;
|
||||
}
|
||||
[[nodiscard]] int height() const {
|
||||
return _height;
|
||||
}
|
||||
|
||||
void setSize(int width, int height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool valid() const {
|
||||
return _file.valid();
|
||||
}
|
||||
[[nodiscard]] bool isLegacy() const {
|
||||
return _file.isLegacy();
|
||||
}
|
||||
[[nodiscard]] QByteArray fileReference() const {
|
||||
return _file.fileReference();
|
||||
}
|
||||
bool refreshFileReference(const QByteArray &data) {
|
||||
return _file.refreshFileReference(data);
|
||||
}
|
||||
bool refreshFileReference(const Data::UpdatedFileReferences &updates) {
|
||||
return _file.refreshFileReference(updates);
|
||||
}
|
||||
|
||||
[[nodiscard]] static const ImageLocation &Invalid() {
|
||||
static auto result = ImageLocation();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend inline bool operator==(
|
||||
const ImageLocation &a,
|
||||
const ImageLocation &b) {
|
||||
return (a._file == b._file);
|
||||
}
|
||||
friend inline bool operator<(
|
||||
const ImageLocation &a,
|
||||
const ImageLocation &b) {
|
||||
return (a._file < b._file);
|
||||
}
|
||||
|
||||
private:
|
||||
DownloadLocation _file;
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
|
||||
};
|
||||
|
||||
inline bool operator!=(
|
||||
const ImageLocation &a,
|
||||
const ImageLocation &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator>(
|
||||
const ImageLocation &a,
|
||||
const ImageLocation &b) {
|
||||
return (b < a);
|
||||
}
|
||||
|
||||
inline bool operator<=(
|
||||
const ImageLocation &a,
|
||||
const ImageLocation &b) {
|
||||
return !(b < a);
|
||||
}
|
||||
|
||||
inline bool operator>=(
|
||||
const ImageLocation &a,
|
||||
const ImageLocation &b) {
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
struct ImageWithLocation {
|
||||
ImageLocation location;
|
||||
QByteArray bytes;
|
||||
QImage preloaded;
|
||||
int bytesCount = 0;
|
||||
int progressivePartSize = 0;
|
||||
};
|
||||
|
||||
struct InlineImageLocation {
|
||||
QByteArray bytes;
|
||||
bool isPath = false;
|
||||
};
|
||||
|
||||
InMemoryKey inMemoryKey(const StorageFileLocation &location);
|
||||
|
||||
inline InMemoryKey inMemoryKey(const StorageImageLocation &location) {
|
||||
return inMemoryKey(location.file());
|
||||
}
|
||||
|
||||
InMemoryKey inMemoryKey(const WebFileLocation &location);
|
||||
InMemoryKey inMemoryKey(const GeoPointLocation &location);
|
||||
InMemoryKey inMemoryKey(const PlainUrlLocation &location);
|
||||
InMemoryKey inMemoryKey(const InMemoryLocation &location);
|
||||
InMemoryKey inMemoryKey(const DownloadLocation &location);
|
||||
|
||||
inline InMemoryKey inMemoryKey(const ImageLocation &location) {
|
||||
return inMemoryKey(location.file());
|
||||
}
|
||||
|
||||
inline QSize shrinkToKeepAspect(int32 width, int32 height, int32 towidth, int32 toheight) {
|
||||
int32 w = qMax(width, 1), h = qMax(height, 1);
|
||||
if (w * toheight > h * towidth) {
|
||||
h = qRound(h * towidth / float64(w));
|
||||
w = towidth;
|
||||
} else {
|
||||
w = qRound(w * toheight / float64(h));
|
||||
h = toheight;
|
||||
}
|
||||
return QSize(qMax(w, 1), qMax(h, 1));
|
||||
}
|
||||
Reference in New Issue
Block a user