| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-21 20:08:03 +02:00
										 |  |  | #include <AK/Debug.h>
 | 
					
						
							| 
									
										
										
										
											2022-02-25 12:18:30 +02:00
										 |  |  | #include <ImageDecoder/ConnectionFromClient.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | #include <ImageDecoder/ImageDecoderClientEndpoint.h>
 | 
					
						
							|  |  |  | #include <LibGfx/Bitmap.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-21 14:58:06 -04:00
										 |  |  | #include <LibGfx/ImageFormats/ImageDecoder.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace ImageDecoder { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 23:05:44 +01:00
										 |  |  | ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket) | 
					
						
							| 
									
										
										
										
											2022-02-25 12:18:30 +02:00
										 |  |  |     : IPC::ConnectionFromClient<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, move(socket), 1) | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 12:18:30 +02:00
										 |  |  | void ConnectionFromClient::die() | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-11-29 17:12:55 +01:00
										 |  |  |     Core::EventLoop::current().quit(0); | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-23 13:56:23 -05:00
										 |  |  | static void decode_image_to_bitmaps_and_durations_with_decoder(Gfx::ImageDecoder const& decoder, Optional<Gfx::IntSize> ideal_size, Vector<Gfx::ShareableBitmap>& bitmaps, Vector<u32>& durations) | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  |     for (size_t i = 0; i < decoder.frame_count(); ++i) { | 
					
						
							| 
									
										
										
										
											2023-12-23 13:56:23 -05:00
										 |  |  |         auto frame_or_error = decoder.frame(i, ideal_size); | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  |         if (frame_or_error.is_error()) { | 
					
						
							|  |  |  |             bitmaps.append(Gfx::ShareableBitmap {}); | 
					
						
							|  |  |  |             durations.append(0); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             auto frame = frame_or_error.release_value(); | 
					
						
							|  |  |  |             bitmaps.append(frame.image->to_shareable_bitmap()); | 
					
						
							|  |  |  |             durations.append(frame.duration); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-23 13:56:23 -05:00
										 |  |  | static void decode_image_to_details(Core::AnonymousBuffer const& encoded_buffer, Optional<Gfx::IntSize> ideal_size, Optional<ByteString> const& known_mime_type, bool& is_animated, u32& loop_count, Vector<Gfx::ShareableBitmap>& bitmaps, Vector<u32>& durations) | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     VERIFY(bitmaps.size() == 0); | 
					
						
							|  |  |  |     VERIFY(durations.size() == 0); | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-20 03:27:10 +02:00
										 |  |  |     auto decoder = Gfx::ImageDecoder::try_create_for_raw_bytes(ReadonlyBytes { encoded_buffer.data<u8>(), encoded_buffer.size() }, known_mime_type); | 
					
						
							| 
									
										
										
										
											2021-07-27 01:12:53 +02:00
										 |  |  |     if (!decoder) { | 
					
						
							|  |  |  |         dbgln_if(IMAGE_DECODER_DEBUG, "Could not find suitable image decoder plugin for data"); | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-07-27 01:12:53 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 22:30:48 +01:00
										 |  |  |     if (!decoder->frame_count()) { | 
					
						
							| 
									
										
										
										
											2021-04-21 20:08:03 +02:00
										 |  |  |         dbgln_if(IMAGE_DECODER_DEBUG, "Could not decode image from encoded data"); | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-22 11:58:36 +01:00
										 |  |  |     is_animated = decoder->is_animated(); | 
					
						
							|  |  |  |     loop_count = decoder->loop_count(); | 
					
						
							| 
									
										
										
										
											2023-12-23 13:56:23 -05:00
										 |  |  |     decode_image_to_bitmaps_and_durations_with_decoder(*decoder, ideal_size, bitmaps, durations); | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-23 13:56:23 -05:00
										 |  |  | Messages::ImageDecoderServer::DecodeImageResponse ConnectionFromClient::decode_image(Core::AnonymousBuffer const& encoded_buffer, Optional<Gfx::IntSize> const& ideal_size, Optional<ByteString> const& mime_type) | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!encoded_buffer.is_valid()) { | 
					
						
							|  |  |  |         dbgln_if(IMAGE_DECODER_DEBUG, "Encoded data is invalid"); | 
					
						
							|  |  |  |         return nullptr; | 
					
						
							| 
									
										
										
										
											2021-01-29 22:30:48 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  |     bool is_animated = false; | 
					
						
							|  |  |  |     u32 loop_count = 0; | 
					
						
							|  |  |  |     Vector<Gfx::ShareableBitmap> bitmaps; | 
					
						
							|  |  |  |     Vector<u32> durations; | 
					
						
							| 
									
										
										
										
											2023-12-23 13:56:23 -05:00
										 |  |  |     decode_image_to_details(encoded_buffer, ideal_size, mime_type, is_animated, loop_count, bitmaps, durations); | 
					
						
							| 
									
										
										
										
											2023-01-15 21:50:32 +02:00
										 |  |  |     return { is_animated, loop_count, bitmaps, durations }; | 
					
						
							| 
									
										
										
										
											2020-06-22 21:35:22 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |