diff options
author | Lucas CHOLLET <lucas.chollet@free.fr> | 2023-03-12 22:18:16 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-03-13 15:15:41 +0000 |
commit | 9c9bd271c8ffe7cfcd8f50389121a1c4ba5a34be (patch) | |
tree | 0e507c7157a78c2882019555fe65e65709ef50b2 /Userland/Libraries | |
parent | e32267c902c779678466294b5d00a87e67c94a05 (diff) | |
download | serenity-9c9bd271c8ffe7cfcd8f50389121a1c4ba5a34be.zip |
LibGfx/PortableFormat: Add `PortableFormatWriter`
Currently, the encoder only output ppm files, but it can easily be
extended to support both PBM and PGM.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibGfx/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/PortableFormatWriter.cpp | 54 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/PortableFormatWriter.h | 38 |
3 files changed, 93 insertions, 0 deletions
diff --git a/Userland/Libraries/LibGfx/CMakeLists.txt b/Userland/Libraries/LibGfx/CMakeLists.txt index 5ffa912f9f..259dd78fc9 100644 --- a/Userland/Libraries/LibGfx/CMakeLists.txt +++ b/Userland/Libraries/LibGfx/CMakeLists.txt @@ -41,6 +41,7 @@ set(SOURCES PGMLoader.cpp PNGLoader.cpp PNGWriter.cpp + PortableFormatWriter.cpp PPMLoader.cpp Painter.cpp Palette.cpp diff --git a/Userland/Libraries/LibGfx/PortableFormatWriter.cpp b/Userland/Libraries/LibGfx/PortableFormatWriter.cpp new file mode 100644 index 0000000000..56bf8b0bd6 --- /dev/null +++ b/Userland/Libraries/LibGfx/PortableFormatWriter.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023, Lucas Chollet <lucas.chollet@serenityos.org > + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "PortableFormatWriter.h" +#include <AK/String.h> + +namespace Gfx { + +ErrorOr<ByteBuffer> PortableFormatWriter::encode(Bitmap const& bitmap, Options options) +{ + ByteBuffer buffer; + + // FIXME: Add support for PBM and PGM + + TRY(add_header(buffer, options, bitmap.width(), bitmap.height(), 255)); + TRY(add_pixels(buffer, options, bitmap)); + + return buffer; +} + +ErrorOr<void> PortableFormatWriter::add_header(ByteBuffer& buffer, Options const& options, u32 width, u32 height, u32 maximal_value) +{ + TRY(buffer.try_append(TRY(String::formatted("P{}\n", options.format == Options::Format::ASCII ? "3"sv : "6"sv)).bytes())); + TRY(buffer.try_append(TRY(String::formatted("# {}\n", options.comment)).bytes())); + TRY(buffer.try_append(TRY(String::formatted("{} {}\n", width, height)).bytes())); + TRY(buffer.try_append(TRY(String::formatted("{}\n", maximal_value)).bytes())); + + return {}; +} + +ErrorOr<void> PortableFormatWriter::add_pixels(ByteBuffer& buffer, Options const& options, Bitmap const& bitmap) +{ + for (int i = 0; i < bitmap.height(); ++i) { + for (int j = 0; j < bitmap.width(); ++j) { + auto color = bitmap.get_pixel(j, i); + if (options.format == Options::Format::ASCII) { + TRY(buffer.try_append(TRY(String::formatted("{} {} {}\t", color.red(), color.green(), color.blue())).bytes())); + } else { + TRY(buffer.try_append(color.red())); + TRY(buffer.try_append(color.green())); + TRY(buffer.try_append(color.blue())); + } + } + if (options.format == Options::Format::ASCII) + TRY(buffer.try_append('\n')); + } + + return {}; +} + +} diff --git a/Userland/Libraries/LibGfx/PortableFormatWriter.h b/Userland/Libraries/LibGfx/PortableFormatWriter.h new file mode 100644 index 0000000000..30da31a703 --- /dev/null +++ b/Userland/Libraries/LibGfx/PortableFormatWriter.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023, Lucas Chollet <lucas.chollet@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/ByteBuffer.h> +#include <LibGfx/Bitmap.h> + +namespace Gfx { + +// This is not a nested struct to work around https://llvm.org/PR36684 +struct PortableFormatWriterOptions { + enum class Format { + ASCII, + Raw, + }; + + Format format = Format::Raw; + StringView comment = "Generated with SerenityOS - LibGfx."sv; +}; + +class PortableFormatWriter { +public: + using Options = PortableFormatWriterOptions; + + static ErrorOr<ByteBuffer> encode(Bitmap const&, Options options = Options {}); + +private: + PortableFormatWriter() = delete; + + static ErrorOr<void> add_header(ByteBuffer&, Options const& options, u32 width, u32 height, u32 max_value); + static ErrorOr<void> add_pixels(ByteBuffer&, Options const& options, Bitmap const&); +}; + +} |