libdonut  2.3.2
Application framework for cross-platform game development in C++20
Image.hpp
Go to the documentation of this file.
1 #ifndef DONUT_GRAPHICS_IMAGE_HPP
2 #define DONUT_GRAPHICS_IMAGE_HPP
3 
4 #include <donut/Filesystem.hpp>
5 #include <donut/UniqueHandle.hpp>
6 
7 #include <cassert> // assert
8 #include <cstddef> // std::size_t
9 #include <cstdint> // std::uint32_t
10 #include <optional> // std::optional
11 #include <utility> // std::move
12 
13 namespace donut::graphics {
14 
19 enum class PixelFormat : std::uint32_t {
20  R = 0x1903,
21  RG = 0x8227,
22  RGB = 0x1907,
23  RGBA = 0x1908,
24 };
25 
29 enum class PixelComponentType : std::uint32_t {
30  U8 = 0x1401,
31  F16 = 0x140B,
32  F32 = 0x1406,
33 };
34 
40 class ImageView {
41 public:
45  constexpr ImageView() noexcept = default;
46 
61  constexpr ImageView(std::size_t width, std::size_t height, PixelFormat pixelFormat, PixelComponentType pixelComponentType, const void* pixels) noexcept
62  : pixels(pixels)
63  , width(width)
64  , height(height)
65  , pixelFormat(pixelFormat)
66  , pixelComponentType(pixelComponentType) {
67  assert(pixels || (width == 0 && height == 0 && pixelFormat == PixelFormat::R && pixelComponentType == PixelComponentType::U8));
68  }
69 
75  explicit operator bool() const noexcept {
76  return static_cast<bool>(pixels);
77  }
78 
88  [[nodiscard]] constexpr std::size_t getWidth() const noexcept {
89  return width;
90  }
91 
101  [[nodiscard]] constexpr std::size_t getHeight() const noexcept {
102  return height;
103  }
104 
113  [[nodiscard]] constexpr PixelFormat getPixelFormat() const noexcept {
114  return pixelFormat;
115  }
116 
125  [[nodiscard]] constexpr PixelComponentType getPixelComponentType() const noexcept {
126  return pixelComponentType;
127  }
128 
157  [[nodiscard]] constexpr const void* getPixels() const noexcept {
158  return pixels;
159  }
160 
171  [[nodiscard]] constexpr std::size_t getChannelCount() const noexcept {
172  if (pixels) {
173  switch (pixelFormat) {
174  case PixelFormat::R: return 1;
175  case PixelFormat::RG: return 2;
176  case PixelFormat::RGB: return 3;
177  case PixelFormat::RGBA: return 4;
178  }
179  }
180  return 0;
181  }
182 
193  [[nodiscard]] constexpr std::size_t getPixelComponentSize() const noexcept {
194  if (pixels) {
195  switch (pixelComponentType) {
196  case PixelComponentType::U8: return 1;
197  case PixelComponentType::F16: return 2;
198  case PixelComponentType::F32: return 4;
199  }
200  }
201  return 0;
202  }
203 
215  [[nodiscard]] constexpr std::size_t getPixelStride() const noexcept {
217  }
218 
229  [[nodiscard]] constexpr std::size_t getSizeInBytes() const noexcept {
230  return getWidth() * getHeight() * getPixelStride();
231  }
232 
233 private:
234  const void* pixels = nullptr;
235  std::size_t width = 0;
236  std::size_t height = 0;
237  PixelFormat pixelFormat = PixelFormat::R;
238  PixelComponentType pixelComponentType = PixelComponentType::U8;
239 };
240 
253 
257  bool flipVertically = false;
258 };
259 
267  bool flipVertically = false;
268 };
269 
280  bool useRleCompression = true;
281 
285  bool flipVertically = false;
286 };
287 
298  int quality = 90;
299 
303  bool flipVertically = false;
304 };
305 
313  bool flipVertically = false;
314 };
315 
323  bool flipVertically = false;
324 };
325 
329 struct ImageOptions {
333  std::optional<PixelFormat> desiredFormat{};
334 
346  bool highDynamicRange = false;
347 
351  bool flipVertically = false;
352 };
353 
359 class Image {
360 public:
376  static void savePNG(const ImageView& image, Filesystem& filesystem, const char* filepath, const ImageSavePNGOptions& options = {});
377 
393  static void saveBMP(const ImageView& image, Filesystem& filesystem, const char* filepath, const ImageSaveBMPOptions& options = {});
394 
410  static void saveTGA(const ImageView& image, Filesystem& filesystem, const char* filepath, const ImageSaveTGAOptions& options = {});
411 
427  static void saveJPG(const ImageView& image, Filesystem& filesystem, const char* filepath, const ImageSaveJPGOptions& options = {});
428 
445  static void saveHDR(const ImageView& image, Filesystem& filesystem, const char* filepath, const ImageSaveHDROptions& options = {});
446 
462  static void save(const ImageView& image, Filesystem& filesystem, const char* filepath, const ImageSaveOptions& options = {});
463 
467  Image() noexcept = default;
468 
489  Image(std::size_t width, std::size_t height, PixelFormat pixelFormat, PixelComponentType pixelComponentType, const void* pixels);
490 
498  explicit Image(const ImageView& image);
499 
539  explicit Image(const Filesystem& filesystem, const char* filepath, const ImageOptions& options = {});
540 
546  explicit operator bool() const noexcept {
547  return static_cast<bool>(pixels);
548  }
549 
557  operator ImageView() const noexcept {
559  }
560 
564  void reset() noexcept {
565  *this = Image{};
566  }
567 
577  [[nodiscard]] std::size_t getWidth() const noexcept {
578  return width;
579  }
580 
590  [[nodiscard]] std::size_t getHeight() const noexcept {
591  return height;
592  }
593 
602  [[nodiscard]] PixelFormat getPixelFormat() const noexcept {
603  return pixelFormat;
604  }
605 
614  [[nodiscard]] PixelComponentType getPixelComponentType() const noexcept {
615  return pixelComponentType;
616  }
617 
633  [[nodiscard]] void* getPixels() noexcept {
634  return pixels.get();
635  }
636 
652  [[nodiscard]] const void* getPixels() const noexcept {
653  return pixels.get();
654  }
655 
664  [[nodiscard]] std::size_t getChannelCount() const noexcept {
665  return ImageView{*this}.getChannelCount();
666  }
667 
677  [[nodiscard]] std::size_t getPixelComponentSize() const noexcept {
678  return ImageView{*this}.getPixelComponentSize();
679  }
680 
691  [[nodiscard]] std::size_t getPixelStride() const noexcept {
692  return ImageView{*this}.getPixelStride();
693  }
694 
705  [[nodiscard]] std::size_t getSizeInBytes() const noexcept {
706  return ImageView{*this}.getSizeInBytes();
707  }
708 
709 private:
710  struct PixelsDeleter {
711  void operator()(void* handle) const noexcept;
712  };
713 
715  std::size_t width = 0;
716  std::size_t height = 0;
717  PixelFormat pixelFormat = PixelFormat::R;
718  PixelComponentType pixelComponentType = PixelComponentType::U8;
719 };
720 
721 } // namespace donut::graphics
722 
723 #endif
Persistent system for managing the virtual filesystem.
Definition: Filesystem.hpp:185
constexpr Handle get() const noexcept
Get the value of the underlying resource handle.
Definition: UniqueHandle.hpp:152
Read-only non-owning view over a 2D image.
Definition: Image.hpp:40
constexpr std::size_t getPixelStride() const noexcept
Get the stride in bytes of the pixels in the image referenced by this view.
Definition: Image.hpp:215
constexpr PixelFormat getPixelFormat() const noexcept
Get the pixel format of the image referenced by this view.
Definition: Image.hpp:113
constexpr std::size_t getPixelComponentSize() const noexcept
Get the size in bytes of a single component of a pixel in the image referenced by this view.
Definition: Image.hpp:193
constexpr std::size_t getHeight() const noexcept
Get the height of the image referenced by this view.
Definition: Image.hpp:101
constexpr const void * getPixels() const noexcept
Get the pixel data referenced by this view.
Definition: Image.hpp:157
constexpr std::size_t getChannelCount() const noexcept
Get the number of component channels in the pixel format of the image referenced by this view.
Definition: Image.hpp:171
constexpr std::size_t getSizeInBytes() const noexcept
Get the size in bytes of the image referenced by this view.
Definition: Image.hpp:229
constexpr ImageView() noexcept=default
Construct a view that does not reference an image.
constexpr std::size_t getWidth() const noexcept
Get the width of the image referenced by this view.
Definition: Image.hpp:88
constexpr PixelComponentType getPixelComponentType() const noexcept
Get the pixel component type of the image referenced by this view.
Definition: Image.hpp:125
Container for a 2D image.
Definition: Image.hpp:359
PixelComponentType getPixelComponentType() const noexcept
Get the pixel component type of the image.
Definition: Image.hpp:614
static void saveHDR(const ImageView &image, Filesystem &filesystem, const char *filepath, const ImageSaveHDROptions &options={})
Save a floating-point 32-bit-per-channel image to a Radiance HDR RGBE file.
std::size_t getWidth() const noexcept
Get the width of the image.
Definition: Image.hpp:577
const void * getPixels() const noexcept
Get the pixel data of this image.
Definition: Image.hpp:652
static void saveTGA(const ImageView &image, Filesystem &filesystem, const char *filepath, const ImageSaveTGAOptions &options={})
Save an 8-bit-per-channel image to a Truevision TARGA file.
PixelFormat getPixelFormat() const noexcept
Get the pixel format of the image.
Definition: Image.hpp:602
std::size_t getSizeInBytes() const noexcept
Get the size in bytes of this image.
Definition: Image.hpp:705
static void savePNG(const ImageView &image, Filesystem &filesystem, const char *filepath, const ImageSavePNGOptions &options={})
Save an 8-bit-per-channel image to a PNG file.
std::size_t getPixelComponentSize() const noexcept
Get the size in bytes of a single component of a pixel in this image.
Definition: Image.hpp:677
static void saveBMP(const ImageView &image, Filesystem &filesystem, const char *filepath, const ImageSaveBMPOptions &options={})
Save an 8-bit-per-channel image to a Windows Bitmap file.
std::size_t getPixelStride() const noexcept
Get the stride in bytes of the pixels in this image.
Definition: Image.hpp:691
static void save(const ImageView &image, Filesystem &filesystem, const char *filepath, const ImageSaveOptions &options={})
Save an image to a file.
Image() noexcept=default
Construct an empty image without a value.
void reset() noexcept
Remove the value from this image and reset it to an empty image.
Definition: Image.hpp:564
std::size_t getHeight() const noexcept
Get the height of the image.
Definition: Image.hpp:590
std::size_t getChannelCount() const noexcept
Get the number of component channels in the pixel format of this image.
Definition: Image.hpp:664
void * getPixels() noexcept
Get the pixel data of this image.
Definition: Image.hpp:633
static void saveJPG(const ImageView &image, Filesystem &filesystem, const char *filepath, const ImageSaveJPGOptions &options={})
Save an 8-bit-per-channel image to a JPEG file.
Definition: Buffer.hpp:7
PixelComponentType
Description of the data type of the pixel components of an image.
Definition: Image.hpp:29
@ F32
Each pixel component is a 32-bit floating-point number.
@ F16
Each pixel component is a 16-bit floating-point number.
@ U8
Each pixel component is an 8-bit unsigned integer.
PixelFormat
Description of the number and meaning of the pixel component channels of an image.
Definition: Image.hpp:19
@ RGB
Each pixel comprises 3 components: red, green, blue.
@ RG
Each pixel comprises 2 components: red, green.
@ R
Each pixel comprises 1 component: red.
@ RGBA
Each pixel comprises 4 components: red, green, blue, alpha.
Options for loading an image.
Definition: Image.hpp:329
bool flipVertically
Flip the loaded image vertically.
Definition: Image.hpp:351
bool highDynamicRange
Load and store the image with high dynamic range.
Definition: Image.hpp:346
std::optional< PixelFormat > desiredFormat
If set, request the loaded image to be converted to this format.
Definition: Image.hpp:333
Options for saving an image in Windows Bitmap format.
Definition: Image.hpp:263
bool flipVertically
Flip the saved image vertically.
Definition: Image.hpp:267
Options for saving an image in Radiance HDR RGBE format.
Definition: Image.hpp:309
bool flipVertically
Flip the saved image vertically.
Definition: Image.hpp:313
Options for saving an image in JPEG format.
Definition: Image.hpp:291
bool flipVertically
Flip the saved image vertically.
Definition: Image.hpp:303
int quality
JPEG quality.
Definition: Image.hpp:298
Options for saving an image in any format.
Definition: Image.hpp:319
bool flipVertically
Flip the saved image vertically.
Definition: Image.hpp:323
Options for saving an image in PNG format.
Definition: Image.hpp:244
bool flipVertically
Flip the saved image vertically.
Definition: Image.hpp:257
int compressionLevel
PNG compression level.
Definition: Image.hpp:252
Options for saving an image in Truevision TARGA format.
Definition: Image.hpp:273
bool useRleCompression
Use run-length encoding to compress the image.
Definition: Image.hpp:280
bool flipVertically
Flip the saved image vertically.
Definition: Image.hpp:285