/* * Copyright (c) 2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include namespace Gfx { ShareableBitmap::ShareableBitmap(NonnullRefPtr bitmap, Tag) : m_bitmap(move(bitmap)) { } } namespace IPC { template<> ErrorOr 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(bitmap.scale()))); TRY(encoder.encode(static_cast(bitmap.format()))); if (bitmap.is_indexed()) { auto palette = bitmap.palette_to_vector(); TRY(encoder.encode(palette)); } return {}; } template<> ErrorOr decode(Decoder& decoder) { if (auto valid = TRY(decoder.decode()); !valid) return Gfx::ShareableBitmap {}; auto anon_file = TRY(decoder.decode()); auto size = TRY(decoder.decode()); auto scale = TRY(decoder.decode()); auto raw_bitmap_format = TRY(decoder.decode()); if (!Gfx::is_valid_bitmap_format(raw_bitmap_format)) return Error::from_string_literal("IPC: Invalid Gfx::ShareableBitmap format"); auto bitmap_format = static_cast(raw_bitmap_format); Vector palette; if (Gfx::Bitmap::is_indexed(bitmap_format)) palette = TRY(decoder.decode()); 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)); return Gfx::ShareableBitmap { move(bitmap), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap }; } }