GraphicsBitmap.h 5.2 KB

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