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 :^)
This commit is contained in:
Jelle Raaijmakers 2023-08-08 20:22:54 +02:00 committed by Daniel Bertalan
parent e272f796ad
commit 1c19c2bc92
Notes: sideshowbarker 2024-07-16 21:39:23 +09:00
5 changed files with 13 additions and 9 deletions

View file

@ -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));
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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); }