Serenity Operating System
at master 75 lines 2.7 kB view raw
1/* 2 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Debug.h> 8#include <ImageDecoder/ConnectionFromClient.h> 9#include <ImageDecoder/ImageDecoderClientEndpoint.h> 10#include <LibGfx/Bitmap.h> 11#include <LibGfx/ImageDecoder.h> 12 13namespace ImageDecoder { 14 15ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket) 16 : IPC::ConnectionFromClient<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, move(socket), 1) 17{ 18} 19 20void ConnectionFromClient::die() 21{ 22 Core::EventLoop::current().quit(0); 23} 24 25static void decode_image_to_bitmaps_and_durations_with_decoder(Gfx::ImageDecoder const& decoder, Vector<Gfx::ShareableBitmap>& bitmaps, Vector<u32>& durations) 26{ 27 for (size_t i = 0; i < decoder.frame_count(); ++i) { 28 auto frame_or_error = decoder.frame(i); 29 if (frame_or_error.is_error()) { 30 bitmaps.append(Gfx::ShareableBitmap {}); 31 durations.append(0); 32 } else { 33 auto frame = frame_or_error.release_value(); 34 bitmaps.append(frame.image->to_shareable_bitmap()); 35 durations.append(frame.duration); 36 } 37 } 38} 39 40static void decode_image_to_details(Core::AnonymousBuffer const& encoded_buffer, Optional<DeprecatedString> const& known_mime_type, bool& is_animated, u32& loop_count, Vector<Gfx::ShareableBitmap>& bitmaps, Vector<u32>& durations) 41{ 42 VERIFY(bitmaps.size() == 0); 43 VERIFY(durations.size() == 0); 44 45 auto decoder = Gfx::ImageDecoder::try_create_for_raw_bytes(ReadonlyBytes { encoded_buffer.data<u8>(), encoded_buffer.size() }, known_mime_type); 46 if (!decoder) { 47 dbgln_if(IMAGE_DECODER_DEBUG, "Could not find suitable image decoder plugin for data"); 48 return; 49 } 50 51 if (!decoder->frame_count()) { 52 dbgln_if(IMAGE_DECODER_DEBUG, "Could not decode image from encoded data"); 53 return; 54 } 55 is_animated = decoder->is_animated(); 56 loop_count = decoder->loop_count(); 57 decode_image_to_bitmaps_and_durations_with_decoder(*decoder, bitmaps, durations); 58} 59 60Messages::ImageDecoderServer::DecodeImageResponse ConnectionFromClient::decode_image(Core::AnonymousBuffer const& encoded_buffer, Optional<DeprecatedString> const& mime_type) 61{ 62 if (!encoded_buffer.is_valid()) { 63 dbgln_if(IMAGE_DECODER_DEBUG, "Encoded data is invalid"); 64 return nullptr; 65 } 66 67 bool is_animated = false; 68 u32 loop_count = 0; 69 Vector<Gfx::ShareableBitmap> bitmaps; 70 Vector<u32> durations; 71 decode_image_to_details(encoded_buffer, mime_type, is_animated, loop_count, bitmaps, durations); 72 return { is_animated, loop_count, bitmaps, durations }; 73} 74 75}