From 1c19c2bc925501b026884949532077df95e1b282 Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Tue, 8 Aug 2023 20:22:54 +0200 Subject: [PATCH] PixelPaint: Guess image type based on its filename We do this in ImageViewer so it understands TGA images; let's do it in PixelPaint as well :^) --- Userland/Applications/PixelPaint/Image.cpp | 9 +++++---- Userland/Applications/PixelPaint/Image.h | 3 ++- Userland/Applications/PixelPaint/MainWidget.cpp | 2 +- Userland/Applications/PixelPaint/ProjectLoader.cpp | 6 ++++-- Userland/Applications/PixelPaint/ProjectLoader.h | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Userland/Applications/PixelPaint/Image.cpp b/Userland/Applications/PixelPaint/Image.cpp index 09dd480d8d2..592fd18b597 100644 --- a/Userland/Applications/PixelPaint/Image.cpp +++ b/Userland/Applications/PixelPaint/Image.cpp @@ -50,13 +50,14 @@ void Image::paint_into(GUI::Painter& painter, Gfx::IntRect const& dest_rect, flo } } -ErrorOr> Image::decode_bitmap(ReadonlyBytes bitmap_data) +ErrorOr> Image::decode_bitmap(ReadonlyBytes bitmap_data, Optional guessed_mime_type) { // Spawn a new ImageDecoder service process and connect to it. auto client = TRY(ImageDecoderClient::Client::try_create()); + auto optional_mime_type = guessed_mime_type.map([](auto mime_type) { return mime_type.to_deprecated_string(); }); // FIXME: Find a way to avoid the memory copying here. - auto maybe_decoded_image = client->decode_image(bitmap_data); + auto maybe_decoded_image = client->decode_image(bitmap_data, optional_mime_type); if (!maybe_decoded_image.has_value()) return Error::from_string_literal("Image decode failed"); @@ -91,13 +92,13 @@ ErrorOr> Image::create_from_pixel_paint_json(JsonObject con auto bitmap_base64_encoded = layer_object.get_deprecated_string("bitmap"sv).value(); auto bitmap_data = TRY(decode_base64(bitmap_base64_encoded)); - auto bitmap = TRY(decode_bitmap(bitmap_data)); + auto bitmap = TRY(decode_bitmap(bitmap_data, {})); auto layer = TRY(Layer::create_with_bitmap(*image, move(bitmap), name)); if (auto const& mask_object = layer_object.get_deprecated_string("mask"sv); mask_object.has_value()) { auto mask_base64_encoded = mask_object.value(); auto mask_data = TRY(decode_base64(mask_base64_encoded)); - auto mask = TRY(decode_bitmap(mask_data)); + auto mask = TRY(decode_bitmap(mask_data, {})); TRY(layer->set_bitmaps(layer->content_bitmap(), mask)); } diff --git a/Userland/Applications/PixelPaint/Image.h b/Userland/Applications/PixelPaint/Image.h index 5a6ea27e7f0..001f597ac4e 100644 --- a/Userland/Applications/PixelPaint/Image.h +++ b/Userland/Applications/PixelPaint/Image.h @@ -11,6 +11,7 @@ #include "Selection.h" #include #include +#include #include #include #include @@ -48,7 +49,7 @@ public: static ErrorOr> create_from_pixel_paint_json(JsonObject const&); static ErrorOr> create_from_bitmap(NonnullRefPtr const&); - static ErrorOr> decode_bitmap(ReadonlyBytes); + static ErrorOr> decode_bitmap(ReadonlyBytes, Optional guessed_mime_type); // This generates a new Bitmap with the final image (all layers composed according to their attributes.) ErrorOr> compose_bitmap(Gfx::BitmapFormat format) const; diff --git a/Userland/Applications/PixelPaint/MainWidget.cpp b/Userland/Applications/PixelPaint/MainWidget.cpp index 35720dccaf6..4f8a2e37fb5 100644 --- a/Userland/Applications/PixelPaint/MainWidget.cpp +++ b/Userland/Applications/PixelPaint/MainWidget.cpp @@ -1288,7 +1288,7 @@ void MainWidget::set_mask_actions_for_layer(Layer* layer) void MainWidget::open_image(FileSystemAccessClient::File file) { - auto try_load = m_loader.load_from_file(file.release_stream()); + auto try_load = m_loader.load_from_file(file.filename(), file.release_stream()); if (try_load.is_error()) { GUI::MessageBox::show_error(window(), MUST(String::formatted("Unable to open file: {}, {}", file.filename(), try_load.release_error()))); return; diff --git a/Userland/Applications/PixelPaint/ProjectLoader.cpp b/Userland/Applications/PixelPaint/ProjectLoader.cpp index aae291ebfff..8ef36cfa770 100644 --- a/Userland/Applications/PixelPaint/ProjectLoader.cpp +++ b/Userland/Applications/PixelPaint/ProjectLoader.cpp @@ -8,20 +8,22 @@ #include "Image.h" #include "Layer.h" #include +#include #include namespace PixelPaint { -ErrorOr ProjectLoader::load_from_file(NonnullOwnPtr file) +ErrorOr ProjectLoader::load_from_file(StringView filename, NonnullOwnPtr file) { auto contents = TRY(file->read_until_eof()); auto json_or_error = JsonValue::from_string(contents); if (json_or_error.is_error()) { m_is_raw_image = true; + auto guessed_mime_type = Core::guess_mime_type_based_on_filename(filename); // FIXME: Find a way to avoid the memory copy here. - auto bitmap = TRY(Image::decode_bitmap(contents)); + auto bitmap = TRY(Image::decode_bitmap(contents, guessed_mime_type)); auto image = TRY(Image::create_from_bitmap(move(bitmap))); m_image = image; diff --git a/Userland/Applications/PixelPaint/ProjectLoader.h b/Userland/Applications/PixelPaint/ProjectLoader.h index 98b5fdf6d5a..3963ee1c38c 100644 --- a/Userland/Applications/PixelPaint/ProjectLoader.h +++ b/Userland/Applications/PixelPaint/ProjectLoader.h @@ -18,7 +18,7 @@ public: ProjectLoader() = default; ~ProjectLoader() = default; - ErrorOr load_from_file(NonnullOwnPtr); + ErrorOr load_from_file(StringView filename, NonnullOwnPtr); bool is_raw_image() const { return m_is_raw_image; } RefPtr release_image() const { return move(m_image); }