Chatterino
Image.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <QPixmap>
4 #include <QString>
5 #include <QThread>
6 #include <QTimer>
7 #include <QVector>
8 #include <atomic>
9 #include <boost/noncopyable.hpp>
10 #include <boost/optional.hpp>
11 #include <boost/variant.hpp>
12 #include <chrono>
13 #include <map>
14 #include <memory>
15 #include <mutex>
16 #include <pajlada/signals/signal.hpp>
17 
18 #include "common/Aliases.hpp"
19 #include "common/Common.hpp"
20 
21 namespace chatterino {
22 namespace detail {
23  template <typename Image>
24  struct Frame {
26  int duration;
27  };
28  class Frames : boost::noncopyable
29  {
30  public:
31  Frames();
32  Frames(QVector<Frame<QPixmap>> &&frames);
33  ~Frames();
34 
35  void clear();
36  bool empty() const;
37  bool animated() const;
38  void advance();
39  boost::optional<QPixmap> current() const;
40  boost::optional<QPixmap> first() const;
41 
42  private:
43  void processOffset();
44  QVector<Frame<QPixmap>> items_;
45  int index_{0};
46  int durationOffset_{0};
47  pajlada::Signals::Connection gifTimerConnection_;
48  };
49 } // namespace detail
50 
51 class Image;
52 using ImagePtr = std::shared_ptr<Image>;
53 
55 class Image : public std::enable_shared_from_this<Image>, boost::noncopyable
56 {
57 public:
58  // Maximum amount of RAM used by the image in bytes.
59  static constexpr int maxBytesRam = 20 * 1024 * 1024;
60 
61  ~Image();
62 
63  static ImagePtr fromUrl(const Url &url, qreal scale = 1);
64  static ImagePtr fromResourcePixmap(const QPixmap &pixmap, qreal scale = 1);
65  static ImagePtr getEmpty();
66 
67  const Url &url() const;
68  bool loaded() const;
69  // either returns the current pixmap, or triggers loading it (lazy loading)
70  boost::optional<QPixmap> pixmapOrLoad() const;
71  void load() const;
72  qreal scale() const;
73  bool isEmpty() const;
74  int width() const;
75  int height() const;
76  bool animated() const;
77 
78  bool operator==(const Image &image) const;
79  bool operator!=(const Image &image) const;
80 
81 private:
82  Image();
83  Image(const Url &url, qreal scale);
84  Image(qreal scale);
85 
86  void setPixmap(const QPixmap &pixmap);
87  void actuallyLoad();
88  void expireFrames();
89 
90  const Url url_{};
91  const qreal scale_{1};
92  std::atomic_bool empty_{false};
93 
94  mutable std::chrono::time_point<std::chrono::steady_clock> lastUsed_;
95 
96  bool shouldLoad_{false};
97 
98  // gui thread only
99  std::unique_ptr<detail::Frames> frames_{};
100 
101  friend class ImageExpirationPool;
102 };
103 
105 {
106 private:
107  friend class Image;
108 
110  static ImageExpirationPool &instance();
111 
112  void addImagePtr(ImagePtr imgPtr);
113  void removeImagePtr(Image *rawPtr);
114 
121  void freeOld();
122 
123 private:
124  // Timer to periodically run freeOld()
125  QTimer freeTimer_;
126  std::map<Image *, std::weak_ptr<Image>> allImages_;
127  std::mutex mutex_;
128 };
129 
130 } // namespace chatterino
Definition: Image.hpp:28
Image image
Definition: Image.hpp:25
Definition: Application.cpp:48
This class is thread safe.
Definition: Image.hpp:55
Definition: Image.hpp:104
std::shared_ptr< Image > ImagePtr
Definition: ModerationAction.hpp:14
bool operator==(const Emote &a, const Emote &b)
Definition: Emote.cpp:7
Definition: Image.hpp:24
void load(const std::shared_ptr< NetworkData > &data)
Definition: NetworkPrivate.cpp:391
int duration
Definition: Image.hpp:26
bool operator!=(const Emote &a, const Emote &b)
Definition: Emote.cpp:13