Browse Source

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 :^)
Jelle Raaijmakers 1 year ago
parent
commit
1c19c2bc92

+ 5 - 4
Userland/Applications/PixelPaint/Image.cpp

@@ -50,13 +50,14 @@ void Image::paint_into(GUI::Painter& painter, Gfx::IntRect const& dest_rect, flo
     }
 }
 
-ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Image::decode_bitmap(ReadonlyBytes bitmap_data)
+ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Image::decode_bitmap(ReadonlyBytes bitmap_data, Optional<StringView> 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<NonnullRefPtr<Image>> 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));
         }
 

+ 2 - 1
Userland/Applications/PixelPaint/Image.h

@@ -11,6 +11,7 @@
 #include "Selection.h"
 #include <AK/HashTable.h>
 #include <AK/JsonObjectSerializer.h>
+#include <AK/Optional.h>
 #include <AK/RefCounted.h>
 #include <AK/RefPtr.h>
 #include <AK/Result.h>
@@ -48,7 +49,7 @@ public:
     static ErrorOr<NonnullRefPtr<Image>> create_from_pixel_paint_json(JsonObject const&);
     static ErrorOr<NonnullRefPtr<Image>> create_from_bitmap(NonnullRefPtr<Gfx::Bitmap> const&);
 
-    static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> decode_bitmap(ReadonlyBytes);
+    static ErrorOr<NonnullRefPtr<Gfx::Bitmap>> decode_bitmap(ReadonlyBytes, Optional<StringView> guessed_mime_type);
 
     // This generates a new Bitmap with the final image (all layers composed according to their attributes.)
     ErrorOr<NonnullRefPtr<Gfx::Bitmap>> compose_bitmap(Gfx::BitmapFormat format) const;

+ 1 - 1
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;

+ 4 - 2
Userland/Applications/PixelPaint/ProjectLoader.cpp

@@ -8,20 +8,22 @@
 #include "Image.h"
 #include "Layer.h"
 #include <AK/JsonObject.h>
+#include <LibCore/MimeData.h>
 #include <LibImageDecoderClient/Client.h>
 
 namespace PixelPaint {
 
-ErrorOr<void> ProjectLoader::load_from_file(NonnullOwnPtr<Core::File> file)
+ErrorOr<void> ProjectLoader::load_from_file(StringView filename, NonnullOwnPtr<Core::File> 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;

+ 1 - 1
Userland/Applications/PixelPaint/ProjectLoader.h

@@ -18,7 +18,7 @@ public:
     ProjectLoader() = default;
     ~ProjectLoader() = default;
 
-    ErrorOr<void> load_from_file(NonnullOwnPtr<Core::File>);
+    ErrorOr<void> load_from_file(StringView filename, NonnullOwnPtr<Core::File>);
 
     bool is_raw_image() const { return m_is_raw_image; }
     RefPtr<Image> release_image() const { return move(m_image); }