Skip to content

Fix APNG push/sequential frame-count divergence (#891) - #893

Open
0xMrNiko wants to merge 1 commit into
pnggroup:libpng18from
0xMrNiko:fix-891-apng-push-sequential-consistency
Open

Fix APNG push/sequential frame-count divergence (#891)#893
0xMrNiko wants to merge 1 commit into
pnggroup:libpng18from
0xMrNiko:fix-891-apng-push-sequential-consistency

Conversation

@0xMrNiko

Copy link
Copy Markdown

Fixes #891

Problem

When an APNG has a leading fcTL whose width/height does not match IHDR, libpng warns and ignores it (PNG_FIRST_FRAME_HIDDEN). The two read APIs then disagree on completed frame count for the same bytes:

  • Sequential (png_read_frame_head): 0 frames completed
  • Progressive (png_process_data): 1 frame completed (incorrect frame_end callback)

Root cause

In png_push_read_IDAT(), after the default IDAT finishes (num_frames_read == 0), the progressive reader always calls frame_end_fn. The sequential reader does not treat the hidden default image as a completed animation frame.

Fix

Skip frame_end_fn when PNG_FIRST_FRAME_HIDDEN is set at the num_frames_read == 0 completion path. num_frames_read is still incremented to match sequential behavior.

Verification

POC compares frame_end callback counts between sequential and progressive readers on a malformed APNG (leading fcTL 8×1 vs IHDR 8×8):

Before:
sequential_frames_completed=0 progressive_frames_completed=1 BUG_PRESENT=yes

After:
sequential_frames_completed=0 progressive_frames_completed=0 BUG_PRESENT=no

When a leading fcTL has an incorrect frame size it is ignored and
PNG_FIRST_FRAME_HIDDEN is set. The progressive reader was still calling
frame_end_fn after the default IDAT, completing 1 frame while the
sequential reader completed 0. Skip the frame_end callback for the hidden
default image to align both read paths.
@jbowler

jbowler commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

There are a whole lot of bugs reported here in the Stepin APNG reader.

Perhaps someone would like to enter the arena as a maintainer? @ProgramMax

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants