/* This file is part of Telegram Desktop, the official desktop version of Telegram messaging app, see https://telegram.org Telegram Desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once #include "base/flags.h" class FileLoader; class mtpFileLoader; enum LoadFromCloudSetting { LoadFromCloudOrLocal, LoadFromLocalOnly, }; enum LoadToCacheSetting { LoadToFileOnly, LoadToCacheAsWell, }; enum class ImageRoundRadius { None, Large, Small, Ellipse, }; enum class ImageRoundCorner { None = 0x00, TopLeft = 0x01, TopRight = 0x02, BottomLeft = 0x04, BottomRight = 0x08, All = 0x0f, }; using ImageRoundCorners = base::flags; inline constexpr auto is_flag_type(ImageRoundCorner) { return true; }; inline uint32_t packInt(int32_t a) { return (a < 0) ? uint32_t(int64_t(a) + 0x100000000LL) : uint32_t(a); } inline int32_t unpackInt(uint32_t a) { return (a > 0x7FFFFFFFU) ? int32_t(int64_t(a) - 0x100000000LL) : int32_t(a); } inline uint64_t packUIntUInt(uint32_t a, uint32_t b) { return (uint64_t(a) << 32) | uint64_t(b); } inline uint64_t packUIntInt(uint32_t a, int32_t b) { return packUIntUInt(a, packInt(b)); } inline uint64_t packIntUInt(int32_t a, uint32_t b) { return packUIntUInt(packInt(a), b); } inline uint64_t packIntInt(int32_t a, int32_t b) { return packUIntUInt(packInt(a), packInt(b)); } inline uint32_t unpackUIntFirst(uint64_t v) { return uint32_t(v >> 32); } inline int32_t unpackIntFirst(uint64_t v) { return unpackInt(unpackUIntFirst(v)); } inline uint32_t unpackUIntSecond(uint64_t v) { return uint32_t(v & 0xFFFFFFFFULL); } inline int32_t unpackIntSecond(uint64_t v) { return unpackInt(unpackUIntSecond(v)); } class StorageImageLocation { public: StorageImageLocation() = default; StorageImageLocation(int32_t width, int32_t height, int32_t dc, const uint64_t &volume, int32_t local, const uint64_t &secret) : _widthheight(packIntInt(width, height)), _dclocal(packIntInt(dc, local)), _volume(volume), _secret(secret) { } StorageImageLocation(int32_t width, int32_t height, const MTPDfileLocation &location) : _widthheight(packIntInt(width, height)), _dclocal(packIntInt(location.vdc_id.v, location.vlocal_id.v)), _volume(location.vvolume_id.v), _secret(location.vsecret.v) { } bool isNull() const { return !_dclocal; } int32_t width() const { return unpackIntFirst(_widthheight); } int32_t height() const { return unpackIntSecond(_widthheight); } void setSize(int32_t width, int32_t height) { _widthheight = packIntInt(width, height); } int32_t dc() const { return unpackIntFirst(_dclocal); } uint64_t volume() const { return _volume; } int32_t local() const { return unpackIntSecond(_dclocal); } uint64_t secret() const { return _secret; } static StorageImageLocation Null; private: uint64_t _widthheight = 0; uint64_t _dclocal = 0; uint64_t _volume = 0; uint64_t _secret = 0; friend inline bool operator==(const StorageImageLocation &a, const StorageImageLocation &b) { return (a._dclocal == b._dclocal) && (a._volume == b._volume) && (a._secret == b._secret); } }; inline bool operator!=(const StorageImageLocation &a, const StorageImageLocation &b) { return !(a == b); } class WebFileImageLocation { public: WebFileImageLocation() = default; WebFileImageLocation(int32_t width, int32_t height, int32_t dc, const QByteArray &url, uint64_t accessHash) : _widthheight(packIntInt(width, height)), _accessHash(accessHash), _url(url), _dc(dc) { } bool isNull() const { return !_dc; } int32_t width() const { return unpackIntFirst(_widthheight); } int32_t height() const { return unpackIntSecond(_widthheight); } void setSize(int32_t width, int32_t height) { _widthheight = packIntInt(width, height); } int32_t dc() const { return _dc; } uint64_t accessHash() const { return _accessHash; } const QByteArray &url() const { return _url; } static WebFileImageLocation Null; private: uint64_t _widthheight = 0; uint64_t _accessHash = 0; QByteArray _url; int32_t _dc = 0; friend inline bool operator==(const WebFileImageLocation &a, const WebFileImageLocation &b) { return (a._dc == b._dc) && (a._accessHash == b._accessHash) && (a._url == b._url); } }; inline bool operator!=(const WebFileImageLocation &a, const WebFileImageLocation &b) { return !(a == b); } namespace Images { QImage prepareBlur(QImage image); void prepareRound(QImage &image, ImageRoundRadius radius, ImageRoundCorners corners = ImageRoundCorner::All); void prepareRound(QImage &image, QImage *cornerMasks, ImageRoundCorners corners = ImageRoundCorner::All); void prepareCircle(QImage &image); QImage prepareColored(style::color add, QImage image); QImage prepareOpaque(QImage image); enum class Option { None = 0, Smooth = (1 << 0), Blurred = (1 << 1), Circled = (1 << 2), RoundedLarge = (1 << 3), RoundedSmall = (1 << 4), RoundedTopLeft = (1 << 5), RoundedTopRight = (1 << 6), RoundedBottomLeft = (1 << 7), RoundedBottomRight = (1 << 8), Colored = (1 << 9), TransparentBackground = (1 << 10), }; using Options = base::flags