ladybird/Userland/Libraries/LibGfx/ShareableBitmap.cpp
Timothy Flynn ab99ed5fba LibIPC+Everywhere: Change IPC::encode's return type to ErrorOr
In doing so, this removes all uses of the Encoder's stream operator,
except for where it is currently still used in the generated IPC code.
So the stream operator currently discards any errors, which is the
existing behavior. A subsequent commit will propagate the errors.
2023-01-04 11:49:15 +01:00

70 lines
2.2 KiB
C++

/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Bitmap.h>
#include <LibGfx/ShareableBitmap.h>
#include <LibGfx/Size.h>
#include <LibIPC/Decoder.h>
#include <LibIPC/Encoder.h>
#include <LibIPC/File.h>
namespace Gfx {
ShareableBitmap::ShareableBitmap(NonnullRefPtr<Bitmap> bitmap, Tag)
: m_bitmap(move(bitmap))
{
}
}
namespace IPC {
template<>
ErrorOr<void> encode(Encoder& encoder, Gfx::ShareableBitmap const& shareable_bitmap)
{
TRY(encoder.encode(shareable_bitmap.is_valid()));
if (!shareable_bitmap.is_valid())
return {};
auto& bitmap = *shareable_bitmap.bitmap();
TRY(encoder.encode(IPC::File(bitmap.anonymous_buffer().fd())));
TRY(encoder.encode(bitmap.size()));
TRY(encoder.encode(static_cast<u32>(bitmap.scale())));
TRY(encoder.encode(static_cast<u32>(bitmap.format())));
if (bitmap.is_indexed()) {
auto palette = bitmap.palette_to_vector();
TRY(encoder.encode(palette));
}
return {};
}
template<>
ErrorOr<Gfx::ShareableBitmap> decode(Decoder& decoder)
{
if (auto valid = TRY(decoder.decode<bool>()); !valid)
return Gfx::ShareableBitmap {};
auto anon_file = TRY(decoder.decode<IPC::File>());
auto size = TRY(decoder.decode<Gfx::IntSize>());
auto scale = TRY(decoder.decode<u32>());
auto raw_bitmap_format = TRY(decoder.decode<u32>());
if (!Gfx::is_valid_bitmap_format(raw_bitmap_format))
return Error::from_string_literal("IPC: Invalid Gfx::ShareableBitmap 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 bitmap = TRY(Gfx::Bitmap::try_create_with_anonymous_buffer(bitmap_format, move(buffer), size, scale, palette));
return Gfx::ShareableBitmap { move(bitmap), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap };
}
}