diff --git a/Libraries/LibGfx/Bitmap.cpp b/Libraries/LibGfx/Bitmap.cpp index c5b0a98abc..b33924f981 100644 --- a/Libraries/LibGfx/Bitmap.cpp +++ b/Libraries/LibGfx/Bitmap.cpp @@ -127,6 +127,16 @@ ErrorOr> Bitmap::create_with_anonymous_buffer(BitmapFormat return adopt_nonnull_ref_or_enomem(new (nothrow) Bitmap(format, alpha_type, move(buffer), size)); } +ErrorOr> Bitmap::create_with_raw_data(BitmapFormat format, AlphaType alpha_type, ReadonlyBytes raw_data, IntSize size) +{ + if (size_would_overflow(format, size)) + return Error::from_string_literal("Gfx::Bitmap::create_with_raw_data size overflow"); + + auto backing_store = TRY(Bitmap::allocate_backing_store(format, size, InitializeBackingStore::No)); + raw_data.copy_to(Bytes { backing_store.data, backing_store.size_in_bytes }); + return AK::adopt_nonnull_ref_or_enomem(new (nothrow) Bitmap(format, alpha_type, size, backing_store)); +} + Bitmap::Bitmap(BitmapFormat format, AlphaType alpha_type, Core::AnonymousBuffer buffer, IntSize size) : m_size(size) , m_data(buffer.data()) @@ -242,7 +252,7 @@ Gfx::ShareableBitmap Bitmap::to_shareable_bitmap() const return Gfx::ShareableBitmap { bitmap_or_error.release_value_but_fixme_should_propagate_errors(), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap }; } -ErrorOr Bitmap::allocate_backing_store(BitmapFormat format, IntSize size) +ErrorOr Bitmap::allocate_backing_store(BitmapFormat format, IntSize size, InitializeBackingStore initialize_backing_store) { if (size.is_empty()) return Error::from_string_literal("Gfx::Bitmap backing store size is empty"); @@ -253,7 +263,11 @@ ErrorOr Bitmap::allocate_backing_store(BitmapFormat format, IntSiz auto const pitch = minimum_pitch(size.width(), format); auto const data_size_in_bytes = size_in_bytes(pitch, size.height()); - void* data = kcalloc(1, data_size_in_bytes); + void* data; + if (initialize_backing_store == InitializeBackingStore::Yes) + data = kcalloc(1, data_size_in_bytes); + else + data = kmalloc(data_size_in_bytes); if (data == nullptr) return Error::from_errno(errno); return BackingStore { data, pitch, data_size_in_bytes }; diff --git a/Libraries/LibGfx/Bitmap.h b/Libraries/LibGfx/Bitmap.h index 31c7aa5619..d0d4871b7c 100644 --- a/Libraries/LibGfx/Bitmap.h +++ b/Libraries/LibGfx/Bitmap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2024, Andreas Kling + * Copyright (c) 2018-2025, Andreas Kling * Copyright (c) 2022, Timothy Slater * * SPDX-License-Identifier: BSD-2-Clause @@ -70,6 +70,7 @@ public: [[nodiscard]] static ErrorOr> create(BitmapFormat, AlphaType, IntSize); [[nodiscard]] static ErrorOr> create_shareable(BitmapFormat, AlphaType, IntSize); [[nodiscard]] static ErrorOr> create_wrapper(BitmapFormat, AlphaType, IntSize, size_t pitch, void*, Function&& destruction_callback = {}); + [[nodiscard]] static ErrorOr> create_with_raw_data(BitmapFormat, AlphaType, ReadonlyBytes, IntSize); [[nodiscard]] static ErrorOr> create_with_anonymous_buffer(BitmapFormat, AlphaType, Core::AnonymousBuffer, IntSize); ErrorOr> clone() const; @@ -172,7 +173,11 @@ private: Bitmap(BitmapFormat, AlphaType, IntSize, size_t pitch, void*, Function&& destruction_callback); Bitmap(BitmapFormat, AlphaType, Core::AnonymousBuffer, IntSize); - static ErrorOr allocate_backing_store(BitmapFormat format, IntSize size); + enum class InitializeBackingStore { + No, + Yes, + }; + static ErrorOr allocate_backing_store(BitmapFormat format, IntSize size, InitializeBackingStore = InitializeBackingStore::Yes); IntSize m_size; void* m_data { nullptr }; diff --git a/Libraries/LibGfx/BitmapSequence.cpp b/Libraries/LibGfx/BitmapSequence.cpp index ed3d6f4de9..3d997d30f7 100644 --- a/Libraries/LibGfx/BitmapSequence.cpp +++ b/Libraries/LibGfx/BitmapSequence.cpp @@ -128,14 +128,9 @@ ErrorOr decode(Decoder& decoder) if (size_check.has_overflow() || size_check.value() > bytes.size()) return Error::from_string_literal("IPC: Invalid Gfx::BitmapSequence buffer data"); - auto buffer = TRY(Core::AnonymousBuffer::create_with_size(size_in_bytes)); - auto buffer_bytes = Bytes { buffer.data(), buffer.size() }; - - bytes.slice(bytes_read, size_in_bytes).copy_to(buffer_bytes); - + auto slice = bytes.slice(bytes_read, size_in_bytes); bytes_read += size_in_bytes; - - bitmap = TRY(Gfx::Bitmap::create_with_anonymous_buffer(metadata.format, metadata.alpha_type, move(buffer), metadata.size)); + bitmap = TRY(Gfx::Bitmap::create_with_raw_data(metadata.format, metadata.alpha_type, slice, metadata.size)); } bitmaps.append(bitmap);