1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:37:35 +00:00

LibGfx/PortableFormat+image: Make encode take a Stream

As we directly write to the stream, we don't need to store a copy of the
entire image in memory. However, writing to a stream is heavier on the
CPU than to a ByteBuffer. This commit unfortunately makes `add_pixels`
two times slower.
This commit is contained in:
Lucas CHOLLET 2023-04-30 21:13:50 -04:00 committed by Andreas Kling
parent af6dc267d3
commit d4d3c3f262
3 changed files with 29 additions and 28 deletions

View file

@ -5,47 +5,45 @@
*/
#include "PortableFormatWriter.h"
#include <AK/String.h>
#include <AK/Stream.h>
namespace Gfx {
ErrorOr<ByteBuffer> PortableFormatWriter::encode(Bitmap const& bitmap, Options options)
ErrorOr<void> PortableFormatWriter::encode(Stream& output, 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()));
TRY(add_header(output, options, bitmap.width(), bitmap.height(), 255));
TRY(add_pixels(output, options, bitmap));
return {};
}
ErrorOr<void> PortableFormatWriter::add_pixels(ByteBuffer& buffer, Options const& options, Bitmap const& bitmap)
ErrorOr<void> PortableFormatWriter::add_header(Stream& output, Options const& options, u32 width, u32 height, u32 maximal_value)
{
TRY(output.write_formatted("P{}\n", options.format == Options::Format::ASCII ? "3"sv : "6"sv));
TRY(output.write_formatted("# {}\n", options.comment));
TRY(output.write_formatted("{} {}\n", width, height));
TRY(output.write_formatted("{}\n", maximal_value));
return {};
}
ErrorOr<void> PortableFormatWriter::add_pixels(Stream& output, 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()));
TRY(output.write_formatted("{} {} {}\t", color.red(), color.green(), color.blue()));
} else {
TRY(buffer.try_append(color.red()));
TRY(buffer.try_append(color.green()));
TRY(buffer.try_append(color.blue()));
TRY(output.write_value(color.red()));
TRY(output.write_value(color.green()));
TRY(output.write_value(color.blue()));
}
}
if (options.format == Options::Format::ASCII)
TRY(buffer.try_append('\n'));
TRY(output.write_value('\n'));
}
return {};