GraphicsBitmap.h 4.6 KB

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