Ultralight C++ API 1.3.0
Loading...
Searching...
No Matches
Bitmap.h
Go to the documentation of this file.
1/******************************************************************************
2 * This file is a part of Ultralight, an ultra-portable web-browser engine. *
3 * *
4 * See <https://ultralig.ht> for licensing and more. *
5 * *
6 * (C) 2023 Ultralight, Inc. *
7 *****************************************************************************/
8#pragma once
10#include <Ultralight/RefPtr.h>
11#include <Ultralight/Geometry.h>
12
13namespace ultralight {
14
15///
16/// The various Bitmap formats.
17///
18enum class UExport BitmapFormat : uint8_t {
19 ///
20 /// Alpha channel only, 8-bits per pixel.
21 ///
22 /// Encoding: 8-bits per channel, unsigned normalized.
23 ///
24 /// Color-space: Linear (no gamma), alpha-coverage only.
25 ///
27
28 ///
29 /// Blue Green Red Alpha channels, 32-bits per pixel.
30 ///
31 /// Encoding: 8-bits per channel, unsigned normalized.
32 ///
33 /// Color-space: sRGB gamma with premultiplied linear alpha channel.
34 ///
36};
37
38///
39/// Macro to get the bytes per pixel from a BitmapFormat
40///
41#define GetBytesPerPixel(x) (x == BitmapFormat::A8_UNORM ? 1 : 4)
42
43///
44/// Forward declaration for the LockedPixels class.
45///
46template<typename T>
47class LockedPixels;
48
49///
50/// @brief Bitmap container with basic blitting and conversion routines.
51///
52class UExport Bitmap : public RefCounted {
53 public:
54 ///
55 /// Create an empty Bitmap. No pixels will be allocated.
56 ///
58
59 ///
60 /// Create a Bitmap with a certain configuration. Pixels will be allocated but not initialized.
61 ///
62 /// @param width The width in pixels.
63 ///
64 /// @param height The height in pixels.
65 ///
66 /// @param format The pixel format to use.
67 ///
68 /// @return A ref-pointer to a new Bitmap instance.
69 ///
70 static RefPtr<Bitmap> Create(uint32_t width, uint32_t height, BitmapFormat format);
71
72 ///
73 /// Create an aligned Bitmap with a certain configuration. Pixels will be allocated but not
74 /// initialized. Row bytes will be padded to reach the specified alignment.
75 ///
76 /// @param width The width in pixels.
77 ///
78 /// @param height The height in pixels.
79 ///
80 /// @param format The pixel format to use.
81 ///
82 /// @param alignment The alignment (in bytes) to use. Row bytes will be padded to reach a
83 /// multiple of this value and the underlying storage will be allocated with
84 /// this alignment.
85 ///
86 /// @return A ref-pointer to a new Bitmap instance.
87 ///
88 static RefPtr<Bitmap> Create(uint32_t width, uint32_t height, BitmapFormat format,
89 uint32_t alignment);
90
91 ///
92 /// Create a Bitmap with existing pixels and configuration.
93 ///
94 /// @param width The width in pixels.
95 ///
96 /// @param height The height in pixels.
97 ///
98 /// @param format The pixel format to use.
99 ///
100 /// @param row_bytes The number of bytes between each row (note that this value should be >=
101 /// width * bytes_per_pixel).
102 ///
103 /// @param pixels Pointer to raw pixel buffer.
104 ///
105 /// @param size Size of the raw pixel buffer.
106 ///
107 /// @param should_copy Whether or not a copy should be made of the pixels. If this is false
108 /// the returned Bitmap will use the raw pixels passed in as its own, but
109 /// you are still responsible for destroying your buffer afterwards.
110 ///
111 /// @return A ref-pointer to a new Bitmap instance.
112 ///
113 static RefPtr<Bitmap> Create(uint32_t width, uint32_t height, BitmapFormat format,
114 uint32_t row_bytes, const void* pixels, size_t size,
115 bool should_copy = true);
116
117 ///
118 /// Create a bitmap from a deep copy of another Bitmap.
119 ///
120 static RefPtr<Bitmap> Create(const Bitmap& bitmap);
121
122 ///
123 /// Get the width in pixels.
124 ///
125 virtual uint32_t width() const = 0;
126
127 ///
128 /// Get the height in pixels.
129 ///
130 virtual uint32_t height() const = 0;
131
132 ///
133 /// Get the bounds as an IntRect
134 ///
135 virtual IntRect bounds() const = 0;
136
137 ///
138 /// Get the pixel format.
139 ///
140 virtual BitmapFormat format() const = 0;
141
142 ///
143 /// Get the number of bytes per pixel.
144 ///
145 virtual uint32_t bpp() const = 0;
146
147 ///
148 /// Get the number of bytes between each row of pixels.
149 ///
150 /// @note This value is usually calculated as width * bytes_per_pixel (bpp) but it may be larger
151 /// due to alignment rules in the allocator.
152 ///
153 virtual uint32_t row_bytes() const = 0;
154
155 ///
156 /// Get the size in bytes of the pixel buffer.
157 ///
158 /// @note Size is calculated as row_bytes() * height().
159 ///
160 virtual size_t size() const = 0;
161
162 ///
163 /// Whether or not this Bitmap owns the pixel buffer and will destroy it at the end of its
164 /// lifetime.
165 ///
166 virtual bool owns_pixels() const = 0;
167
168 ///
169 /// Lock the pixel buffer for reading/writing (safe version, automatically unlocks).
170 ///
171 /// @return A managed container that can be used to access the pixels (LockedPixels::data()).
172 /// This container will automatically unlock the pixels when it goes out of scope.
173 ///
175
176 ///
177 /// Lock the pixel buffer for reading/writing.
178 ///
179 /// @return A pointer to the pixel buffer.
180 ///
181 virtual void* LockPixels() = 0;
182
183 ///
184 /// Unlock the pixel buffer.
185 ///
186 virtual void UnlockPixels() = 0;
187
188 ///
189 /// Lock the pixel buffer for reading/writing. (const)
190 ///
191 /// @return A const pointer to the pixel buffer.
192 ///
193 virtual const void* LockPixels() const = 0;
194
195 ///
196 /// Unlock the pixel buffer. (const)
197 ///
198 virtual void UnlockPixels() const = 0;
199
200 ///
201 /// Get the raw pixel buffer.
202 ///
203 /// @note You should only call this if pixels are already locked.
204 ///
205 virtual void* raw_pixels() = 0;
206
207 ///
208 /// Whether or not this Bitmap is empty (no pixels allocated).
209 ///
210 virtual bool IsEmpty() const = 0;
211
212 ///
213 /// Erase the Bitmap (set all pixels to 0).
214 ///
215 virtual void Erase() = 0;
216
217 ///
218 /// Assign another bitmap to this one.
219 ///
220 /// @param bitmap The bitmap to copy from.
221 ///
222 virtual void Set(RefPtr<Bitmap> bitmap) = 0;
223
224 ///
225 /// Draw another bitmap to this bitmap.
226 ///
227 /// @note Formats do not need to match. Bitmap formats will be converted to one another
228 /// automatically. Note that when converting from BGRA8 to A8, only the Blue channel will
229 /// be used.
230 ///
231 /// @param src_rect The source rectangle, relative to src bitmap.
232 ///
233 /// @param dest_rect The destination rectangle, relative to this bitmap.
234 ///
235 /// @param src The source bitmap.
236 ///
237 /// @param pad_repeat Whether or not we should pad the drawn bitmap by one pixel of repeated
238 /// edge pixels from the source bitmap.
239 ///
240 /// @return Whether or not the operation succeeded (this can fail if the src_rect and/or
241 /// dest_rect are invalid).
242 ///
243 virtual bool DrawBitmap(IntRect src_rect, IntRect dest_rect, RefPtr<Bitmap> src, bool pad_repeat)
244 = 0;
245
246 ///
247 /// Write this Bitmap out to a PNG image.
248 ///
249 /// @param path The filepath to write to (opened with fopen())
250 ///
251 /// @param convert_to_rgba The PNG format expects RGBA format but our bitmap is stored as BGRA,
252 /// set this to true to perform the conversion automatically.
253 ///
254 /// @param convert_to_straight_alpha The PNG format expects semi-transparent values to be
255 /// stored as straight alpha instead of premultiplied alpha,
256 /// set this to true to perform the conversion automatically.
257 ///
258 /// @return Whether or not the operation succeeded.
259 ///
260 virtual bool WritePNG(const char* path, bool convert_to_rgba = true,
261 bool convert_to_straight_alpha = true) const = 0;
262
263 ///
264 /// Make a resized copy of this bitmap by writing to a pre-allocated destination bitmap.
265 ///
266 /// @param destination The bitmap to store the result in, the width and height of the
267 /// destination will be used.
268 ///
269 /// @param high_quality Whether or not a high quality resampling will be used during the
270 /// resize. (Otherwise, just uses fast nearest-neighbor sampling)
271 ///
272 /// @return Whether or not the operation succeeded. This operation is only valid if both formats
273 /// are BitmapFormat::BGRA8_UNORM_SRGB and the source and destination are non-empty.
274 ///
275 virtual bool Resample(RefPtr<Bitmap> destination, bool high_quality) = 0;
276
277 ///
278 /// Convert a BGRA bitmap to RGBA bitmap and vice-versa by swapping the red and blue channels.
279 ///
280 /// @note Only valid if the format is BitmapFormat::BGRA8_UNORM_SRGB
281 ///
282 virtual void SwapRedBlueChannels() = 0;
283
284 ///
285 /// Convert a BGRA bitmap from premultiplied alpha (the default) to straight alpha.
286 ///
287 /// @note Only valid if the format is BitmapFormat::BGRA8_UNORM_SRGB
288 ///
289 virtual void ConvertToStraightAlpha() = 0;
290
291 ///
292 /// Convert a BGRA bitmap from straight alpha to premultiplied alpha.
293 ///
294 /// @note Only valid if the format is BitmapFormat::BGRA8_UNORM_SRGB
295 ///
296 virtual void ConvertToPremultipliedAlpha() = 0;
297
298 protected:
300 virtual ~Bitmap();
301 Bitmap(const Bitmap&);
302 void operator=(const Bitmap&);
303};
304
305template <typename T>
307 public:
308 LockedPixels(const LockedPixels&) = delete;
310 LockedPixels(int) = delete;
311 explicit LockedPixels(T& lockable) : lockable_(lockable), data_(nullptr), size_(0) { lock(); }
312
314 if (lockable_)
315 lockable_->UnlockPixels();
316 }
317
318 ///
319 /// Access the locked pixel data.
320 ///
321 void* data() { return data_; }
322
323 ///
324 /// Access the size of the locked pixel data.
325 ///
326 size_t size() { return size_; }
327
328 explicit operator bool() const { return !!lockable_; }
329
330 LockedPixels(LockedPixels&& other) : lockable_(other.lockable_), data_(other.data_),
331 size_(other.size_) {
332 other.lockable_ = nullptr;
333 other.data_ = nullptr;
334 other.size_ = 0;
335 }
336
338 if (lockable_)
339 lockable_->UnlockPixels();
340 lockable_ = other.lockable_;
341 data_ = other.data_;
342 size_ = other.size_;
343 other.lockable_ = nullptr;
344 other.data_ = nullptr;
345 other.size_ = 0;
346 return *this;
347 }
348
349 private:
350 void lock() {
351 if (lockable_) {
352 data_ = lockable_->LockPixels();
353 size_ = lockable_->size();
354 }
355 }
356
357 T lockable_;
358 void* data_;
359 size_t size_;
360};
361
362
363} // namespace ultralight
#define UExport
Definition Defines.h:65
Bitmap container with basic blitting and conversion routines.
Definition Bitmap.h:52
virtual void ConvertToPremultipliedAlpha()=0
Convert a BGRA bitmap from straight alpha to premultiplied alpha.
void operator=(const Bitmap &)
virtual void UnlockPixels()=0
Unlock the pixel buffer.
virtual size_t size() const =0
Get the size in bytes of the pixel buffer.
virtual void UnlockPixels() const =0
Unlock the pixel buffer.
virtual void Erase()=0
Erase the Bitmap (set all pixels to 0).
virtual uint32_t bpp() const =0
Get the number of bytes per pixel.
virtual bool DrawBitmap(IntRect src_rect, IntRect dest_rect, RefPtr< Bitmap > src, bool pad_repeat)=0
Draw another bitmap to this bitmap.
virtual void ConvertToStraightAlpha()=0
Convert a BGRA bitmap from premultiplied alpha (the default) to straight alpha.
static RefPtr< Bitmap > Create(uint32_t width, uint32_t height, BitmapFormat format, uint32_t row_bytes, const void *pixels, size_t size, bool should_copy=true)
Create a Bitmap with existing pixels and configuration.
virtual IntRect bounds() const =0
Get the bounds as an IntRect.
virtual bool owns_pixels() const =0
Whether or not this Bitmap owns the pixel buffer and will destroy it at the end of its lifetime.
virtual const void * LockPixels() const =0
Lock the pixel buffer for reading/writing.
virtual bool IsEmpty() const =0
Whether or not this Bitmap is empty (no pixels allocated).
virtual LockedPixels< RefPtr< Bitmap > > LockPixelsSafe() const =0
Lock the pixel buffer for reading/writing (safe version, automatically unlocks).
virtual uint32_t row_bytes() const =0
Get the number of bytes between each row of pixels.
virtual BitmapFormat format() const =0
Get the pixel format.
virtual void * LockPixels()=0
Lock the pixel buffer for reading/writing.
static RefPtr< Bitmap > Create()
Create an empty Bitmap.
virtual uint32_t height() const =0
Get the height in pixels.
virtual void Set(RefPtr< Bitmap > bitmap)=0
Assign another bitmap to this one.
virtual uint32_t width() const =0
Get the width in pixels.
virtual void SwapRedBlueChannels()=0
Convert a BGRA bitmap to RGBA bitmap and vice-versa by swapping the red and blue channels.
virtual bool Resample(RefPtr< Bitmap > destination, bool high_quality)=0
Make a resized copy of this bitmap by writing to a pre-allocated destination bitmap.
virtual void * raw_pixels()=0
Get the raw pixel buffer.
Bitmap(const Bitmap &)
static RefPtr< Bitmap > Create(uint32_t width, uint32_t height, BitmapFormat format)
Create a Bitmap with a certain configuration.
static RefPtr< Bitmap > Create(const Bitmap &bitmap)
Create a bitmap from a deep copy of another Bitmap.
static RefPtr< Bitmap > Create(uint32_t width, uint32_t height, BitmapFormat format, uint32_t alignment)
Create an aligned Bitmap with a certain configuration.
virtual bool WritePNG(const char *path, bool convert_to_rgba=true, bool convert_to_straight_alpha=true) const =0
Write this Bitmap out to a PNG image.
Forward declaration for the LockedPixels class.
Definition Bitmap.h:306
~LockedPixels()
Definition Bitmap.h:313
LockedPixels & operator=(LockedPixels &&other)
Definition Bitmap.h:337
LockedPixels(LockedPixels &&other)
Definition Bitmap.h:330
void * data()
Access the locked pixel data.
Definition Bitmap.h:321
LockedPixels(const LockedPixels &)=delete
LockedPixels(T &lockable)
Definition Bitmap.h:311
LockedPixels & operator=(const LockedPixels &)=delete
size_t size()
Access the size of the locked pixel data.
Definition Bitmap.h:326
Interface for all ref-counted objects that will be managed using the RefPtr<> smart pointer.
Definition RefPtr.h:47
A nullable smart pointer.
Definition RefPtr.h:79
Definition App.h:14
BitmapFormat
The various Bitmap formats.
Definition Bitmap.h:18
@ A8_UNORM
Alpha channel only, 8-bits per pixel.
@ BGRA8_UNORM_SRGB
Blue Green Red Alpha channels, 32-bits per pixel.
Integer Rectangle Helper.
Definition Geometry.h:529