How GIMP Splits Animated WebP into Layers

When importing an animated WebP file, GIMP processes the file using its native file-webp plug-in and Google's libwebpdemux library to unpack the RIFF container. The software extracts individual frame data, converts each frame into a full-canvas raster layer, and translates embedded animation parameters—such as frame delay and disposal methods—directly into GIMP's layer naming syntax. This structural conversion allows the user to edit, manipulate, and preview the individual frames within GIMP's standard layer hierarchy.

Demuxing the RIFF Container

The WebP format stores animation data inside an ANIM chunk (which defines global canvas properties like background color and loop count) and multiple ANMF (Animation Frame) chunks. Upon opening the file, GIMP's WebP loader initializes a demuxer instance using WebPDemuxGetI().

The plug-in sequentially iterates through every ANMF chunk using WebPDemuxNextFrame(). For each chunk, the demuxer extracts:

  • The compressed image bitstream (VP8 or VP8L).
  • Frame coordinates (X and Y offsets relative to the main canvas).
  • Frame dimensions (width and height).
  • Frame duration in milliseconds.
  • Blending and disposal flags.

Canvas Reconstruction and Layer Allocation

Because animated WebP files often optimize file size by storing only the "dirty" bounding box—the pixels that change between frames—an individual frame's bitmap may be smaller than the overall animation canvas. GIMP standardizes these inputs to ensure uniform layer dimensions:

  1. Decoding the Bitstream: The loader decodes the WebP bitstream into a raw RGBA pixel buffer using WebPDecodeRGBA().
  2. Layer Initialization: GIMP creates a new GimpLayer matching the overall canvas dimensions defined in the WebP header.
  3. Compositing: The decoded frame pixel data is painted into the layer at the specific (X, Y) offset retrieved during the demuxing phase. Any canvas area outside the frame's specific bounding box is filled with transparent pixels, preserving the spatial integrity of partial-frame updates.
  4. Stack Placement: The layers are added to the image stack sequentially from bottom to top, where the bottom-most layer represents Frame 1 and the top-most layer represents the final frame.

Metadata Encoding into Layer Names

GIMP does not maintain a separate metadata track for frame intervals inside the native image runtime. Instead, it relies on an established textual convention parsed by GIMP's internal animation engine (used by filters like "Animation Playback"):

  • Duration: The frame duration extracted from the ANMF chunk (in milliseconds) is converted into a string format: (###ms).
  • Disposal Mode: The disposal flag determines how the current frame behaves when the next frame appears. GIMP translates these flags into (combine) or (replace) tags:
    • WEBP_MUX_DISPOSE_NONE translates to (combine), instructing the renderer to draw the next frame on top of the current one.
    • WEBP_MUX_DISPOSE_BACKGROUND translates to (replace), instructing the renderer to clear the frame before drawing the subsequent one.

The loader concatenates the frame identifier, delay, and disposal behavior into the layer's label. A generated layer will typically be named using the pattern: Frame 1 (100ms) (replace). When playback is triggered or the file is re-exported to an animated format, GIMP parses these text tags to reconstruct the playback timing and state behavior accurately.