mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:48:14 +00:00
LibGfx: Add first_animated_frame_index method to ImageDecoder
Some image formats such as APNG may not use the first frame for animations.
This commit is contained in:
parent
5a4c61838f
commit
e7921cfe14
20 changed files with 64 additions and 4 deletions
|
@ -52,18 +52,20 @@ void ImageWidget::set_auto_resize(bool value)
|
|||
// Same as ImageViewer::ViewWidget::animate(), you probably want to keep any changes in sync
|
||||
void ImageWidget::animate()
|
||||
{
|
||||
m_current_frame_index = (m_current_frame_index + 1) % m_image_decoder->frame_count();
|
||||
auto first_animated_frame_index = m_image_decoder->first_animated_frame_index();
|
||||
auto total_animated_frames = m_image_decoder->frame_count() - first_animated_frame_index;
|
||||
m_current_frame_index = (m_current_frame_index + 1) % total_animated_frames;
|
||||
|
||||
auto current_frame = m_image_decoder->frame(m_current_frame_index).release_value_but_fixme_should_propagate_errors();
|
||||
auto current_frame = m_image_decoder->frame(first_animated_frame_index + m_current_frame_index).release_value_but_fixme_should_propagate_errors();
|
||||
set_bitmap(current_frame.image);
|
||||
|
||||
if (current_frame.duration != m_timer->interval()) {
|
||||
m_timer->restart(current_frame.duration);
|
||||
}
|
||||
|
||||
if (m_current_frame_index == m_image_decoder->frame_count() - 1) {
|
||||
if (m_current_frame_index == total_animated_frames - 1) {
|
||||
++m_loops_completed;
|
||||
if (m_loops_completed > 0 && m_loops_completed == m_image_decoder->loop_count()) {
|
||||
if (m_image_decoder->loop_count() > 0 && m_loops_completed == m_image_decoder->loop_count()) {
|
||||
m_timer->stop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1544,6 +1544,11 @@ size_t BMPImageDecoderPlugin::frame_count()
|
|||
return 1;
|
||||
}
|
||||
|
||||
size_t BMPImageDecoderPlugin::first_animated_frame_index()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorOr<ImageFrameDescriptor> BMPImageDecoderPlugin::frame(size_t index)
|
||||
{
|
||||
if (index > 0)
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
virtual bool is_animated() override;
|
||||
virtual size_t loop_count() override;
|
||||
virtual size_t frame_count() override;
|
||||
virtual size_t first_animated_frame_index() override;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
|
|
@ -685,6 +685,11 @@ size_t DDSImageDecoderPlugin::frame_count()
|
|||
return 1;
|
||||
}
|
||||
|
||||
size_t DDSImageDecoderPlugin::first_animated_frame_index()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorOr<ImageFrameDescriptor> DDSImageDecoderPlugin::frame(size_t index)
|
||||
{
|
||||
if (index > 0)
|
||||
|
|
|
@ -247,6 +247,7 @@ public:
|
|||
virtual bool is_animated() override;
|
||||
virtual size_t loop_count() override;
|
||||
virtual size_t frame_count() override;
|
||||
virtual size_t first_animated_frame_index() override;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
|
|
@ -627,6 +627,11 @@ size_t GIFImageDecoderPlugin::frame_count()
|
|||
return m_context->images.size();
|
||||
}
|
||||
|
||||
size_t GIFImageDecoderPlugin::first_animated_frame_index()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorOr<ImageFrameDescriptor> GIFImageDecoderPlugin::frame(size_t index)
|
||||
{
|
||||
if (m_context->error_state >= GIFLoadingContext::ErrorState::FailedToDecodeAnyFrame) {
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
virtual bool is_animated() override;
|
||||
virtual size_t loop_count() override;
|
||||
virtual size_t frame_count() override;
|
||||
virtual size_t first_animated_frame_index() override;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
|
|
@ -251,6 +251,11 @@ size_t ICOImageDecoderPlugin::frame_count()
|
|||
return 1;
|
||||
}
|
||||
|
||||
size_t ICOImageDecoderPlugin::first_animated_frame_index()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorOr<ImageFrameDescriptor> ICOImageDecoderPlugin::frame(size_t index)
|
||||
{
|
||||
if (index > 0)
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
virtual bool is_animated() override;
|
||||
virtual size_t loop_count() override;
|
||||
virtual size_t frame_count() override;
|
||||
virtual size_t first_animated_frame_index() override;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
virtual bool is_animated() = 0;
|
||||
virtual size_t loop_count() = 0;
|
||||
virtual size_t frame_count() = 0;
|
||||
virtual size_t first_animated_frame_index() = 0;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) = 0;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() = 0;
|
||||
|
||||
|
@ -59,6 +60,7 @@ public:
|
|||
bool is_animated() const { return m_plugin->is_animated(); }
|
||||
size_t loop_count() const { return m_plugin->loop_count(); }
|
||||
size_t frame_count() const { return m_plugin->frame_count(); }
|
||||
size_t first_animated_frame_index() const { return m_plugin->first_animated_frame_index(); }
|
||||
ErrorOr<ImageFrameDescriptor> frame(size_t index) const { return m_plugin->frame(index); }
|
||||
ErrorOr<Optional<ReadonlyBytes>> icc_data() const { return m_plugin->icc_data(); }
|
||||
|
||||
|
|
|
@ -1801,6 +1801,11 @@ size_t JPEGImageDecoderPlugin::frame_count()
|
|||
return 1;
|
||||
}
|
||||
|
||||
size_t JPEGImageDecoderPlugin::first_animated_frame_index()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorOr<ImageFrameDescriptor> JPEGImageDecoderPlugin::frame(size_t index)
|
||||
{
|
||||
if (index > 0)
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
virtual bool is_animated() override;
|
||||
virtual size_t loop_count() override;
|
||||
virtual size_t frame_count() override;
|
||||
virtual size_t first_animated_frame_index() override;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
|
|
@ -1062,6 +1062,11 @@ size_t PNGImageDecoderPlugin::frame_count()
|
|||
return 1;
|
||||
}
|
||||
|
||||
size_t PNGImageDecoderPlugin::first_animated_frame_index()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorOr<ImageFrameDescriptor> PNGImageDecoderPlugin::frame(size_t index)
|
||||
{
|
||||
if (index > 0)
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
virtual bool is_animated() override;
|
||||
virtual size_t loop_count() override;
|
||||
virtual size_t frame_count() override;
|
||||
virtual size_t first_animated_frame_index() override;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
virtual bool is_animated() override;
|
||||
virtual size_t loop_count() override;
|
||||
virtual size_t frame_count() override;
|
||||
virtual size_t first_animated_frame_index() override;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
@ -160,6 +161,12 @@ size_t PortableImageDecoderPlugin<TContext>::frame_count()
|
|||
return 1;
|
||||
}
|
||||
|
||||
template<typename TContext>
|
||||
size_t PortableImageDecoderPlugin<TContext>::first_animated_frame_index()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename TContext>
|
||||
ErrorOr<ImageFrameDescriptor> PortableImageDecoderPlugin<TContext>::frame(size_t index)
|
||||
{
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
virtual bool is_animated() override { return false; }
|
||||
virtual size_t loop_count() override { return 0; }
|
||||
virtual size_t frame_count() override { return 1; }
|
||||
virtual size_t first_animated_frame_index() override { return 0; }
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
|
|
@ -257,6 +257,11 @@ size_t TGAImageDecoderPlugin::frame_count()
|
|||
return 1;
|
||||
}
|
||||
|
||||
size_t TGAImageDecoderPlugin::first_animated_frame_index()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorOr<ImageFrameDescriptor> TGAImageDecoderPlugin::frame(size_t index)
|
||||
{
|
||||
auto bits_per_pixel = m_context->header.bits_per_pixel;
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
virtual bool is_animated() override;
|
||||
virtual size_t loop_count() override;
|
||||
virtual size_t frame_count() override;
|
||||
virtual size_t first_animated_frame_index() override;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
|
|
@ -1555,6 +1555,11 @@ size_t WebPImageDecoderPlugin::frame_count()
|
|||
return m_context->animation_frame_chunks.size();
|
||||
}
|
||||
|
||||
size_t WebPImageDecoderPlugin::first_animated_frame_index()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorOr<ImageFrameDescriptor> WebPImageDecoderPlugin::frame(size_t index)
|
||||
{
|
||||
if (index >= frame_count())
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
virtual bool is_animated() override;
|
||||
virtual size_t loop_count() override;
|
||||
virtual size_t frame_count() override;
|
||||
virtual size_t first_animated_frame_index() override;
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index) override;
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue