mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 00:42:44 +00:00 
			
		
		
		
	LibGfx: Remove indexed palette formats from Bitmap and Painter
Nobody was actually using these formats anymore, and this simplifies and shrinks the code. :^)
This commit is contained in:
		
							parent
							
								
									bcbaad0b1d
								
							
						
					
					
						commit
						a396bb0c0b
					
				
					 10 changed files with 17 additions and 203 deletions
				
			
		|  | @ -44,14 +44,6 @@ static StringView bpp_for_format_resilient(DeprecatedString format) | ||||||
|     unsigned format_uint = format.to_uint().value_or(static_cast<unsigned>(Gfx::BitmapFormat::Invalid)); |     unsigned format_uint = format.to_uint().value_or(static_cast<unsigned>(Gfx::BitmapFormat::Invalid)); | ||||||
|     // Cannot use Gfx::Bitmap::bpp_for_format here, as we have to accept invalid enum values.
 |     // Cannot use Gfx::Bitmap::bpp_for_format here, as we have to accept invalid enum values.
 | ||||||
|     switch (static_cast<Gfx::BitmapFormat>(format_uint)) { |     switch (static_cast<Gfx::BitmapFormat>(format_uint)) { | ||||||
|     case Gfx::BitmapFormat::Indexed1: |  | ||||||
|         return "1"sv; |  | ||||||
|     case Gfx::BitmapFormat::Indexed2: |  | ||||||
|         return "2"sv; |  | ||||||
|     case Gfx::BitmapFormat::Indexed4: |  | ||||||
|         return "4"sv; |  | ||||||
|     case Gfx::BitmapFormat::Indexed8: |  | ||||||
|         return "8"sv; |  | ||||||
|     case Gfx::BitmapFormat::BGRx8888: |     case Gfx::BitmapFormat::BGRx8888: | ||||||
|     case Gfx::BitmapFormat::BGRA8888: |     case Gfx::BitmapFormat::BGRA8888: | ||||||
|         return "32"sv; |         return "32"sv; | ||||||
|  |  | ||||||
|  | @ -102,10 +102,6 @@ RefPtr<Gfx::Bitmap> Clipboard::DataAndType::as_bitmap() const | ||||||
|     if (!Gfx::is_valid_bitmap_format(format.value())) |     if (!Gfx::is_valid_bitmap_format(format.value())) | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     auto bitmap_format = (Gfx::BitmapFormat)format.value(); |     auto bitmap_format = (Gfx::BitmapFormat)format.value(); | ||||||
|     // We cannot handle indexed bitmaps, as the palette would be lost.
 |  | ||||||
|     // Thankfully, everything that copies bitmaps also transforms them to RGB beforehand.
 |  | ||||||
|     if (Gfx::determine_storage_format(bitmap_format) == Gfx::StorageFormat::Indexed8) |  | ||||||
|         return nullptr; |  | ||||||
| 
 | 
 | ||||||
|     // We won't actually write to the clipping_bitmap, so casting away the const is okay.
 |     // We won't actually write to the clipping_bitmap, so casting away the const is okay.
 | ||||||
|     auto clipping_data = const_cast<u8*>(data.data()); |     auto clipping_data = const_cast<u8*>(data.data()); | ||||||
|  |  | ||||||
|  | @ -1025,7 +1025,7 @@ ErrorOr<NonnullOwnPtr<WindowBackingStore>> Window::create_backing_store(Gfx::Int | ||||||
|     auto buffer = TRY(Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes, PAGE_SIZE))); |     auto buffer = TRY(Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes, PAGE_SIZE))); | ||||||
| 
 | 
 | ||||||
|     // FIXME: Plumb scale factor here eventually.
 |     // FIXME: Plumb scale factor here eventually.
 | ||||||
|     auto bitmap = TRY(Gfx::Bitmap::create_with_anonymous_buffer(format, buffer, size, 1, {})); |     auto bitmap = TRY(Gfx::Bitmap::create_with_anonymous_buffer(format, buffer, size, 1)); | ||||||
|     return make<WindowBackingStore>(bitmap); |     return make<WindowBackingStore>(bitmap); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -39,9 +39,6 @@ size_t Bitmap::minimum_pitch(size_t physical_width, BitmapFormat format) | ||||||
| { | { | ||||||
|     size_t element_size; |     size_t element_size; | ||||||
|     switch (determine_storage_format(format)) { |     switch (determine_storage_format(format)) { | ||||||
|     case StorageFormat::Indexed8: |  | ||||||
|         element_size = 1; |  | ||||||
|         break; |  | ||||||
|     case StorageFormat::BGRx8888: |     case StorageFormat::BGRx8888: | ||||||
|     case StorageFormat::BGRA8888: |     case StorageFormat::BGRA8888: | ||||||
|     case StorageFormat::RGBA8888: |     case StorageFormat::RGBA8888: | ||||||
|  | @ -81,7 +78,7 @@ ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_shareable(BitmapFormat format, Int | ||||||
|     auto const data_size = size_in_bytes(pitch, size.height() * scale_factor); |     auto const data_size = size_in_bytes(pitch, size.height() * scale_factor); | ||||||
| 
 | 
 | ||||||
|     auto buffer = TRY(Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(data_size, PAGE_SIZE))); |     auto buffer = TRY(Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(data_size, PAGE_SIZE))); | ||||||
|     auto bitmap = TRY(Bitmap::create_with_anonymous_buffer(format, buffer, size, scale_factor, {})); |     auto bitmap = TRY(Bitmap::create_with_anonymous_buffer(format, buffer, size, scale_factor)); | ||||||
|     return bitmap; |     return bitmap; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -96,7 +93,6 @@ Bitmap::Bitmap(BitmapFormat format, IntSize size, int scale_factor, BackingStore | ||||||
|     VERIFY(!size_would_overflow(format, size, scale_factor)); |     VERIFY(!size_would_overflow(format, size, scale_factor)); | ||||||
|     VERIFY(m_data); |     VERIFY(m_data); | ||||||
|     VERIFY(backing_store.size_in_bytes == size_in_bytes()); |     VERIFY(backing_store.size_in_bytes == size_in_bytes()); | ||||||
|     allocate_palette_from_format(format, {}); |  | ||||||
|     m_needs_munmap = true; |     m_needs_munmap = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -170,8 +166,6 @@ Bitmap::Bitmap(BitmapFormat format, IntSize size, int scale_factor, size_t pitch | ||||||
|     VERIFY(pitch >= minimum_pitch(size.width() * scale_factor, format)); |     VERIFY(pitch >= minimum_pitch(size.width() * scale_factor, format)); | ||||||
|     VERIFY(!size_would_overflow(format, size, scale_factor)); |     VERIFY(!size_would_overflow(format, size, scale_factor)); | ||||||
|     // FIXME: assert that `data` is actually long enough!
 |     // FIXME: assert that `data` is actually long enough!
 | ||||||
| 
 |  | ||||||
|     allocate_palette_from_format(format, {}); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool check_size(IntSize size, int scale_factor, BitmapFormat format, unsigned actual_size) | static bool check_size(IntSize size, int scale_factor, BitmapFormat format, unsigned actual_size) | ||||||
|  | @ -194,12 +188,12 @@ static bool check_size(IntSize size, int scale_factor, BitmapFormat format, unsi | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_with_anonymous_buffer(BitmapFormat format, Core::AnonymousBuffer buffer, IntSize size, int scale_factor, Vector<ARGB32> const& palette) | ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_with_anonymous_buffer(BitmapFormat format, Core::AnonymousBuffer buffer, IntSize size, int scale_factor) | ||||||
| { | { | ||||||
|     if (size_would_overflow(format, size, scale_factor)) |     if (size_would_overflow(format, size, scale_factor)) | ||||||
|         return Error::from_string_literal("Gfx::Bitmap::create_with_anonymous_buffer size overflow"); |         return Error::from_string_literal("Gfx::Bitmap::create_with_anonymous_buffer size overflow"); | ||||||
| 
 | 
 | ||||||
|     return adopt_nonnull_ref_or_enomem(new (nothrow) Bitmap(format, move(buffer), size, scale_factor, palette)); |     return adopt_nonnull_ref_or_enomem(new (nothrow) Bitmap(format, move(buffer), size, scale_factor)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_from_serialized_byte_buffer(ByteBuffer&& buffer) | ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_from_serialized_byte_buffer(ByteBuffer&& buffer) | ||||||
|  | @ -213,8 +207,6 @@ ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_from_serialized_byte_buffer(ByteBu | ||||||
| /// - height
 | /// - height
 | ||||||
| /// - scale_factor
 | /// - scale_factor
 | ||||||
| /// - format
 | /// - format
 | ||||||
| /// - palette count
 |  | ||||||
| /// - palette data (= palette count * BGRA8888)
 |  | ||||||
| /// - image data (= actual size * u8)
 | /// - image data (= actual size * u8)
 | ||||||
| ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_from_serialized_bytes(ReadonlyBytes bytes) | ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_from_serialized_bytes(ReadonlyBytes bytes) | ||||||
| { | { | ||||||
|  | @ -225,20 +217,13 @@ ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_from_serialized_bytes(ReadonlyByte | ||||||
|     auto height = TRY(stream.read_value<unsigned>()); |     auto height = TRY(stream.read_value<unsigned>()); | ||||||
|     auto scale_factor = TRY(stream.read_value<unsigned>()); |     auto scale_factor = TRY(stream.read_value<unsigned>()); | ||||||
|     auto format = TRY(stream.read_value<BitmapFormat>()); |     auto format = TRY(stream.read_value<BitmapFormat>()); | ||||||
|     auto palette_size = TRY(stream.read_value<unsigned>()); |  | ||||||
| 
 | 
 | ||||||
|     if (format > BitmapFormat::BGRA8888 || format < BitmapFormat::Indexed1) |     if (format > BitmapFormat::LastValid || format < BitmapFormat::FirstValid) | ||||||
|         return Error::from_string_literal("Gfx::Bitmap::create_from_serialized_byte_buffer: decode failed"); |         return Error::from_string_literal("Gfx::Bitmap::create_from_serialized_byte_buffer: decode failed"); | ||||||
| 
 | 
 | ||||||
|     if (!check_size({ width, height }, scale_factor, format, actual_size)) |     if (!check_size({ width, height }, scale_factor, format, actual_size)) | ||||||
|         return Error::from_string_literal("Gfx::Bitmap::create_from_serialized_byte_buffer: decode failed"); |         return Error::from_string_literal("Gfx::Bitmap::create_from_serialized_byte_buffer: decode failed"); | ||||||
| 
 | 
 | ||||||
|     Vector<ARGB32> palette; |  | ||||||
|     palette.ensure_capacity(palette_size); |  | ||||||
|     for (size_t i = 0; i < palette_size; ++i) { |  | ||||||
|         palette[i] = TRY(stream.read_value<ARGB32>()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (TRY(stream.size()) - TRY(stream.tell()) < actual_size) |     if (TRY(stream.size()) - TRY(stream.tell()) < actual_size) | ||||||
|         return Error::from_string_literal("Gfx::Bitmap::create_from_serialized_byte_buffer: decode failed"); |         return Error::from_string_literal("Gfx::Bitmap::create_from_serialized_byte_buffer: decode failed"); | ||||||
| 
 | 
 | ||||||
|  | @ -246,30 +231,20 @@ ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_from_serialized_bytes(ReadonlyByte | ||||||
| 
 | 
 | ||||||
|     auto bitmap = TRY(Bitmap::create(format, { width, height }, scale_factor)); |     auto bitmap = TRY(Bitmap::create(format, { width, height }, scale_factor)); | ||||||
| 
 | 
 | ||||||
|     bitmap->m_palette = new ARGB32[palette_size]; |  | ||||||
|     memcpy(bitmap->m_palette, palette.data(), palette_size * sizeof(ARGB32)); |  | ||||||
| 
 |  | ||||||
|     data.copy_to({ bitmap->scanline(0), bitmap->size_in_bytes() }); |     data.copy_to({ bitmap->scanline(0), bitmap->size_in_bytes() }); | ||||||
|     return bitmap; |     return bitmap; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<ByteBuffer> Bitmap::serialize_to_byte_buffer() const | ErrorOr<ByteBuffer> Bitmap::serialize_to_byte_buffer() const | ||||||
| { | { | ||||||
|     auto buffer = TRY(ByteBuffer::create_uninitialized(sizeof(size_t) + 4 * sizeof(unsigned) + sizeof(BitmapFormat) + sizeof(ARGB32) * palette_size(m_format) + size_in_bytes())); |     auto buffer = TRY(ByteBuffer::create_uninitialized(sizeof(size_t) + 4 * sizeof(unsigned) + sizeof(BitmapFormat) + size_in_bytes())); | ||||||
|     FixedMemoryStream stream { buffer.span() }; |     FixedMemoryStream stream { buffer.span() }; | ||||||
| 
 | 
 | ||||||
|     auto palette = palette_to_vector(); |  | ||||||
| 
 |  | ||||||
|     TRY(stream.write_value(size_in_bytes())); |     TRY(stream.write_value(size_in_bytes())); | ||||||
|     TRY(stream.write_value<unsigned>(size().width())); |     TRY(stream.write_value<unsigned>(size().width())); | ||||||
|     TRY(stream.write_value<unsigned>(size().height())); |     TRY(stream.write_value<unsigned>(size().height())); | ||||||
|     TRY(stream.write_value<unsigned>(scale())); |     TRY(stream.write_value<unsigned>(scale())); | ||||||
|     TRY(stream.write_value(m_format)); |     TRY(stream.write_value(m_format)); | ||||||
|     TRY(stream.write_value<unsigned>(palette.size())); |  | ||||||
| 
 |  | ||||||
|     for (auto& p : palette) { |  | ||||||
|         TRY(stream.write_value(p)); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     auto size = size_in_bytes(); |     auto size = size_in_bytes(); | ||||||
|     TRY(stream.write_until_depleted({ scanline(0), size })); |     TRY(stream.write_until_depleted({ scanline(0), size })); | ||||||
|  | @ -279,7 +254,7 @@ ErrorOr<ByteBuffer> Bitmap::serialize_to_byte_buffer() const | ||||||
|     return buffer; |     return buffer; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Bitmap::Bitmap(BitmapFormat format, Core::AnonymousBuffer buffer, IntSize size, int scale_factor, Vector<ARGB32> const& palette) | Bitmap::Bitmap(BitmapFormat format, Core::AnonymousBuffer buffer, IntSize size, int scale_factor) | ||||||
|     : m_size(size) |     : m_size(size) | ||||||
|     , m_scale(scale_factor) |     , m_scale(scale_factor) | ||||||
|     , m_data(buffer.data<void>()) |     , m_data(buffer.data<void>()) | ||||||
|  | @ -287,11 +262,7 @@ Bitmap::Bitmap(BitmapFormat format, Core::AnonymousBuffer buffer, IntSize size, | ||||||
|     , m_format(format) |     , m_format(format) | ||||||
|     , m_buffer(move(buffer)) |     , m_buffer(move(buffer)) | ||||||
| { | { | ||||||
|     VERIFY(!is_indexed() || !palette.is_empty()); |  | ||||||
|     VERIFY(!size_would_overflow(format, size, scale_factor)); |     VERIFY(!size_would_overflow(format, size, scale_factor)); | ||||||
| 
 |  | ||||||
|     if (is_indexed(m_format)) |  | ||||||
|         allocate_palette_from_format(m_format, palette); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Bitmap::clone() const | ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Bitmap::clone() const | ||||||
|  | @ -545,7 +516,7 @@ ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::to_bitmap_backed_by_anonymous_buffer() co | ||||||
|         return NonnullRefPtr { const_cast<Bitmap&>(*this) }; |         return NonnullRefPtr { const_cast<Bitmap&>(*this) }; | ||||||
|     } |     } | ||||||
|     auto buffer = TRY(Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes(), PAGE_SIZE))); |     auto buffer = TRY(Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes(), PAGE_SIZE))); | ||||||
|     auto bitmap = TRY(Bitmap::create_with_anonymous_buffer(m_format, move(buffer), size(), scale(), palette_to_vector())); |     auto bitmap = TRY(Bitmap::create_with_anonymous_buffer(m_format, move(buffer), size(), scale())); | ||||||
|     memcpy(bitmap->scanline(0), scanline(0), size_in_bytes()); |     memcpy(bitmap->scanline(0), scanline(0), size_in_bytes()); | ||||||
|     return bitmap; |     return bitmap; | ||||||
| } | } | ||||||
|  | @ -567,7 +538,6 @@ Bitmap::~Bitmap() | ||||||
|         VERIFY(rc == 0); |         VERIFY(rc == 0); | ||||||
|     } |     } | ||||||
|     m_data = nullptr; |     m_data = nullptr; | ||||||
|     delete[] m_palette; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Bitmap::strip_alpha_channel() | void Bitmap::strip_alpha_channel() | ||||||
|  | @ -588,7 +558,6 @@ void Bitmap::set_mmap_name([[maybe_unused]] DeprecatedString const& name) | ||||||
| 
 | 
 | ||||||
| void Bitmap::fill(Color color) | void Bitmap::fill(Color color) | ||||||
| { | { | ||||||
|     VERIFY(!is_indexed(m_format)); |  | ||||||
|     for (int y = 0; y < physical_height(); ++y) { |     for (int y = 0; y < physical_height(); ++y) { | ||||||
|         auto* scanline = this->scanline(y); |         auto* scanline = this->scanline(y); | ||||||
|         fast_u32_fill(scanline, color.value(), physical_width()); |         fast_u32_fill(scanline, color.value(), physical_width()); | ||||||
|  | @ -660,28 +629,6 @@ ErrorOr<BackingStore> Bitmap::allocate_backing_store(BitmapFormat format, IntSiz | ||||||
|     return BackingStore { data, pitch, data_size_in_bytes }; |     return BackingStore { data, pitch, data_size_in_bytes }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Bitmap::allocate_palette_from_format(BitmapFormat format, Vector<ARGB32> const& source_palette) |  | ||||||
| { |  | ||||||
|     size_t size = palette_size(format); |  | ||||||
|     if (size == 0) |  | ||||||
|         return; |  | ||||||
|     m_palette = new ARGB32[size]; |  | ||||||
|     if (!source_palette.is_empty()) { |  | ||||||
|         VERIFY(source_palette.size() == size); |  | ||||||
|         memcpy(m_palette, source_palette.data(), size * sizeof(ARGB32)); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Vector<ARGB32> Bitmap::palette_to_vector() const |  | ||||||
| { |  | ||||||
|     Vector<ARGB32> vector; |  | ||||||
|     auto size = palette_size(m_format); |  | ||||||
|     vector.ensure_capacity(size); |  | ||||||
|     for (size_t i = 0; i < size; ++i) |  | ||||||
|         vector.unchecked_append(palette_color(i).value()); |  | ||||||
|     return vector; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool Bitmap::visually_equals(Bitmap const& other) const | bool Bitmap::visually_equals(Bitmap const& other) const | ||||||
| { | { | ||||||
|     auto own_width = width(); |     auto own_width = width(); | ||||||
|  |  | ||||||
|  | @ -38,23 +38,18 @@ namespace Gfx { | ||||||
| 
 | 
 | ||||||
| enum class BitmapFormat { | enum class BitmapFormat { | ||||||
|     Invalid, |     Invalid, | ||||||
|     Indexed1, |  | ||||||
|     Indexed2, |  | ||||||
|     Indexed4, |  | ||||||
|     Indexed8, |  | ||||||
|     BGRx8888, |     BGRx8888, | ||||||
|     BGRA8888, |     BGRA8888, | ||||||
|     RGBA8888, |     RGBA8888, | ||||||
|  | 
 | ||||||
|  |     FirstValid = BGRx8888, | ||||||
|  |     LastValid = RGBA8888, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| inline bool is_valid_bitmap_format(unsigned format) | inline bool is_valid_bitmap_format(unsigned format) | ||||||
| { | { | ||||||
|     switch (format) { |     switch (format) { | ||||||
|     case (unsigned)BitmapFormat::Invalid: |     case (unsigned)BitmapFormat::Invalid: | ||||||
|     case (unsigned)BitmapFormat::Indexed1: |  | ||||||
|     case (unsigned)BitmapFormat::Indexed2: |  | ||||||
|     case (unsigned)BitmapFormat::Indexed4: |  | ||||||
|     case (unsigned)BitmapFormat::Indexed8: |  | ||||||
|     case (unsigned)BitmapFormat::BGRx8888: |     case (unsigned)BitmapFormat::BGRx8888: | ||||||
|     case (unsigned)BitmapFormat::BGRA8888: |     case (unsigned)BitmapFormat::BGRA8888: | ||||||
|     case (unsigned)BitmapFormat::RGBA8888: |     case (unsigned)BitmapFormat::RGBA8888: | ||||||
|  | @ -64,7 +59,6 @@ inline bool is_valid_bitmap_format(unsigned format) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| enum class StorageFormat { | enum class StorageFormat { | ||||||
|     Indexed8, |  | ||||||
|     BGRx8888, |     BGRx8888, | ||||||
|     BGRA8888, |     BGRA8888, | ||||||
|     RGBA8888, |     RGBA8888, | ||||||
|  | @ -79,11 +73,6 @@ inline StorageFormat determine_storage_format(BitmapFormat format) | ||||||
|         return StorageFormat::BGRA8888; |         return StorageFormat::BGRA8888; | ||||||
|     case BitmapFormat::RGBA8888: |     case BitmapFormat::RGBA8888: | ||||||
|         return StorageFormat::RGBA8888; |         return StorageFormat::RGBA8888; | ||||||
|     case BitmapFormat::Indexed1: |  | ||||||
|     case BitmapFormat::Indexed2: |  | ||||||
|     case BitmapFormat::Indexed4: |  | ||||||
|     case BitmapFormat::Indexed8: |  | ||||||
|         return StorageFormat::Indexed8; |  | ||||||
|     default: |     default: | ||||||
|         VERIFY_NOT_REACHED(); |         VERIFY_NOT_REACHED(); | ||||||
|     } |     } | ||||||
|  | @ -104,7 +93,7 @@ public: | ||||||
|     [[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> load_from_file(StringView path, int scale_factor = 1, Optional<IntSize> ideal_size = {}); |     [[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> load_from_file(StringView path, int scale_factor = 1, Optional<IntSize> ideal_size = {}); | ||||||
|     [[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> load_from_file(NonnullOwnPtr<Core::File>, StringView path, Optional<IntSize> ideal_size = {}); |     [[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> load_from_file(NonnullOwnPtr<Core::File>, StringView path, Optional<IntSize> ideal_size = {}); | ||||||
|     [[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> load_from_bytes(ReadonlyBytes, Optional<IntSize> ideal_size = {}, Optional<DeprecatedString> mine_type = {}); |     [[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> load_from_bytes(ReadonlyBytes, Optional<IntSize> ideal_size = {}, Optional<DeprecatedString> mine_type = {}); | ||||||
|     [[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create_with_anonymous_buffer(BitmapFormat, Core::AnonymousBuffer, IntSize, int intrinsic_scale, Vector<ARGB32> const& palette); |     [[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create_with_anonymous_buffer(BitmapFormat, Core::AnonymousBuffer, IntSize, int intrinsic_scale); | ||||||
|     static ErrorOr<NonnullRefPtr<Bitmap>> create_from_serialized_bytes(ReadonlyBytes); |     static ErrorOr<NonnullRefPtr<Bitmap>> create_from_serialized_bytes(ReadonlyBytes); | ||||||
|     static ErrorOr<NonnullRefPtr<Bitmap>> create_from_serialized_byte_buffer(ByteBuffer&&); |     static ErrorOr<NonnullRefPtr<Bitmap>> create_from_serialized_byte_buffer(ByteBuffer&&); | ||||||
| 
 | 
 | ||||||
|  | @ -162,46 +151,9 @@ public: | ||||||
|     [[nodiscard]] int physical_height() const { return physical_size().height(); } |     [[nodiscard]] int physical_height() const { return physical_size().height(); } | ||||||
|     [[nodiscard]] size_t pitch() const { return m_pitch; } |     [[nodiscard]] size_t pitch() const { return m_pitch; } | ||||||
| 
 | 
 | ||||||
|     [[nodiscard]] ALWAYS_INLINE bool is_indexed() const |  | ||||||
|     { |  | ||||||
|         return is_indexed(m_format); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     [[nodiscard]] ALWAYS_INLINE static bool is_indexed(BitmapFormat format) |  | ||||||
|     { |  | ||||||
|         return format == BitmapFormat::Indexed8 || format == BitmapFormat::Indexed4 |  | ||||||
|             || format == BitmapFormat::Indexed2 || format == BitmapFormat::Indexed1; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     [[nodiscard]] static size_t palette_size(BitmapFormat format) |  | ||||||
|     { |  | ||||||
|         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; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     [[nodiscard]] Vector<ARGB32> palette_to_vector() const; |  | ||||||
| 
 |  | ||||||
|     [[nodiscard]] static unsigned bpp_for_format(BitmapFormat format) |     [[nodiscard]] static unsigned bpp_for_format(BitmapFormat format) | ||||||
|     { |     { | ||||||
|         switch (format) { |         switch (format) { | ||||||
|         case BitmapFormat::Indexed1: |  | ||||||
|             return 1; |  | ||||||
|         case BitmapFormat::Indexed2: |  | ||||||
|             return 2; |  | ||||||
|         case BitmapFormat::Indexed4: |  | ||||||
|             return 4; |  | ||||||
|         case BitmapFormat::Indexed8: |  | ||||||
|             return 8; |  | ||||||
|         case BitmapFormat::BGRx8888: |         case BitmapFormat::BGRx8888: | ||||||
|         case BitmapFormat::BGRA8888: |         case BitmapFormat::BGRA8888: | ||||||
|             return 32; |             return 32; | ||||||
|  | @ -232,9 +184,6 @@ public: | ||||||
|     [[nodiscard]] static constexpr size_t size_in_bytes(size_t pitch, int physical_height) { return pitch * physical_height; } |     [[nodiscard]] static constexpr size_t size_in_bytes(size_t pitch, int physical_height) { return pitch * physical_height; } | ||||||
|     [[nodiscard]] size_t size_in_bytes() const { return size_in_bytes(m_pitch, physical_height()); } |     [[nodiscard]] size_t size_in_bytes() const { return size_in_bytes(m_pitch, physical_height()); } | ||||||
| 
 | 
 | ||||||
|     [[nodiscard]] Color palette_color(u8 index) const { return Color::from_argb(m_palette[index]); } |  | ||||||
|     void set_palette_color(u8 index, Color color) { m_palette[index] = color.value(); } |  | ||||||
| 
 |  | ||||||
|     template<StorageFormat> |     template<StorageFormat> | ||||||
|     [[nodiscard]] Color get_pixel(int physical_x, int physical_y) const; |     [[nodiscard]] Color get_pixel(int physical_x, int physical_y) const; | ||||||
|     [[nodiscard]] Color get_pixel(int physical_x, int physical_y) const; |     [[nodiscard]] Color get_pixel(int physical_x, int physical_y) const; | ||||||
|  | @ -270,16 +219,13 @@ public: | ||||||
| private: | private: | ||||||
|     Bitmap(BitmapFormat, IntSize, int, BackingStore const&); |     Bitmap(BitmapFormat, IntSize, int, BackingStore const&); | ||||||
|     Bitmap(BitmapFormat, IntSize, int, size_t pitch, void*); |     Bitmap(BitmapFormat, IntSize, int, size_t pitch, void*); | ||||||
|     Bitmap(BitmapFormat, Core::AnonymousBuffer, IntSize, int, Vector<ARGB32> const& palette); |     Bitmap(BitmapFormat, Core::AnonymousBuffer, IntSize, int); | ||||||
| 
 | 
 | ||||||
|     static ErrorOr<BackingStore> allocate_backing_store(BitmapFormat format, IntSize size, int scale_factor); |     static ErrorOr<BackingStore> allocate_backing_store(BitmapFormat format, IntSize size, int scale_factor); | ||||||
| 
 | 
 | ||||||
|     void allocate_palette_from_format(BitmapFormat, Vector<ARGB32> const& source_palette); |  | ||||||
| 
 |  | ||||||
|     IntSize m_size; |     IntSize m_size; | ||||||
|     int m_scale; |     int m_scale; | ||||||
|     void* m_data { nullptr }; |     void* m_data { nullptr }; | ||||||
|     ARGB32* m_palette { nullptr }; |  | ||||||
|     size_t m_pitch { 0 }; |     size_t m_pitch { 0 }; | ||||||
|     BitmapFormat m_format { BitmapFormat::Invalid }; |     BitmapFormat m_format { BitmapFormat::Invalid }; | ||||||
|     bool m_needs_munmap { false }; |     bool m_needs_munmap { false }; | ||||||
|  | @ -337,14 +283,6 @@ ALWAYS_INLINE Color Bitmap::get_pixel<StorageFormat::BGRA8888>(int x, int y) con | ||||||
|     return Color::from_argb(scanline(y)[x]); |     return Color::from_argb(scanline(y)[x]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| ALWAYS_INLINE Color Bitmap::get_pixel<StorageFormat::Indexed8>(int x, int y) const |  | ||||||
| { |  | ||||||
|     VERIFY(x >= 0); |  | ||||||
|     VERIFY(x < physical_width()); |  | ||||||
|     return Color::from_rgb(m_palette[scanline_u8(y)[x]]); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ALWAYS_INLINE Color Bitmap::get_pixel(int x, int y) const | ALWAYS_INLINE Color Bitmap::get_pixel(int x, int y) const | ||||||
| { | { | ||||||
|     switch (determine_storage_format(m_format)) { |     switch (determine_storage_format(m_format)) { | ||||||
|  | @ -352,8 +290,6 @@ ALWAYS_INLINE Color Bitmap::get_pixel(int x, int y) const | ||||||
|         return get_pixel<StorageFormat::BGRx8888>(x, y); |         return get_pixel<StorageFormat::BGRx8888>(x, y); | ||||||
|     case StorageFormat::BGRA8888: |     case StorageFormat::BGRA8888: | ||||||
|         return get_pixel<StorageFormat::BGRA8888>(x, y); |         return get_pixel<StorageFormat::BGRA8888>(x, y); | ||||||
|     case StorageFormat::Indexed8: |  | ||||||
|         return get_pixel<StorageFormat::Indexed8>(x, y); |  | ||||||
|     default: |     default: | ||||||
|         VERIFY_NOT_REACHED(); |         VERIFY_NOT_REACHED(); | ||||||
|     } |     } | ||||||
|  | @ -398,8 +334,6 @@ ALWAYS_INLINE void Bitmap::set_pixel(int x, int y, Color color) | ||||||
|     case StorageFormat::RGBA8888: |     case StorageFormat::RGBA8888: | ||||||
|         set_pixel<StorageFormat::RGBA8888>(x, y, color); |         set_pixel<StorageFormat::RGBA8888>(x, y, color); | ||||||
|         break; |         break; | ||||||
|     case StorageFormat::Indexed8: |  | ||||||
|         VERIFY_NOT_REACHED(); |  | ||||||
|     default: |     default: | ||||||
|         VERIFY_NOT_REACHED(); |         VERIFY_NOT_REACHED(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -888,8 +888,6 @@ ErrorOr<NonnullOwnPtr<ColorIndexingTransform>> ColorIndexingTransform::read(Litt | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullRefPtr<Bitmap>> ColorIndexingTransform::transform(NonnullRefPtr<Bitmap> bitmap) | ErrorOr<NonnullRefPtr<Bitmap>> ColorIndexingTransform::transform(NonnullRefPtr<Bitmap> bitmap) | ||||||
| { | { | ||||||
|     // FIXME: If this is the last transform, consider returning an Indexed8 bitmap here?
 |  | ||||||
| 
 |  | ||||||
|     if (pixels_per_pixel() == 1) { |     if (pixels_per_pixel() == 1) { | ||||||
|         for (ARGB32& pixel : *bitmap) { |         for (ARGB32& pixel : *bitmap) { | ||||||
|             // "The inverse transform for the image is simply replacing the pixel values (which are indices to the color table)
 |             // "The inverse transform for the image is simply replacing the pixel values (which are indices to the color table)
 | ||||||
|  |  | ||||||
|  | @ -63,14 +63,6 @@ ALWAYS_INLINE static Color color_for_format(BitmapFormat format, ARGB32 value) | ||||||
| template<BitmapFormat format = BitmapFormat::Invalid> | template<BitmapFormat format = BitmapFormat::Invalid> | ||||||
| ALWAYS_INLINE Color get_pixel(Gfx::Bitmap const& bitmap, int x, int y) | ALWAYS_INLINE Color get_pixel(Gfx::Bitmap const& bitmap, int x, int y) | ||||||
| { | { | ||||||
|     if constexpr (format == BitmapFormat::Indexed8) |  | ||||||
|         return bitmap.palette_color(bitmap.scanline_u8(y)[x]); |  | ||||||
|     if constexpr (format == BitmapFormat::Indexed4) |  | ||||||
|         return bitmap.palette_color(bitmap.scanline_u8(y)[x]); |  | ||||||
|     if constexpr (format == BitmapFormat::Indexed2) |  | ||||||
|         return bitmap.palette_color(bitmap.scanline_u8(y)[x]); |  | ||||||
|     if constexpr (format == BitmapFormat::Indexed1) |  | ||||||
|         return bitmap.palette_color(bitmap.scanline_u8(y)[x]); |  | ||||||
|     if constexpr (format == BitmapFormat::BGRx8888) |     if constexpr (format == BitmapFormat::BGRx8888) | ||||||
|         return Color::from_rgb(bitmap.scanline(y)[x]); |         return Color::from_rgb(bitmap.scanline(y)[x]); | ||||||
|     if constexpr (format == BitmapFormat::BGRA8888) |     if constexpr (format == BitmapFormat::BGRA8888) | ||||||
|  | @ -1126,18 +1118,6 @@ void Painter::blit(IntPoint position, Gfx::Bitmap const& source, IntRect const& | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (Bitmap::is_indexed(source.format())) { |  | ||||||
|         u8 const* src = source.scanline_u8(src_rect.top() + first_row) + src_rect.left() + first_column; |  | ||||||
|         size_t const src_skip = source.pitch(); |  | ||||||
|         for (int row = first_row; row <= last_row; ++row) { |  | ||||||
|             for (int i = 0; i < clipped_rect.width(); ++i) |  | ||||||
|                 dst[i] = source.palette_color(src[i]).value(); |  | ||||||
|             dst += dst_skip; |  | ||||||
|             src += src_skip; |  | ||||||
|         } |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     VERIFY_NOT_REACHED(); |     VERIFY_NOT_REACHED(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1373,18 +1353,6 @@ void Painter::draw_scaled_bitmap(IntRect const& a_dst_rect, Gfx::Bitmap const& s | ||||||
|         case BitmapFormat::BGRA8888: |         case BitmapFormat::BGRA8888: | ||||||
|             do_draw_scaled_bitmap<true>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::BGRA8888>, opacity, scaling_mode); |             do_draw_scaled_bitmap<true>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::BGRA8888>, opacity, scaling_mode); | ||||||
|             break; |             break; | ||||||
|         case BitmapFormat::Indexed8: |  | ||||||
|             do_draw_scaled_bitmap<true>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::Indexed8>, opacity, scaling_mode); |  | ||||||
|             break; |  | ||||||
|         case BitmapFormat::Indexed4: |  | ||||||
|             do_draw_scaled_bitmap<true>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::Indexed4>, opacity, scaling_mode); |  | ||||||
|             break; |  | ||||||
|         case BitmapFormat::Indexed2: |  | ||||||
|             do_draw_scaled_bitmap<true>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::Indexed2>, opacity, scaling_mode); |  | ||||||
|             break; |  | ||||||
|         case BitmapFormat::Indexed1: |  | ||||||
|             do_draw_scaled_bitmap<true>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::Indexed1>, opacity, scaling_mode); |  | ||||||
|             break; |  | ||||||
|         default: |         default: | ||||||
|             do_draw_scaled_bitmap<true>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::Invalid>, opacity, scaling_mode); |             do_draw_scaled_bitmap<true>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::Invalid>, opacity, scaling_mode); | ||||||
|             break; |             break; | ||||||
|  | @ -1394,9 +1362,6 @@ void Painter::draw_scaled_bitmap(IntRect const& a_dst_rect, Gfx::Bitmap const& s | ||||||
|         case BitmapFormat::BGRx8888: |         case BitmapFormat::BGRx8888: | ||||||
|             do_draw_scaled_bitmap<false>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::BGRx8888>, opacity, scaling_mode); |             do_draw_scaled_bitmap<false>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::BGRx8888>, opacity, scaling_mode); | ||||||
|             break; |             break; | ||||||
|         case BitmapFormat::Indexed8: |  | ||||||
|             do_draw_scaled_bitmap<false>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::Indexed8>, opacity, scaling_mode); |  | ||||||
|             break; |  | ||||||
|         default: |         default: | ||||||
|             do_draw_scaled_bitmap<false>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::Invalid>, opacity, scaling_mode); |             do_draw_scaled_bitmap<false>(*m_target, dst_rect, clipped_rect, source, src_rect, Gfx::get_pixel<BitmapFormat::Invalid>, opacity, scaling_mode); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|  | @ -34,11 +34,6 @@ ErrorOr<void> encode(Encoder& encoder, Gfx::ShareableBitmap const& shareable_bit | ||||||
|     TRY(encoder.encode(bitmap.size())); |     TRY(encoder.encode(bitmap.size())); | ||||||
|     TRY(encoder.encode(static_cast<u32>(bitmap.scale()))); |     TRY(encoder.encode(static_cast<u32>(bitmap.scale()))); | ||||||
|     TRY(encoder.encode(static_cast<u32>(bitmap.format()))); |     TRY(encoder.encode(static_cast<u32>(bitmap.format()))); | ||||||
|     if (bitmap.is_indexed()) { |  | ||||||
|         auto palette = bitmap.palette_to_vector(); |  | ||||||
|         TRY(encoder.encode(palette)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -57,12 +52,8 @@ ErrorOr<Gfx::ShareableBitmap> decode(Decoder& decoder) | ||||||
| 
 | 
 | ||||||
|     auto bitmap_format = static_cast<Gfx::BitmapFormat>(raw_bitmap_format); |     auto bitmap_format = static_cast<Gfx::BitmapFormat>(raw_bitmap_format); | ||||||
| 
 | 
 | ||||||
|     Vector<Gfx::ARGB32> palette; |  | ||||||
|     if (Gfx::Bitmap::is_indexed(bitmap_format)) |  | ||||||
|         palette = TRY(decoder.decode<decltype(palette)>()); |  | ||||||
| 
 |  | ||||||
|     auto buffer = TRY(Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), Gfx::Bitmap::size_in_bytes(Gfx::Bitmap::minimum_pitch(size.width() * scale, bitmap_format), size.height() * scale))); |     auto buffer = TRY(Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), Gfx::Bitmap::size_in_bytes(Gfx::Bitmap::minimum_pitch(size.width() * scale, bitmap_format), size.height() * scale))); | ||||||
|     auto bitmap = TRY(Gfx::Bitmap::create_with_anonymous_buffer(bitmap_format, move(buffer), size, scale, palette)); |     auto bitmap = TRY(Gfx::Bitmap::create_with_anonymous_buffer(bitmap_format, move(buffer), size, scale)); | ||||||
| 
 | 
 | ||||||
|     return Gfx::ShareableBitmap { move(bitmap), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap }; |     return Gfx::ShareableBitmap { move(bitmap), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -778,8 +778,7 @@ void ConnectionFromClient::set_window_backing_store(i32 window_id, [[maybe_unuse | ||||||
|             has_alpha_channel ? Gfx::BitmapFormat::BGRA8888 : Gfx::BitmapFormat::BGRx8888, |             has_alpha_channel ? Gfx::BitmapFormat::BGRA8888 : Gfx::BitmapFormat::BGRx8888, | ||||||
|             buffer_or_error.release_value(), |             buffer_or_error.release_value(), | ||||||
|             size, |             size, | ||||||
|             1, |             1); | ||||||
|             {}); |  | ||||||
|         if (backing_store_or_error.is_error()) { |         if (backing_store_or_error.is_error()) { | ||||||
|             did_misbehave(""); |             did_misbehave(""); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -71,11 +71,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) | ||||||
|     if (move_alpha_to_rgb) { |     if (move_alpha_to_rgb) { | ||||||
|         switch (frame->format()) { |         switch (frame->format()) { | ||||||
|         case Gfx::BitmapFormat::Invalid: |         case Gfx::BitmapFormat::Invalid: | ||||||
|         case Gfx::BitmapFormat::Indexed1: |             warnln("Can't --strip-alpha with invalid bitmaps"); | ||||||
|         case Gfx::BitmapFormat::Indexed2: |  | ||||||
|         case Gfx::BitmapFormat::Indexed4: |  | ||||||
|         case Gfx::BitmapFormat::Indexed8: |  | ||||||
|             warnln("Can't --strip-alpha with indexed or invalid bitmaps"); |  | ||||||
|             return 1; |             return 1; | ||||||
|         case Gfx::BitmapFormat::RGBA8888: |         case Gfx::BitmapFormat::RGBA8888: | ||||||
|             // No image decoder currently produces bitmaps with this format.
 |             // No image decoder currently produces bitmaps with this format.
 | ||||||
|  | @ -96,11 +92,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) | ||||||
|     if (strip_alpha) { |     if (strip_alpha) { | ||||||
|         switch (frame->format()) { |         switch (frame->format()) { | ||||||
|         case Gfx::BitmapFormat::Invalid: |         case Gfx::BitmapFormat::Invalid: | ||||||
|         case Gfx::BitmapFormat::Indexed1: |             warnln("Can't --strip-alpha with invalid bitmaps"); | ||||||
|         case Gfx::BitmapFormat::Indexed2: |  | ||||||
|         case Gfx::BitmapFormat::Indexed4: |  | ||||||
|         case Gfx::BitmapFormat::Indexed8: |  | ||||||
|             warnln("Can't --strip-alpha with indexed or invalid bitmaps"); |  | ||||||
|             return 1; |             return 1; | ||||||
|         case Gfx::BitmapFormat::RGBA8888: |         case Gfx::BitmapFormat::RGBA8888: | ||||||
|             // No image decoder currently produces bitmaps with this format.
 |             // No image decoder currently produces bitmaps with this format.
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling