GIF Structure Inspector
Walks a GIF the way a decoder must — block by block, from the 13-byte header to the 0x3B trailer, with nothing skipped by guesswork. The header gives the version (GIF87a knows no extensions at all; GIF89a is the one that can animate), the logical screen the frames are composed onto, the background colour index, the pixel aspect ratio byte no browser has honoured in thirty years, and whether a global colour table is present, how many entries it holds and how many bits that is. Every frame is then listed with the two numbers that decide how it plays: its delay and its disposal method. Delays are the usual reason a GIF looks slow — they are stored in hundredths of a second, and browsers silently replace anything under about 20 ms with 100 ms, so a file written at 5 ms a frame plays five times slower than its author intended. Both totals are shown: what the delays add up to, and what you will actually see. Disposal is why frames smear or flash: restore-to-background clears the frame’s rectangle before the next one arrives, restore-to-previous rewinds the canvas, and leave-in-place is what lets an optimiser store only the pixels that changed. That optimisation shows up here as well, since a frame smaller than the logical screen is flagged along with its position, its own local colour table if it has one, its interlace flag and its transparent index. Because the sub-block chains are followed exactly rather than scanned for, each frame’s byte cost is exact, and the table ranks them, so the frame that made the file 20 MB is the one at the top. The rest of the file is split into colour tables, LZW image data and block overhead, and every extension block — graphic control, comment, plain text and application, including the NETSCAPE loop counter and anything unrecognised — is listed with its offset, size and text. What it will not do is decode pixels: the LZW streams are measured, never decompressed, so nothing is said about colour accuracy, dithering or how similar two frames are. A file that is truncated, or whose block lengths run off the end, is refused with a named error rather than half-read, because past that point every offset would be a guess.
How to use
- Drop a .gif on the box, or click it to pick a file. The bytes are read in the page; nothing is uploaded.
- Read the overview first: header version, logical screen, frame count, the duration a browser will actually play, and the loop behaviour.
- If the playback warning appears, the frame delays are below the browser floor — raise them to 20 ms or more, or the file will always play slower than it claims.
- Take size questions to the frame table: the byte column and its bar show which frames cost the most, and a size marked * means that frame repaints only part of the canvas.
- Check the extension list for the NETSCAPE loop block, comments left by the encoder, and any application block you did not expect.
Frequently asked questions
- Why does my GIF play slower than the delays I set?
- Because browsers refuse very short delays. The delay lives in each frame’s graphic control extension in hundredths of a second, so the smallest non-zero value is 10 ms — but Blink and WebKit replace anything below 11 ms with 100 ms, and Gecko does the same below 20 ms. A file exported at "50 fps" therefore runs at 10 fps, ten times too slow, and there is no flag that overrides it: the clamp dates back to pages full of one-frame GIFs used as spacers, and every engine still applies it. This tool shows both figures, what the delays add up to and what a browser will really take, so you can tell a clamped file from a genuinely long one. If you need fast motion, the answer is a video codec, not a GIF.
- What does the loop count actually mean?
- Looping is not in the GIF specification at all. It is an application extension Netscape added in 1995: the 11-byte identifier NETSCAPE2.0 followed by a sub-block holding a 16-bit count. Zero means loop forever, which is what almost every encoder writes. A non-zero count is the number of extra plays after the first, so 1 shows the animation twice in Chrome and Firefox, although a few historical readers treated it as the total instead. If the block is missing entirely the animation plays exactly once and stops on the last frame — a common surprise after a file has been through a tool that drops extensions it does not recognise.
- Why is my GIF so large?
- Almost always because each frame stores the whole canvas instead of the part that changed. The byte column here charges every frame with everything it costs — its graphic control extension, its image descriptor, its local colour table and its LZW data — so the ranking is exact rather than an estimate. Three things dominate: full-frame rewrites, where every frame is the size of the logical screen; local colour tables, at 768 bytes each for 256 entries, which is 45 KB across sixty frames before a single pixel is stored; and LZW itself, which does badly on photographic or dithered content and can end up larger than the raw indices. The byte summary separates all three, so you can see which one you are paying for.
- What are disposal methods, and why do my frames leave ghosts?
- A GIF frame paints onto the canvas the previous frame left behind; the disposal method says what happens to that frame before the next one is drawn. 0 (unspecified) and 1 (do not dispose) keep it, which is what makes delta frames possible — only the changed pixels need to be stored. 2 clears the frame’s rectangle back to the background, which is what you want when transparent pixels must not accumulate, and what causes a visible flash when the whole screen is cleared each time. 3 restores whatever was on the canvas before the frame was drawn; it is expensive and rarely implemented consistently. Trails and ghosting nearly always mean disposal 1 where 2 was intended, or transparent pixels drawn over frames that were never cleared.
- Why do transparent edges look jagged?
- GIF transparency is a single palette index, not an alpha channel. A frame may nominate one entry as transparent, and every pixel carrying that index is skipped when the frame is composed; there is nothing between fully opaque and fully invisible. Anti-aliased edges from a PNG have nowhere to go, so the semi-transparent pixels are either blended against whatever background the exporter assumed — the familiar white or grey halo — or snapped to the transparent index, which leaves the staircase. It also costs a colour: an image with transparency has 255 usable entries, not 256. Note that the transparent index is per frame, so a decoder only ever reports the current frame’s.
- What is the difference between GIF87a and GIF89a, and does interlacing still help?
- GIF87a is the original 1987 format and has no extension blocks at all, which means no delays, no transparency, no loop counter and no comments. GIF89a added the extension mechanism, and everything people think of as GIF behaviour lives in it. Both are still read by everything, and encoders quite reasonably write 87a when nothing 89a-specific is needed — a single still frame usually is. Interlacing is a separate per-frame flag: rows are stored in four passes so a partly downloaded image already shows a coarse version of the whole picture. On a modern connection it buys nothing, and it slightly enlarges the LZW stream by breaking the correlation between neighbouring rows, so a stray interlaced frame is mostly a sign that the file passed through an old tool.
Related tools
WebAssembly Module Inspector
Inspect a .wasm file in your browser: section sizes, imports and exports with full types, memory pages, the start function, name and producers sections.
WebP File Inspector
Walk a .webp file’s RIFF chunks in your browser: lossy, lossless or extended, canvas versus frame size, animation timing, alpha, ICC, Exif and XMP.
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.
EditorConfig Tester
Paste an .editorconfig and some file paths: see the property set each file resolves to, and which section on which line decided every value.
gzip (.gz) Inspector
Read a .gz header field by field, walk every member, and verify the trailer by recomputing CRC32 and the real size in your browser.
JPEG Structure Inspector
Open a .jpg and read its marker segments: baseline or progressive, chroma subsampling, estimated quality, and where the bytes actually went.