WebP File Inspector
Three quite different files share the .webp extension, and the first thing this tool does is tell them apart. A simple lossy file is a RIFF header followed by a single VP8 chunk holding one VP8 key frame, whose size lives in two 14-bit fields behind the 9D 01 2A start code, next to the version that selects the loop filter and the show_frame bit. A simple lossless file is a single VP8L chunk whose five-byte header packs width minus one, height minus one, an alpha hint and a three-bit version behind the 0x2F signature. An extended file starts with VP8X, which declares the canvas as two 24-bit minus-one fields plus a bitmap of features — ICC, alpha, Exif, XMP, animation — and is followed by any of ICCP, ANIM, ANMF, ALPH, EXIF and XMP. Every chunk is listed with its fourcc, offset, declared size and pad byte, because a chunk with an odd payload is followed by one byte that is not part of it, and a reader that forgets that lands one byte late on everything after the first odd chunk. For an animation the ANIM chunk gives a background colour stored blue, green, red, alpha and a loop count in which zero means forever, and each ANMF gives an offset stored halved — the real position is twice the field, which is the mistake most hand-written readers make — plus a size, a duration in milliseconds, blend and dispose bits, and whether that frame’s payload is lossy, lossless, or lossy with a separate ALPH chunk beside it. Two numbers are worth checking on any file you did not write yourself: the RIFF size field, which has to equal the file size minus eight and does not in a download that stopped early, and the canvas, which libwebp requires to match the still image inside it rather than scaling to fit. The preview is decoded by your own browser from the same bytes, so the declared canvas and the decoded canvas sit next to each other; when the browser refuses the file outright, that refusal is itself the answer. What it will not do is decode pixels itself or list every Exif tag — a size, a byte order and an IFD0 entry count is as far as the metadata goes.
How to use
- Drop a .webp file onto the box. Anything the extension covers works: a photo, a sticker with transparency, an animation, or a file you suspect is broken.
- Read the file shape first. Simple lossy, simple lossless and extended are three different layouts, and a decoder that only understands the simple forms will refuse the third.
- Compare the declared canvas with what this browser decoded. They should match; if the browser refused the file entirely, the findings list says why.
- Open the chunk table for the layout: fourcc, offset, declared size and whether a pad byte follows. The offsets are where to look if you are debugging a writer.
- For an animation, check the frame table — offsets are already doubled back from the halved field — and the durations, where a 0 ms frame is played as 100 ms by Chrome.
Frequently asked questions
- Why does one .webp start with a VP8 chunk and another with VP8L or VP8X? Are they the same format?
- They share a container and an extension, not a bitstream. The simple lossy form wraps one VP8 key frame — the same intra frame a VP8 video would start with — and the simple lossless form wraps a VP8L stream, which is an entirely different codec with its own entropy coding and colour transforms. The extended form puts a VP8X chunk first so the file can also carry alpha in a separate ALPH chunk, an ICC profile, Exif, XMP or an animation, and only then the image data. That is why an old decoder can open one WebP and reject the next: support for the simple forms arrived in 2010 and the extended form in 2011, and libraries added them at different times. The fourcc of the first chunk is the only thing that decides which shape you have.
- The frame offsets in an animation look like half of what they should be. Why?
- Because that is literally what is stored. An ANMF header holds the frame’s X and Y as 24-bit values that are the real offset divided by two, which is also why a frame can only be placed at an even coordinate. A reader that prints the field verbatim shows a frame at x=8 as x=4, and a compositor that uses the raw field draws every frame at half the distance from the canvas edge — a bug that looks like a subtle drift rather than an obvious break. The same header stores width and height minus one, so a 32-pixel-wide frame is written as 31. This tool doubles the offsets and adds one to the sizes before showing them, which is why the numbers here match what a decoder actually paints.
- What happens to a frame that declares a duration of 0 ms?
- It is not shown for zero time. Chrome and the other Blink-based browsers substitute 100 ms for a WebP frame whose duration is 0, the same substitution they make for a GIF frame with a very small delay, on the theory that a zero was a mistake rather than a request for an infinitely fast animation. Firefox and Safari have not always agreed, and command-line tools such as ffmpeg keep the zero and produce a different frame rate. The practical consequence is that the sum of the declared durations is not how long the file plays: this tool shows both totals so you can see how far apart they are before you rely on the timing.
- The canvas and the image inside it are different sizes. Will the browser stretch or letterbox it?
- Neither, for a still image. libwebp requires the VP8X canvas to equal the dimensions of the single VP8 or VP8L frame it contains, and refuses the file when they disagree — and since Chrome, Firefox and Safari all decode WebP with libwebp, a mismatched still simply does not display anywhere. For an animation the rule is different and the canvas is genuinely allowed to be larger: each ANMF frame is composited at its own offset, and anything extending past the canvas edge is clipped. That is why this tool treats a canvas-versus-bitstream disagreement on a still as a finding and reports frames that overflow the canvas separately.
- Why does the RIFF size field matter if the file plays anyway?
- It only plays anyway if the field is right. The four bytes at offset 4 must hold the file size minus eight — the eight being the RIFF fourcc and the size field itself — and libwebp validates that before it decodes anything. A download that stopped early keeps its original size field while losing bytes off the end, so the field is too large and the file is rejected with no message beyond a broken image icon. The opposite case is a writer that forgot to go back and patch the field after appending metadata, which produces a file that some tools read and browsers do not. This tool prints both numbers so you can see which of the two you have, and it separately flags any bytes sitting after the last chunk.
- How is transparency stored, and why does the same picture sometimes have an ALPH chunk and sometimes not?
- There are three arrangements. A lossless file records alpha inside the VP8L stream itself and just sets a hint bit in its header. A lossy file cannot, because VP8 has no alpha channel at all, so the encoder emits an extended file: a VP8X with the alpha flag set, an ALPH chunk holding the alpha plane — compressed losslessly, and optionally filtered horizontally, vertically or by gradient — and then the VP8 chunk with the colour. An animation repeats that per frame, so some frames can carry ALPH and others not. One more thing worth knowing: a lossy encoder normally throws away the colour of fully transparent pixels to save bytes, which is invisible until something composites or blurs the image, and libwebp’s `exact` option is what preserves it.
Related tools
WAV File Inspector
Drop a .wav file and read its format, channels, sample rate, bit depth, duration, all RIFF chunks, and embedded LIST/INFO tags — fully client-side.
GIF Structure Inspector
Open a .gif and read its blocks: frame delays and disposal, loop behaviour, palettes, transparency, and how many bytes each frame really costs.
MP4 / ISO Base Media File Inspector
Open an MP4, M4A, M4V or MOV in your browser: brands, the fast-start check, the whole box tree, every track codec and duration, and iTunes tags.
PNG Chunk Inspector
Drop a `.png` file and see every chunk it contains — IHDR, IDAT, tEXt metadata, IEND — with sizes, CRCs, and the critical/ancillary/safe-to-copy flags.
Image EXIF Viewer
Drop a photo to inspect its EXIF metadata — camera, lens, exposure, GPS — all in your browser, nothing uploaded.
Image EXIF Stripper
Drop a photo and download a clean copy with EXIF, GPS, and other metadata removed — all in your browser, no upload.