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:
- Decoding the Bitstream: The loader decodes the WebP
bitstream into a raw RGBA pixel buffer using
WebPDecodeRGBA(). - Layer Initialization: GIMP creates a new
GimpLayermatching the overall canvas dimensions defined in the WebP header. - 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.
- 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
ANMFchunk (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_NONEtranslates to(combine), instructing the renderer to draw the next frame on top of the current one.WEBP_MUX_DISPOSE_BACKGROUNDtranslates 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.