diff --git a/Meta/gn/secondary/Userland/Libraries/LibGfx/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibGfx/BUILD.gn index 9bf9cc4d861..fe8934d002f 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibGfx/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibGfx/BUILD.gn @@ -96,6 +96,7 @@ shared_library("LibGfx") { "ImageFormats/WebPLoader.cpp", "ImageFormats/WebPLoaderLossless.cpp", "ImageFormats/WebPLoaderLossy.cpp", + "ImageFormats/WebPWriter.cpp", "ImmutableBitmap.cpp", "Painter.cpp", "Palette.cpp", diff --git a/Userland/Libraries/LibGfx/CMakeLists.txt b/Userland/Libraries/LibGfx/CMakeLists.txt index 52fe5b40aa0..517954ea5fe 100644 --- a/Userland/Libraries/LibGfx/CMakeLists.txt +++ b/Userland/Libraries/LibGfx/CMakeLists.txt @@ -69,6 +69,7 @@ set(SOURCES ImageFormats/WebPLoader.cpp ImageFormats/WebPLoaderLossless.cpp ImageFormats/WebPLoaderLossy.cpp + ImageFormats/WebPWriter.cpp ImmutableBitmap.cpp Painter.cpp Palette.cpp diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.cpp new file mode 100644 index 00000000000..9f41016ccae --- /dev/null +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024, Nico Weber + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Gfx { + +ErrorOr WebPWriter::encode(Stream&, Bitmap const&, Options const&) +{ + return Error::from_string_literal("WebP encoding not yet implemented"); +} + +} diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.h b/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.h new file mode 100644 index 00000000000..81d166d1d8c --- /dev/null +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPWriter.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024, Nico Weber + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Gfx { + +struct WebPEncoderOptions { + Optional icc_data; +}; + +class WebPWriter { +public: + using Options = WebPEncoderOptions; + + // Always lossless at the moment. + static ErrorOr encode(Stream&, Bitmap const&, Options const& = {}); + +private: + WebPWriter() = delete; +}; + +} diff --git a/Userland/Utilities/image.cpp b/Userland/Utilities/image.cpp index 2aa77f740b0..1b2d54bed4b 100644 --- a/Userland/Utilities/image.cpp +++ b/Userland/Utilities/image.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using AnyBitmap = Variant, RefPtr>; struct LoadedImage { @@ -176,6 +177,10 @@ static ErrorOr save_image(LoadedImage& image, StringView out_path, bool pp TRY(Gfx::PortableFormatWriter::encode(*TRY(stream()), *frame, { .format = format })); return {}; } + if (out_path.ends_with(".webp"sv, CaseSensitivity::CaseInsensitive)) { + TRY(Gfx::WebPWriter::encode(*TRY(stream()), *frame, { .icc_data = image.icc_data })); + return {}; + } ByteBuffer bytes; if (out_path.ends_with(".bmp"sv, CaseSensitivity::CaseInsensitive)) { @@ -185,7 +190,7 @@ static ErrorOr save_image(LoadedImage& image, StringView out_path, bool pp } else if (out_path.ends_with(".qoi"sv, CaseSensitivity::CaseInsensitive)) { bytes = TRY(Gfx::QOIWriter::encode(*frame)); } else { - return Error::from_string_view("can only write .bmp, .jpg, .png, .ppm, and .qoi"sv); + return Error::from_string_view("can only write .bmp, .jpg, .png, .ppm, .qoi, and .webp"sv); } TRY(TRY(stream())->write_until_depleted(bytes));