| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright notice, this | 
					
						
							|  |  |  |  *    list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright notice, | 
					
						
							|  |  |  |  *    this list of conditions and the following disclaimer in the documentation | 
					
						
							|  |  |  |  *    and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
					
						
							|  |  |  |  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  |  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | 
					
						
							|  |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
					
						
							|  |  |  |  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
					
						
							|  |  |  |  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
					
						
							|  |  |  |  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
					
						
							|  |  |  |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-09 02:06:04 +01:00
										 |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  | #include <AK/Forward.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-21 18:58:45 +02:00
										 |  |  | #include <AK/RefCounted.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-25 20:33:24 +02:00
										 |  |  | #include <AK/RefPtr.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  | #include <LibGfx/Color.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-29 19:04:05 +02:00
										 |  |  | #include <LibGfx/Forward.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  | #include <LibGfx/Rect.h>
 | 
					
						
							| 
									
										
										
										
											2019-01-14 20:00:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-15 15:13:12 +03:00
										 |  |  | #define ENUMERATE_IMAGE_FORMATS           \
 | 
					
						
							| 
									
										
										
										
											2020-06-21 12:00:22 +03:00
										 |  |  |     __ENUMERATE_IMAGE_FORMAT(pbm, ".pbm") \ | 
					
						
							| 
									
										
										
										
											2020-06-22 15:19:57 +03:00
										 |  |  |     __ENUMERATE_IMAGE_FORMAT(pgm, ".pgm") \ | 
					
						
							| 
									
										
										
										
											2020-06-15 15:13:12 +03:00
										 |  |  |     __ENUMERATE_IMAGE_FORMAT(png, ".png") \ | 
					
						
							| 
									
										
										
										
											2020-06-22 11:58:04 +03:00
										 |  |  |     __ENUMERATE_IMAGE_FORMAT(ppm, ".ppm") \ | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |     __ENUMERATE_IMAGE_FORMAT(gif, ".gif") \ | 
					
						
							| 
									
										
										
										
											2020-06-15 21:36:05 -04:00
										 |  |  |     __ENUMERATE_IMAGE_FORMAT(bmp, ".bmp") \ | 
					
						
							| 
									
										
										
										
											2020-06-22 12:33:56 +05:30
										 |  |  |     __ENUMERATE_IMAGE_FORMAT(ico, ".ico") \ | 
					
						
							|  |  |  |     __ENUMERATE_IMAGE_FORMAT(jpg, ".jpg") \ | 
					
						
							|  |  |  |     __ENUMERATE_IMAGE_FORMAT(jpg, ".jpeg") | 
					
						
							| 
									
										
										
										
											2020-06-15 15:13:12 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | namespace Gfx { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  | enum class BitmapFormat { | 
					
						
							|  |  |  |     Invalid, | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |     Indexed1, | 
					
						
							|  |  |  |     Indexed2, | 
					
						
							|  |  |  |     Indexed4, | 
					
						
							|  |  |  |     Indexed8, | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     RGB32, | 
					
						
							|  |  |  |     RGBA32, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-12 13:19:18 +03:00
										 |  |  | enum RotationDirection { | 
					
						
							|  |  |  |     Left, | 
					
						
							|  |  |  |     Right | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | class Bitmap : public RefCounted<Bitmap> { | 
					
						
							| 
									
										
										
										
											2019-01-09 02:06:04 +01:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     static RefPtr<Bitmap> create(BitmapFormat, const IntSize&); | 
					
						
							|  |  |  |     static RefPtr<Bitmap> create_purgeable(BitmapFormat, const IntSize&); | 
					
						
							|  |  |  |     static RefPtr<Bitmap> create_wrapper(BitmapFormat, const IntSize&, size_t pitch, RGBA32*); | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  |     static RefPtr<Bitmap> load_from_file(const StringView& path); | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     static RefPtr<Bitmap> create_with_shared_buffer(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const IntSize&); | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  |     static RefPtr<Bitmap> create_with_shared_buffer(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const IntSize&, const Vector<RGBA32>& palette); | 
					
						
							| 
									
										
										
										
											2020-06-15 15:13:12 +03:00
										 |  |  |     static bool is_path_a_supported_image_format(const StringView& path) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | #define __ENUMERATE_IMAGE_FORMAT(Name, Ext) \
 | 
					
						
							|  |  |  |     if (path.ends_with(Ext))                \ | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |         ENUMERATE_IMAGE_FORMATS | 
					
						
							|  |  |  | #undef __ENUMERATE_IMAGE_FORMAT
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-08 17:07:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-15 11:57:24 +02:00
										 |  |  |     RefPtr<Gfx::Bitmap> rotated(Gfx::RotationDirection) const; | 
					
						
							|  |  |  |     RefPtr<Gfx::Bitmap> flipped(Gfx::Orientation) const; | 
					
						
							|  |  |  |     RefPtr<Bitmap> to_bitmap_backed_by_shared_buffer() const; | 
					
						
							| 
									
										
										
										
											2020-03-29 19:04:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ShareableBitmap to_shareable_bitmap(pid_t peer_pid = -1) const; | 
					
						
							| 
									
										
										
										
											2019-12-08 17:07:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  |     ~Bitmap(); | 
					
						
							| 
									
										
										
										
											2019-01-09 02:06:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |     u8* scanline_u8(int y); | 
					
						
							|  |  |  |     const u8* scanline_u8(int y) const; | 
					
						
							| 
									
										
										
										
											2019-01-10 05:36:32 +01:00
										 |  |  |     RGBA32* scanline(int y); | 
					
						
							| 
									
										
										
										
											2019-01-12 06:39:34 +01:00
										 |  |  |     const RGBA32* scanline(int y) const; | 
					
						
							| 
									
										
										
										
											2019-01-09 02:06:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 21:17:35 +02:00
										 |  |  |     u8* bits(int y); | 
					
						
							|  |  |  |     const u8* bits(int y) const; | 
					
						
							| 
									
										
										
										
											2019-05-06 19:32:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     IntRect rect() const { return { {}, m_size }; } | 
					
						
							|  |  |  |     IntSize size() const { return m_size; } | 
					
						
							| 
									
										
										
										
											2019-01-09 02:06:04 +01:00
										 |  |  |     int width() const { return m_size.width(); } | 
					
						
							|  |  |  |     int height() const { return m_size.height(); } | 
					
						
							| 
									
										
										
										
											2019-01-12 21:45:45 +01:00
										 |  |  |     size_t pitch() const { return m_pitch; } | 
					
						
							| 
									
										
										
										
											2020-02-28 11:45:19 +01:00
										 |  |  |     int shbuf_id() const; | 
					
						
							| 
									
										
										
										
											2019-02-16 12:13:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-08 17:07:44 +01:00
										 |  |  |     SharedBuffer* shared_buffer() { return m_shared_buffer.ptr(); } | 
					
						
							|  |  |  |     const SharedBuffer* shared_buffer() const { return m_shared_buffer.ptr(); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  |     ALWAYS_INLINE bool is_indexed() const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return is_indexed(m_format); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |     ALWAYS_INLINE static bool is_indexed(BitmapFormat format) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return format == BitmapFormat::Indexed8 || format == BitmapFormat::Indexed4 | 
					
						
							|  |  |  |             || format == BitmapFormat::Indexed2 || format == BitmapFormat::Indexed1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  |     size_t palette_size(BitmapFormat format) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         switch (format) { | 
					
						
							|  |  |  |         case BitmapFormat::Indexed1: | 
					
						
							|  |  |  |             return 2; | 
					
						
							|  |  |  |         case BitmapFormat::Indexed2: | 
					
						
							|  |  |  |             return 4; | 
					
						
							|  |  |  |         case BitmapFormat::Indexed4: | 
					
						
							|  |  |  |             return 16; | 
					
						
							|  |  |  |         case BitmapFormat::Indexed8: | 
					
						
							|  |  |  |             return 256; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Vector<RGBA32> palette_to_vector() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-15 11:57:24 +02:00
										 |  |  |     static unsigned bpp_for_format(BitmapFormat format) | 
					
						
							| 
									
										
										
										
											2019-06-25 20:33:24 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-04-15 11:57:24 +02:00
										 |  |  |         switch (format) { | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |         case BitmapFormat::Indexed1: | 
					
						
							|  |  |  |             return 1; | 
					
						
							|  |  |  |         case BitmapFormat::Indexed2: | 
					
						
							|  |  |  |             return 2; | 
					
						
							|  |  |  |         case BitmapFormat::Indexed4: | 
					
						
							|  |  |  |             return 4; | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |         case BitmapFormat::Indexed8: | 
					
						
							| 
									
										
										
										
											2019-06-25 20:33:24 +02:00
										 |  |  |             return 8; | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |         case BitmapFormat::RGB32: | 
					
						
							|  |  |  |         case BitmapFormat::RGBA32: | 
					
						
							| 
									
										
										
										
											2019-06-25 20:33:24 +02:00
										 |  |  |             return 32; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             ASSERT_NOT_REACHED(); | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |         case BitmapFormat::Invalid: | 
					
						
							| 
									
										
										
										
											2019-09-29 21:02:49 +02:00
										 |  |  |             return 0; | 
					
						
							| 
									
										
										
										
											2019-06-25 20:33:24 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-15 11:57:24 +02:00
										 |  |  |     unsigned bpp() const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return bpp_for_format(m_format); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-10 19:29:50 +02:00
										 |  |  |     void fill(Color); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     bool has_alpha_channel() const { return m_format == BitmapFormat::RGBA32; } | 
					
						
							|  |  |  |     BitmapFormat format() const { return m_format; } | 
					
						
							| 
									
										
										
										
											2019-02-19 01:42:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 14:58:02 +02:00
										 |  |  |     void set_mmap_name(const StringView&); | 
					
						
							| 
									
										
										
										
											2019-04-30 13:46:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-08 03:28:13 +02:00
										 |  |  |     size_t size_in_bytes() const { return m_pitch * m_size.height(); } | 
					
						
							| 
									
										
										
										
											2019-05-06 14:04:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 21:17:35 +02:00
										 |  |  |     Color palette_color(u8 index) const { return Color::from_rgba(m_palette[index]); } | 
					
						
							|  |  |  |     void set_palette_color(u8 index, Color color) { m_palette[index] = color.value(); } | 
					
						
							| 
									
										
										
										
											2019-05-06 19:32:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     template<BitmapFormat> | 
					
						
							| 
									
										
										
										
											2019-05-06 19:32:56 +02:00
										 |  |  |     Color get_pixel(int x, int y) const | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-01-30 17:58:23 -06:00
										 |  |  |         (void)x; | 
					
						
							|  |  |  |         (void)y; | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  |         ASSERT_NOT_REACHED(); | 
					
						
							| 
									
										
										
										
											2019-05-06 19:32:56 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  |     Color get_pixel(int x, int y) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     Color get_pixel(const IntPoint& position) const | 
					
						
							| 
									
										
										
										
											2019-06-14 19:10:59 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         return get_pixel(position.x(), position.y()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     template<BitmapFormat> | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  |     void set_pixel(int x, int y, Color) | 
					
						
							| 
									
										
										
										
											2019-06-14 19:10:59 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-01-30 17:58:23 -06:00
										 |  |  |         (void)x; | 
					
						
							|  |  |  |         (void)y; | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  |         ASSERT_NOT_REACHED(); | 
					
						
							| 
									
										
										
										
											2019-06-14 19:10:59 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  |     void set_pixel(int x, int y, Color); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     void set_pixel(const IntPoint& position, Color color) | 
					
						
							| 
									
										
										
										
											2019-06-14 19:10:59 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         set_pixel(position.x(), position.y(), color); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 20:50:05 +01:00
										 |  |  |     bool is_purgeable() const { return m_purgeable; } | 
					
						
							|  |  |  |     bool is_volatile() const { return m_volatile; } | 
					
						
							|  |  |  |     void set_volatile(); | 
					
						
							|  |  |  |     [[nodiscard]] bool set_nonvolatile(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-09 02:06:04 +01:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2020-08-26 21:52:24 +02:00
										 |  |  |     enum class Purgeable { | 
					
						
							|  |  |  |         No, | 
					
						
							|  |  |  |         Yes | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     Bitmap(BitmapFormat, const IntSize&, Purgeable); | 
					
						
							|  |  |  |     Bitmap(BitmapFormat, const IntSize&, size_t pitch, RGBA32*); | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  |     Bitmap(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const IntSize&, const Vector<RGBA32>& palette); | 
					
						
							| 
									
										
										
										
											2019-01-09 02:06:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 21:52:24 +02:00
										 |  |  |     void allocate_palette_from_format(BitmapFormat, const Vector<RGBA32>& source_palette); | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 10:57:59 +02:00
										 |  |  |     IntSize m_size; | 
					
						
							| 
									
										
										
										
											2019-01-10 05:36:32 +01:00
										 |  |  |     RGBA32* m_data { nullptr }; | 
					
						
							| 
									
										
										
										
											2019-05-06 19:32:56 +02:00
										 |  |  |     RGBA32* m_palette { nullptr }; | 
					
						
							| 
									
										
										
										
											2019-01-12 21:29:05 +01:00
										 |  |  |     size_t m_pitch { 0 }; | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     BitmapFormat m_format { BitmapFormat::Invalid }; | 
					
						
							| 
									
										
										
										
											2019-04-26 18:25:05 +02:00
										 |  |  |     bool m_needs_munmap { false }; | 
					
						
							| 
									
										
										
										
											2019-12-18 20:50:05 +01:00
										 |  |  |     bool m_purgeable { false }; | 
					
						
							|  |  |  |     bool m_volatile { false }; | 
					
						
							| 
									
										
										
										
											2019-06-21 18:37:47 +02:00
										 |  |  |     RefPtr<SharedBuffer> m_shared_buffer; | 
					
						
							| 
									
										
										
										
											2019-01-09 02:06:04 +01:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2019-01-16 19:43:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  | inline u8* Bitmap::scanline_u8(int y) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return (u8*)m_data + (y * m_pitch); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const u8* Bitmap::scanline_u8(int y) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return (const u8*)m_data + (y * m_pitch); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | inline RGBA32* Bitmap::scanline(int y) | 
					
						
							| 
									
										
										
										
											2019-01-16 19:43:01 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |     return reinterpret_cast<RGBA32*>(scanline_u8(y)); | 
					
						
							| 
									
										
										
										
											2019-01-16 19:43:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | inline const RGBA32* Bitmap::scanline(int y) const | 
					
						
							| 
									
										
										
										
											2019-01-16 19:43:01 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |     return reinterpret_cast<const RGBA32*>(scanline_u8(y)); | 
					
						
							| 
									
										
										
										
											2019-01-16 19:43:01 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-05-06 19:32:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | inline const u8* Bitmap::bits(int y) const | 
					
						
							| 
									
										
										
										
											2019-05-06 19:32:56 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-07-03 21:17:35 +02:00
										 |  |  |     return reinterpret_cast<const u8*>(scanline(y)); | 
					
						
							| 
									
										
										
										
											2019-05-06 19:32:56 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-05-06 20:29:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | inline u8* Bitmap::bits(int y) | 
					
						
							| 
									
										
										
										
											2019-05-06 20:29:52 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-07-03 21:17:35 +02:00
										 |  |  |     return reinterpret_cast<u8*>(scanline(y)); | 
					
						
							| 
									
										
										
										
											2019-05-06 20:29:52 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  | inline Color Bitmap::get_pixel<BitmapFormat::RGB32>(int x, int y) const | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return Color::from_rgb(scanline(y)[x]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  | inline Color Bitmap::get_pixel<BitmapFormat::RGBA32>(int x, int y) const | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return Color::from_rgba(scanline(y)[x]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  | template<> | 
					
						
							|  |  |  | inline Color Bitmap::get_pixel<BitmapFormat::Indexed1>(int x, int y) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return Color::from_rgb(m_palette[bits(y)[x]]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							|  |  |  | inline Color Bitmap::get_pixel<BitmapFormat::Indexed2>(int x, int y) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return Color::from_rgb(m_palette[bits(y)[x]]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							|  |  |  | inline Color Bitmap::get_pixel<BitmapFormat::Indexed4>(int x, int y) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return Color::from_rgb(m_palette[bits(y)[x]]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | template<> | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  | inline Color Bitmap::get_pixel<BitmapFormat::Indexed8>(int x, int y) const | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |     return Color::from_rgb(m_palette[bits(y)[x]]); | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | inline Color Bitmap::get_pixel(int x, int y) const | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     switch (m_format) { | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     case BitmapFormat::RGB32: | 
					
						
							|  |  |  |         return get_pixel<BitmapFormat::RGB32>(x, y); | 
					
						
							|  |  |  |     case BitmapFormat::RGBA32: | 
					
						
							|  |  |  |         return get_pixel<BitmapFormat::RGBA32>(x, y); | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |     case BitmapFormat::Indexed1: | 
					
						
							|  |  |  |         return get_pixel<BitmapFormat::Indexed1>(x, y); | 
					
						
							|  |  |  |     case BitmapFormat::Indexed2: | 
					
						
							|  |  |  |         return get_pixel<BitmapFormat::Indexed2>(x, y); | 
					
						
							|  |  |  |     case BitmapFormat::Indexed4: | 
					
						
							|  |  |  |         return get_pixel<BitmapFormat::Indexed4>(x, y); | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     case BitmapFormat::Indexed8: | 
					
						
							|  |  |  |         return get_pixel<BitmapFormat::Indexed8>(x, y); | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  |     default: | 
					
						
							|  |  |  |         ASSERT_NOT_REACHED(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  | inline void Bitmap::set_pixel<BitmapFormat::RGB32>(int x, int y, Color color) | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     scanline(y)[x] = color.value(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  | inline void Bitmap::set_pixel<BitmapFormat::RGBA32>(int x, int y, Color color) | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     scanline(y)[x] = color.value(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | inline void Bitmap::set_pixel(int x, int y, Color color) | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     switch (m_format) { | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     case BitmapFormat::RGB32: | 
					
						
							|  |  |  |         set_pixel<BitmapFormat::RGB32>(x, y, color); | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     case BitmapFormat::RGBA32: | 
					
						
							|  |  |  |         set_pixel<BitmapFormat::RGBA32>(x, y, color); | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2020-06-17 12:37:16 -07:00
										 |  |  |     case BitmapFormat::Indexed1: | 
					
						
							|  |  |  |     case BitmapFormat::Indexed2: | 
					
						
							|  |  |  |     case BitmapFormat::Indexed4: | 
					
						
							| 
									
										
										
										
											2020-02-14 23:02:47 +01:00
										 |  |  |     case BitmapFormat::Indexed8: | 
					
						
							| 
									
										
										
										
											2019-06-15 11:06:02 +02:00
										 |  |  |         ASSERT_NOT_REACHED(); | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         ASSERT_NOT_REACHED(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-06 11:56:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | } |