Newer
Older
minerva / Userland / Libraries / LibGfx / ImageFormats / AnimationWriter.h
@minerva minerva on 13 Jul 1 KB Initial commit
/*
 * Copyright (c) 2024, Nico Weber <thakis@chromium.org>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/Error.h>
#include <LibGfx/Forward.h>
#include <LibGfx/Point.h>

namespace Gfx {

class AnimationWriter {
public:
    virtual ~AnimationWriter();

    enum class BlendMode {
        // The new frame replaces the data below it.
        Replace,

        // The new frame is blended on top of the data below it.
        // Use only when the new frame has completely opaque and completely transparent pixels.
        // The opaque pixels will replace the pixels below them, the transparent pixels will leave pixels below them unchanged.
        // Use only with AnimationWriter subclasses that return true from can_blend_frames().
        Blend,
    };

    // Flushes the frame to disk.
    // IntRect { at, at + bitmap.size() } must fit in the dimensions
    // passed to `start_writing_animation()`.
    virtual ErrorOr<void> add_frame(Bitmap&, int duration_ms, IntPoint at = {}, BlendMode disposal_method = BlendMode::Replace) = 0;

    // If this is set to Yes and can_blend_frames() returns true, add_frame_relative_to_last_frame() may
    // call add_frame() with BlendMode::Blend and a frame that has transparent pixels.
    enum class AllowInterFrameCompression {
        No,
        Yes,
    };
    ErrorOr<void> add_frame_relative_to_last_frame(Bitmap&, int duration_ms, RefPtr<Bitmap> last_frame, AllowInterFrameCompression = AllowInterFrameCompression::Yes);

    virtual bool can_blend_frames() const { return false; }

private:
    bool can_zero_out_unchanging_pixels(Bitmap& new_frame, Gfx::IntRect new_frame_rect, Bitmap& last_frame, AllowInterFrameCompression) const;
};

}