GraphicsBitmap.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #pragma once
  2. #include "Color.h"
  3. #include "Rect.h"
  4. #include "Size.h"
  5. #include <AK/AKString.h>
  6. #include <AK/MappedFile.h>
  7. #include <AK/RefCounted.h>
  8. #include <AK/RefPtr.h>
  9. #include <AK/StringView.h>
  10. #include <SharedBuffer.h>
  11. class GraphicsBitmap : public RefCounted<GraphicsBitmap> {
  12. public:
  13. enum class Format {
  14. Invalid,
  15. RGB32,
  16. RGBA32,
  17. Indexed8
  18. };
  19. static NonnullRefPtr<GraphicsBitmap> create(Format, const Size&);
  20. static NonnullRefPtr<GraphicsBitmap> create_wrapper(Format, const Size&, RGBA32*);
  21. static RefPtr<GraphicsBitmap> load_from_file(const StringView& path);
  22. static RefPtr<GraphicsBitmap> load_from_file(Format, const StringView& path, const Size&);
  23. static NonnullRefPtr<GraphicsBitmap> create_with_shared_buffer(Format, NonnullRefPtr<SharedBuffer>&&, const Size&);
  24. ~GraphicsBitmap();
  25. RGBA32* scanline(int y);
  26. const RGBA32* scanline(int y) const;
  27. u8* bits(int y);
  28. const u8* bits(int y) const;
  29. Rect rect() const { return { {}, m_size }; }
  30. Size size() const { return m_size; }
  31. int width() const { return m_size.width(); }
  32. int height() const { return m_size.height(); }
  33. size_t pitch() const { return m_pitch; }
  34. int shared_buffer_id() const { return m_shared_buffer ? m_shared_buffer->shared_buffer_id() : -1; }
  35. unsigned bpp() const
  36. {
  37. switch (m_format) {
  38. case Format::Indexed8:
  39. return 8;
  40. case Format::RGB32:
  41. case Format::RGBA32:
  42. return 32;
  43. case Format::Invalid:
  44. return 0;
  45. default:
  46. ASSERT_NOT_REACHED();
  47. }
  48. }
  49. void fill(Color);
  50. bool has_alpha_channel() const { return m_format == Format::RGBA32; }
  51. Format format() const { return m_format; }
  52. void set_mmap_name(const StringView&);
  53. size_t size_in_bytes() const { return m_pitch * m_size.height(); }
  54. Color palette_color(u8 index) const { return Color::from_rgba(m_palette[index]); }
  55. void set_palette_color(u8 index, Color color) { m_palette[index] = color.value(); }
  56. template<Format>
  57. Color get_pixel(int x, int y) const
  58. {
  59. ASSERT_NOT_REACHED();
  60. }
  61. Color get_pixel(int x, int y) const;
  62. Color get_pixel(const Point& position) const
  63. {
  64. return get_pixel(position.x(), position.y());
  65. }
  66. template<Format>
  67. void set_pixel(int x, int y, Color)
  68. {
  69. ASSERT_NOT_REACHED();
  70. }
  71. void set_pixel(int x, int y, Color);
  72. void set_pixel(const Point& position, Color color)
  73. {
  74. set_pixel(position.x(), position.y(), color);
  75. }
  76. private:
  77. GraphicsBitmap(Format, const Size&);
  78. GraphicsBitmap(Format, const Size&, RGBA32*);
  79. GraphicsBitmap(Format, const Size&, MappedFile&&);
  80. GraphicsBitmap(Format, NonnullRefPtr<SharedBuffer>&&, const Size&);
  81. Size m_size;
  82. RGBA32* m_data { nullptr };
  83. RGBA32* m_palette { nullptr };
  84. size_t m_pitch { 0 };
  85. Format m_format { Format::Invalid };
  86. bool m_needs_munmap { false };
  87. MappedFile m_mapped_file;
  88. RefPtr<SharedBuffer> m_shared_buffer;
  89. };
  90. inline RGBA32* GraphicsBitmap::scanline(int y)
  91. {
  92. return reinterpret_cast<RGBA32*>((((u8*)m_data) + (y * m_pitch)));
  93. }
  94. inline const RGBA32* GraphicsBitmap::scanline(int y) const
  95. {
  96. return reinterpret_cast<const RGBA32*>((((const u8*)m_data) + (y * m_pitch)));
  97. }
  98. inline const u8* GraphicsBitmap::bits(int y) const
  99. {
  100. return reinterpret_cast<const u8*>(scanline(y));
  101. }
  102. inline u8* GraphicsBitmap::bits(int y)
  103. {
  104. return reinterpret_cast<u8*>(scanline(y));
  105. }
  106. template<>
  107. inline Color GraphicsBitmap::get_pixel<GraphicsBitmap::Format::RGB32>(int x, int y) const
  108. {
  109. return Color::from_rgb(scanline(y)[x]);
  110. }
  111. template<>
  112. inline Color GraphicsBitmap::get_pixel<GraphicsBitmap::Format::RGBA32>(int x, int y) const
  113. {
  114. return Color::from_rgba(scanline(y)[x]);
  115. }
  116. template<>
  117. inline Color GraphicsBitmap::get_pixel<GraphicsBitmap::Format::Indexed8>(int x, int y) const
  118. {
  119. return Color::from_rgba(m_palette[bits(y)[x]]);
  120. }
  121. inline Color GraphicsBitmap::get_pixel(int x, int y) const
  122. {
  123. switch (m_format) {
  124. case Format::RGB32:
  125. return get_pixel<Format::RGB32>(x, y);
  126. case Format::RGBA32:
  127. return get_pixel<Format::RGBA32>(x, y);
  128. case Format::Indexed8:
  129. return get_pixel<Format::Indexed8>(x, y);
  130. default:
  131. ASSERT_NOT_REACHED();
  132. }
  133. }
  134. template<>
  135. inline void GraphicsBitmap::set_pixel<GraphicsBitmap::Format::RGB32>(int x, int y, Color color)
  136. {
  137. scanline(y)[x] = color.value();
  138. }
  139. template<>
  140. inline void GraphicsBitmap::set_pixel<GraphicsBitmap::Format::RGBA32>(int x, int y, Color color)
  141. {
  142. scanline(y)[x] = color.value();
  143. }
  144. inline void GraphicsBitmap::set_pixel(int x, int y, Color color)
  145. {
  146. switch (m_format) {
  147. case Format::RGB32:
  148. set_pixel<Format::RGB32>(x, y, color);
  149. break;
  150. case Format::RGBA32:
  151. set_pixel<Format::RGBA32>(x, y, color);
  152. break;
  153. case Format::Indexed8:
  154. ASSERT_NOT_REACHED();
  155. default:
  156. ASSERT_NOT_REACHED();
  157. }
  158. }