Bitmap.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #pragma once
  27. #include <AK/Forward.h>
  28. #include <AK/RefCounted.h>
  29. #include <AK/RefPtr.h>
  30. #include <LibGfx/Color.h>
  31. #include <LibGfx/Rect.h>
  32. namespace Gfx {
  33. enum class BitmapFormat {
  34. Invalid,
  35. RGB32,
  36. RGBA32,
  37. Indexed8
  38. };
  39. class Bitmap : public RefCounted<Bitmap> {
  40. public:
  41. static NonnullRefPtr<Bitmap> create(BitmapFormat, const Size&);
  42. static NonnullRefPtr<Bitmap> create_purgeable(BitmapFormat, const Size&);
  43. static NonnullRefPtr<Bitmap> create_wrapper(BitmapFormat, const Size&, size_t pitch, RGBA32*);
  44. static RefPtr<Bitmap> load_from_file(const StringView& path);
  45. static NonnullRefPtr<Bitmap> create_with_shared_buffer(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const Size&);
  46. NonnullRefPtr<Bitmap> to_shareable_bitmap() const;
  47. ~Bitmap();
  48. RGBA32* scanline(int y);
  49. const RGBA32* scanline(int y) const;
  50. u8* bits(int y);
  51. const u8* bits(int y) const;
  52. Rect rect() const { return { {}, m_size }; }
  53. Size size() const { return m_size; }
  54. int width() const { return m_size.width(); }
  55. int height() const { return m_size.height(); }
  56. size_t pitch() const { return m_pitch; }
  57. int shared_buffer_id() const;
  58. SharedBuffer* shared_buffer() { return m_shared_buffer.ptr(); }
  59. const SharedBuffer* shared_buffer() const { return m_shared_buffer.ptr(); }
  60. unsigned bpp() const
  61. {
  62. switch (m_format) {
  63. case BitmapFormat::Indexed8:
  64. return 8;
  65. case BitmapFormat::RGB32:
  66. case BitmapFormat::RGBA32:
  67. return 32;
  68. default:
  69. ASSERT_NOT_REACHED();
  70. case BitmapFormat::Invalid:
  71. return 0;
  72. }
  73. }
  74. void fill(Color);
  75. bool has_alpha_channel() const { return m_format == BitmapFormat::RGBA32; }
  76. BitmapFormat format() const { return m_format; }
  77. void set_mmap_name(const StringView&);
  78. size_t size_in_bytes() const { return m_pitch * m_size.height(); }
  79. Color palette_color(u8 index) const { return Color::from_rgba(m_palette[index]); }
  80. void set_palette_color(u8 index, Color color) { m_palette[index] = color.value(); }
  81. template<BitmapFormat>
  82. Color get_pixel(int x, int y) const
  83. {
  84. (void)x;
  85. (void)y;
  86. ASSERT_NOT_REACHED();
  87. }
  88. Color get_pixel(int x, int y) const;
  89. Color get_pixel(const Point& position) const
  90. {
  91. return get_pixel(position.x(), position.y());
  92. }
  93. template<BitmapFormat>
  94. void set_pixel(int x, int y, Color)
  95. {
  96. (void)x;
  97. (void)y;
  98. ASSERT_NOT_REACHED();
  99. }
  100. void set_pixel(int x, int y, Color);
  101. void set_pixel(const Point& position, Color color)
  102. {
  103. set_pixel(position.x(), position.y(), color);
  104. }
  105. bool is_purgeable() const { return m_purgeable; }
  106. bool is_volatile() const { return m_volatile; }
  107. void set_volatile();
  108. [[nodiscard]] bool set_nonvolatile();
  109. private:
  110. enum class Purgeable { No,
  111. Yes };
  112. Bitmap(BitmapFormat, const Size&, Purgeable);
  113. Bitmap(BitmapFormat, const Size&, size_t pitch, RGBA32*);
  114. Bitmap(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const Size&);
  115. Size m_size;
  116. RGBA32* m_data { nullptr };
  117. RGBA32* m_palette { nullptr };
  118. size_t m_pitch { 0 };
  119. BitmapFormat m_format { BitmapFormat::Invalid };
  120. bool m_needs_munmap { false };
  121. bool m_purgeable { false };
  122. bool m_volatile { false };
  123. RefPtr<SharedBuffer> m_shared_buffer;
  124. };
  125. inline RGBA32* Bitmap::scanline(int y)
  126. {
  127. return reinterpret_cast<RGBA32*>((((u8*)m_data) + (y * m_pitch)));
  128. }
  129. inline const RGBA32* Bitmap::scanline(int y) const
  130. {
  131. return reinterpret_cast<const RGBA32*>((((const u8*)m_data) + (y * m_pitch)));
  132. }
  133. inline const u8* Bitmap::bits(int y) const
  134. {
  135. return reinterpret_cast<const u8*>(scanline(y));
  136. }
  137. inline u8* Bitmap::bits(int y)
  138. {
  139. return reinterpret_cast<u8*>(scanline(y));
  140. }
  141. template<>
  142. inline Color Bitmap::get_pixel<BitmapFormat::RGB32>(int x, int y) const
  143. {
  144. return Color::from_rgb(scanline(y)[x]);
  145. }
  146. template<>
  147. inline Color Bitmap::get_pixel<BitmapFormat::RGBA32>(int x, int y) const
  148. {
  149. return Color::from_rgba(scanline(y)[x]);
  150. }
  151. template<>
  152. inline Color Bitmap::get_pixel<BitmapFormat::Indexed8>(int x, int y) const
  153. {
  154. return Color::from_rgba(m_palette[bits(y)[x]]);
  155. }
  156. inline Color Bitmap::get_pixel(int x, int y) const
  157. {
  158. switch (m_format) {
  159. case BitmapFormat::RGB32:
  160. return get_pixel<BitmapFormat::RGB32>(x, y);
  161. case BitmapFormat::RGBA32:
  162. return get_pixel<BitmapFormat::RGBA32>(x, y);
  163. case BitmapFormat::Indexed8:
  164. return get_pixel<BitmapFormat::Indexed8>(x, y);
  165. default:
  166. ASSERT_NOT_REACHED();
  167. return {};
  168. }
  169. }
  170. template<>
  171. inline void Bitmap::set_pixel<BitmapFormat::RGB32>(int x, int y, Color color)
  172. {
  173. scanline(y)[x] = color.value();
  174. }
  175. template<>
  176. inline void Bitmap::set_pixel<BitmapFormat::RGBA32>(int x, int y, Color color)
  177. {
  178. scanline(y)[x] = color.value();
  179. }
  180. inline void Bitmap::set_pixel(int x, int y, Color color)
  181. {
  182. switch (m_format) {
  183. case BitmapFormat::RGB32:
  184. set_pixel<BitmapFormat::RGB32>(x, y, color);
  185. break;
  186. case BitmapFormat::RGBA32:
  187. set_pixel<BitmapFormat::RGBA32>(x, y, color);
  188. break;
  189. case BitmapFormat::Indexed8:
  190. ASSERT_NOT_REACHED();
  191. default:
  192. ASSERT_NOT_REACHED();
  193. }
  194. }
  195. }