From 3c4b8749f066a14c93227a82033648b3c4ab3682 Mon Sep 17 00:00:00 2001 From: Lucas CHOLLET Date: Sat, 18 May 2024 19:36:33 -0400 Subject: [PATCH] LibGfx/GIF: Write a Graphic Control Extension block This allows us to write the duration of each frame. --- .../LibGfx/ImageFormats/GIFWriter.cpp | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibGfx/ImageFormats/GIFWriter.cpp b/Userland/Libraries/LibGfx/ImageFormats/GIFWriter.cpp index 20cca6e49c5..71c5d2d91c2 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/GIFWriter.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/GIFWriter.cpp @@ -17,7 +17,7 @@ namespace { ErrorOr write_header(Stream& stream) { // 17. Header - TRY(stream.write_until_depleted("GIF87a"sv)); + TRY(stream.write_until_depleted("GIF89a"sv)); return {}; } @@ -121,6 +121,40 @@ ErrorOr write_image_descriptor(BigEndianOutputBitStream& stream, Bitmap co return {}; } +ErrorOr write_graphic_control_extension(BigEndianOutputBitStream& stream, int duration_ms) +{ + // 23. Graphic Control Extension + + // Extension Introducer + TRY(stream.write_value(0x21)); + // Graphic Control Label + TRY(stream.write_value(0xF9)); + + // Block Size + TRY(stream.write_value(4)); + + // Packed Field + // Reserved + TRY(stream.write_bits(0u, 3)); + // Disposal Method + TRY(stream.write_bits(0u, 3)); + // User Input Flag + TRY(stream.write_bits(false, 1)); + // Transparency Flag + TRY(stream.write_bits(false, 1)); + + // Delay Time + TRY(stream.write_value(duration_ms / 10)); + + // Transparent Color Index + TRY(stream.write_value(0)); + + // Block Terminator + TRY(stream.write_value(0)); + + return {}; +} + ErrorOr write_trailer(Stream& stream) { TRY(stream.write_value(0x3B)); @@ -143,8 +177,7 @@ private: ErrorOr GIFAnimationWriter::add_frame(Bitmap& bitmap, int duration_ms, IntPoint at = {}) { - // FIXME: Consider frame's duration and position - (void)duration_ms; + // FIXME: Consider frame's position (void)at; // Let's get rid of the previously written trailer @@ -155,6 +188,7 @@ ErrorOr GIFAnimationWriter::add_frame(Bitmap& bitmap, int duration_ms, Int // Write a Table-Based Image BigEndianOutputBitStream bit_stream { MaybeOwned { m_stream } }; + TRY(write_graphic_control_extension(bit_stream, duration_ms)); TRY(write_image_descriptor(bit_stream, bitmap)); auto const palette = TRY(median_cut(bitmap, 256));