-
Notifications
You must be signed in to change notification settings - Fork 27
/
image.hpp
executable file
·156 lines (124 loc) · 4.45 KB
/
image.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*=============================================================================
Copyright (c) 2016-2020 Joel de Guzman
Distributed under the MIT License [ https://opensource.org/licenses/MIT ]
=============================================================================*/
#if !defined(ARTIST_IMAGE_SEPTEMBER_5_2016)
#define ARTIST_IMAGE_SEPTEMBER_5_2016
#include <artist/point.hpp>
#include <artist/resources.hpp>
#include <string_view>
#include <cstdint>
#include <memory>
#if defined(ARTIST_SKIA)
class SkCanvas;
using canvas_impl = SkCanvas;
#endif
namespace cycfi::artist
{
#if defined(ARTIST_QUARTZ_2D)
struct canvas_impl;
#endif
class image_impl;
using image_impl_ptr = image_impl*;
enum class pixel_format
{
invalid = -1,
gray8,
rgb16,
rgb32, // First byte is Alpha of 1, or ignored
rgba32,
};
////////////////////////////////////////////////////////////////////////////
// image
////////////////////////////////////////////////////////////////////////////
class image
{
public:
explicit image(float sizex, float sizey);
explicit image(extent size);
explicit image(fs::path const& path_);
image(image const& rhs) = delete;
image(image&& rhs) noexcept;
~image();
image& operator=(image const& rhs) = delete;
image& operator=(image&& rhs) noexcept;
image_impl_ptr impl() const;
extent size() const;
void save_png(std::string_view path) const;
uint32_t* pixels();
uint32_t const* pixels() const;
extent bitmap_size() const;
private:
template <pixel_format fmt>
friend typename std::enable_if<(fmt == pixel_format::gray8), image>::type
make_image(std::uint8_t const* data, extent size);
template <pixel_format fmt>
friend typename std::enable_if<(fmt == pixel_format::rgb16), image>::type
make_image(std::uint16_t const* data, extent size);
template <pixel_format fmt>
friend typename std::enable_if<
(fmt == pixel_format::rgb32 || fmt == pixel_format::rgba32), image>::type
make_image(std::uint32_t const* data, extent size);
explicit image(std::uint8_t const* data, pixel_format fmt, extent size);
size_t _pixmap_size(pixel_format, extent size);
image_impl_ptr _impl;
};
using image_ptr = std::shared_ptr<image>;
////////////////////////////////////////////////////////////////////////////
// offscreen_image allows drawing into a picture
////////////////////////////////////////////////////////////////////////////
class offscreen_image
{
public:
explicit offscreen_image(image& img);
~offscreen_image();
offscreen_image& operator=(offscreen_image const& rhs) = delete;
canvas_impl* context() const;
private:
offscreen_image(offscreen_image const&) = delete;
struct state;
image& _image;
state* _state = nullptr;
};
////////////////////////////////////////////////////////////////////////////
// Inlines
////////////////////////////////////////////////////////////////////////////
template <pixel_format fmt>
inline typename std::enable_if<(fmt == pixel_format::gray8), image>::type
make_image(std::uint8_t const* data, extent size)
{
return image(data, fmt, size);
}
template <pixel_format fmt>
inline typename std::enable_if<(fmt == pixel_format::rgb16), image>::type
make_image(std::uint16_t const* data, extent size)
{
return image(reinterpret_cast<std::uint8_t const*>(data), fmt, size);
}
template <pixel_format fmt>
inline typename std::enable_if<
(fmt == pixel_format::rgb32 || fmt == pixel_format::rgba32), image>::type
make_image(std::uint32_t const* data, extent size)
{
return image(reinterpret_cast<std::uint8_t const*>(data), fmt, size);
}
inline image::image(float sizex, float sizey)
: image(extent{sizex, sizey})
{
}
inline image::image(image&& rhs) noexcept
: _impl(std::move(rhs._impl))
{
rhs._impl = nullptr;
}
inline image& image::operator=(image&& rhs) noexcept
{
if (this != &rhs)
{
_impl = std::move(rhs._impl);
rhs._impl = nullptr;
}
return *this;
}
}
#endif