ShareableBitmap.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibGfx/Bitmap.h>
  7. #include <LibGfx/ShareableBitmap.h>
  8. #include <LibGfx/Size.h>
  9. #include <LibIPC/Decoder.h>
  10. #include <LibIPC/Encoder.h>
  11. #include <LibIPC/File.h>
  12. namespace Gfx {
  13. ShareableBitmap::ShareableBitmap(const Bitmap& bitmap)
  14. : m_bitmap(bitmap.to_bitmap_backed_by_anonymous_buffer())
  15. {
  16. }
  17. ShareableBitmap::ShareableBitmap(NonnullRefPtr<Bitmap> bitmap, Tag)
  18. : m_bitmap(move(bitmap))
  19. {
  20. }
  21. }
  22. namespace IPC {
  23. bool encode(Encoder& encoder, const Gfx::ShareableBitmap& shareable_bitmap)
  24. {
  25. encoder << shareable_bitmap.is_valid();
  26. if (!shareable_bitmap.is_valid())
  27. return true;
  28. auto& bitmap = *shareable_bitmap.bitmap();
  29. encoder << IPC::File(bitmap.anonymous_buffer().fd());
  30. encoder << bitmap.size();
  31. encoder << bitmap.scale();
  32. encoder << (u32)bitmap.format();
  33. if (bitmap.is_indexed()) {
  34. auto palette = bitmap.palette_to_vector();
  35. encoder << palette;
  36. }
  37. return true;
  38. }
  39. bool decode(Decoder& decoder, Gfx::ShareableBitmap& shareable_bitmap)
  40. {
  41. bool valid = false;
  42. if (!decoder.decode(valid))
  43. return false;
  44. if (!valid) {
  45. shareable_bitmap = {};
  46. return true;
  47. }
  48. IPC::File anon_file;
  49. if (!decoder.decode(anon_file))
  50. return false;
  51. Gfx::IntSize size;
  52. if (!decoder.decode(size))
  53. return false;
  54. u32 scale;
  55. if (!decoder.decode(scale))
  56. return false;
  57. u32 raw_bitmap_format;
  58. if (!decoder.decode(raw_bitmap_format))
  59. return false;
  60. if (!Gfx::is_valid_bitmap_format(raw_bitmap_format))
  61. return false;
  62. auto bitmap_format = (Gfx::BitmapFormat)raw_bitmap_format;
  63. Vector<Gfx::RGBA32> palette;
  64. if (Gfx::Bitmap::is_indexed(bitmap_format)) {
  65. if (!decoder.decode(palette))
  66. return false;
  67. }
  68. auto buffer_or_error = Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), Gfx::Bitmap::size_in_bytes(Gfx::Bitmap::minimum_pitch(size.width(), bitmap_format), size.height()));
  69. if (buffer_or_error.is_error())
  70. return false;
  71. auto bitmap_or_error = Gfx::Bitmap::try_create_with_anonymous_buffer(bitmap_format, buffer_or_error.release_value(), size, scale, palette);
  72. if (bitmap_or_error.is_error())
  73. return false;
  74. shareable_bitmap = Gfx::ShareableBitmap { bitmap_or_error.release_value(), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap };
  75. return true;
  76. }
  77. }