summaryrefslogtreecommitdiff
path: root/Userland/Services
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2023-01-15 21:50:32 +0200
committerJelle Raaijmakers <jelle@gmta.nl>2023-01-18 21:48:35 +0100
commit649f78d0a4475a640ad353e1e879a7bb27db222b (patch)
tree5ef6f843a86a8c9aad5d76d180dc8c5d87ee2065 /Userland/Services
parent9f2d4d3fd590177c3b6615c18ae5ec7febdb1522 (diff)
downloadserenity-649f78d0a4475a640ad353e1e879a7bb27db222b.zip
LibGfx+Ladybird+Userland: Don't sniff for TGA images with only raw bytes
Because TGA images don't have magic bytes as a signature to be detected, instead assume a sequence of ReadonlyBytes is a possible TGA image only if we are given a path so we could check the extension of the file and see if it's a TGA image. When we know the path of the file being loaded, we will try to first check its extension, and only if there's no match to a known decoder, based on simple extension lookup, then we would probe for other formats as usual with the normal sniffing method.
Diffstat (limited to 'Userland/Services')
-rw-r--r--Userland/Services/ImageDecoder/ConnectionFromClient.cpp70
-rw-r--r--Userland/Services/ImageDecoder/ConnectionFromClient.h1
-rw-r--r--Userland/Services/ImageDecoder/ImageDecoderServer.ipc1
3 files changed, 54 insertions, 18 deletions
diff --git a/Userland/Services/ImageDecoder/ConnectionFromClient.cpp b/Userland/Services/ImageDecoder/ConnectionFromClient.cpp
index e95f9ae066..9f0bee865b 100644
--- a/Userland/Services/ImageDecoder/ConnectionFromClient.cpp
+++ b/Userland/Services/ImageDecoder/ConnectionFromClient.cpp
@@ -22,40 +22,74 @@ void ConnectionFromClient::die()
Core::EventLoop::current().quit(0);
}
-Messages::ImageDecoderServer::DecodeImageResponse ConnectionFromClient::decode_image(Core::AnonymousBuffer const& encoded_buffer)
+static void decode_image_to_bitmaps_and_durations_with_decoder(Gfx::ImageDecoder const& decoder, Vector<Gfx::ShareableBitmap>& bitmaps, Vector<u32>& durations)
{
- if (!encoded_buffer.is_valid()) {
- dbgln_if(IMAGE_DECODER_DEBUG, "Encoded data is invalid");
- return nullptr;
+ for (size_t i = 0; i < decoder.frame_count(); ++i) {
+ auto frame_or_error = decoder.frame(i);
+ 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);
+ }
}
+}
+
+static void decode_image_to_details(Core::AnonymousBuffer const& encoded_buffer, Optional<StringView> known_path, bool& is_animated, u32& loop_count, Vector<Gfx::ShareableBitmap>& bitmaps, Vector<u32>& durations)
+{
+ VERIFY(bitmaps.size() == 0);
+ VERIFY(durations.size() == 0);
+ VERIFY(!is_animated);
+ VERIFY(loop_count == 0);
- auto decoder = Gfx::ImageDecoder::try_create(ReadonlyBytes { encoded_buffer.data<u8>(), encoded_buffer.size() });
+ RefPtr<Gfx::ImageDecoder> decoder;
+ if (known_path.has_value())
+ decoder = Gfx::ImageDecoder::try_create_for_raw_bytes_with_known_path(known_path.value(), ReadonlyBytes { encoded_buffer.data<u8>(), encoded_buffer.size() });
+ else
+ decoder = Gfx::ImageDecoder::try_create_for_raw_bytes(ReadonlyBytes { encoded_buffer.data<u8>(), encoded_buffer.size() });
if (!decoder) {
dbgln_if(IMAGE_DECODER_DEBUG, "Could not find suitable image decoder plugin for data");
- return { false, 0, Vector<Gfx::ShareableBitmap> {}, Vector<u32> {} };
+ return;
}
if (!decoder->frame_count()) {
dbgln_if(IMAGE_DECODER_DEBUG, "Could not decode image from encoded data");
- return { false, 0, Vector<Gfx::ShareableBitmap> {}, Vector<u32> {} };
+ return;
}
+ decode_image_to_bitmaps_and_durations_with_decoder(*decoder, bitmaps, durations);
+}
+Messages::ImageDecoderServer::DecodeImageWithKnownPathResponse ConnectionFromClient::decode_image_with_known_path(DeprecatedString const& path, Core::AnonymousBuffer const& encoded_buffer)
+{
+ if (!encoded_buffer.is_valid()) {
+ dbgln_if(IMAGE_DECODER_DEBUG, "Encoded data is invalid");
+ return nullptr;
+ }
+
+ bool is_animated = false;
+ u32 loop_count = 0;
Vector<Gfx::ShareableBitmap> bitmaps;
Vector<u32> durations;
- for (size_t i = 0; i < decoder->frame_count(); ++i) {
- auto frame_or_error = decoder->frame(i);
- 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);
- }
+ decode_image_to_details(encoded_buffer, path.substring_view(0), is_animated, loop_count, bitmaps, durations);
+ return { is_animated, loop_count, bitmaps, durations };
+}
+
+Messages::ImageDecoderServer::DecodeImageResponse ConnectionFromClient::decode_image(Core::AnonymousBuffer const& encoded_buffer)
+{
+ if (!encoded_buffer.is_valid()) {
+ dbgln_if(IMAGE_DECODER_DEBUG, "Encoded data is invalid");
+ return nullptr;
}
- return { decoder->is_animated(), static_cast<u32>(decoder->loop_count()), bitmaps, durations };
+ bool is_animated = false;
+ u32 loop_count = 0;
+ Vector<Gfx::ShareableBitmap> bitmaps;
+ Vector<u32> durations;
+ decode_image_to_details(encoded_buffer, {}, is_animated, loop_count, bitmaps, durations);
+ return { is_animated, loop_count, bitmaps, durations };
}
}
diff --git a/Userland/Services/ImageDecoder/ConnectionFromClient.h b/Userland/Services/ImageDecoder/ConnectionFromClient.h
index 6b8a5e8086..f137af3dfe 100644
--- a/Userland/Services/ImageDecoder/ConnectionFromClient.h
+++ b/Userland/Services/ImageDecoder/ConnectionFromClient.h
@@ -27,6 +27,7 @@ private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
virtual Messages::ImageDecoderServer::DecodeImageResponse decode_image(Core::AnonymousBuffer const&) override;
+ virtual Messages::ImageDecoderServer::DecodeImageWithKnownPathResponse decode_image_with_known_path(DeprecatedString const& path, Core::AnonymousBuffer const&) override;
};
}
diff --git a/Userland/Services/ImageDecoder/ImageDecoderServer.ipc b/Userland/Services/ImageDecoder/ImageDecoderServer.ipc
index 5ca2e40ea0..9492f685a0 100644
--- a/Userland/Services/ImageDecoder/ImageDecoderServer.ipc
+++ b/Userland/Services/ImageDecoder/ImageDecoderServer.ipc
@@ -4,4 +4,5 @@
endpoint ImageDecoderServer
{
decode_image(Core::AnonymousBuffer data) => (bool is_animated, u32 loop_count, Vector<Gfx::ShareableBitmap> bitmaps, Vector<u32> durations)
+ decode_image_with_known_path(DeprecatedString path, Core::AnonymousBuffer data) => (bool is_animated, u32 loop_count, Vector<Gfx::ShareableBitmap> bitmaps, Vector<u32> durations)
}