// // This file is part of Kepka, // an unofficial desktop version of Telegram messaging app, // see https://github.com/procxx/kepka // // Kepka 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/procxx/kepka/blob/master/LICENSE // Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org // Copyright (c) 2017- Kepka Contributors, https://github.com/procxx // #pragma once #include "base/flags.h" #include "scheme.h" #include "style/style_core_types.h" #include 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 quint32 packInt(qint32 a) { return (a < 0) ? quint32(qint64(a) + 0x100000000LL) : quint32(a); } inline qint32 unpackInt(quint32 a) { return (a > 0x7FFFFFFFU) ? qint32(qint64(a) - 0x100000000LL) : qint32(a); } inline quint64 packUIntUInt(quint32 a, quint32 b) { return (quint64(a) << 32) | quint64(b); } inline quint64 packUIntInt(quint32 a, qint32 b) { return packUIntUInt(a, packInt(b)); } inline quint64 packIntUInt(qint32 a, quint32 b) { return packUIntUInt(packInt(a), b); } inline quint64 packIntInt(qint32 a, qint32 b) { return packUIntUInt(packInt(a), packInt(b)); } inline quint32 unpackUIntFirst(quint64 v) { return quint32(v >> 32); } inline qint32 unpackIntFirst(quint64 v) { return unpackInt(unpackUIntFirst(v)); } inline quint32 unpackUIntSecond(quint64 v) { return quint32(v & 0xFFFFFFFFULL); } inline qint32 unpackIntSecond(quint64 v) { return unpackInt(unpackUIntSecond(v)); } class StorageImageLocation { public: StorageImageLocation() = default; StorageImageLocation(qint32 width, qint32 height, qint32 dc, const quint64 &volume, qint32 local, const quint64 &secret) : _widthheight(packIntInt(width, height)) , _dclocal(packIntInt(dc, local)) , _volume(volume) , _secret(secret) {} StorageImageLocation(qint32 width, qint32 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; } qint32 width() const { return unpackIntFirst(_widthheight); } qint32 height() const { return unpackIntSecond(_widthheight); } void setSize(qint32 width, qint32 height) { _widthheight = packIntInt(width, height); } qint32 dc() const { return unpackIntFirst(_dclocal); } quint64 volume() const { return _volume; } qint32 local() const { return unpackIntSecond(_dclocal); } quint64 secret() const { return _secret; } static StorageImageLocation Null; private: quint64 _widthheight = 0; quint64 _dclocal = 0; quint64 _volume = 0; quint64 _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(qint32 width, qint32 height, qint32 dc, const QByteArray &url, quint64 accessHash) : _widthheight(packIntInt(width, height)) , _accessHash(accessHash) , _url(url) , _dc(dc) {} bool isNull() const { return !_dc; } qint32 width() const { return unpackIntFirst(_widthheight); } qint32 height() const { return unpackIntSecond(_widthheight); } void setSize(qint32 width, qint32 height) { _widthheight = packIntInt(width, height); } qint32 dc() const { return _dc; } quint64 accessHash() const { return _accessHash; } const QByteArray &url() const { return _url; } static WebFileImageLocation Null; private: quint64 _widthheight = 0; quint64 _accessHash = 0; QByteArray _url; qint32 _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