/**
* Freeze an animated GIF by *truncating* it, before the browser ever decodes it.
*
* ## Why a GIF is the hardest of the easy cases
*
* A GIF has been animating since it decoded. No CSS reaches it — `animation-*`
* governs CSS animations and a GIF is not one — so the trick that pins every
* keyframe on the page leaves a spinning logo spinning, and two runs a second
* apart read two different images.
*
* Argos solves this in the page, and the design is careful: construct a *fresh*
* `Image`, draw it to a canvas, take `toDataURL('image/png')` as frame zero, and
* swap it into `src`. Fresh, because the `
` already on the page has been
* animating since load and there is no way to seek it back. It works, and it has
* a failure mode its own documentation states — a cross-origin image without
* CORS taints the canvas, `toDataURL` throws, and the GIF is left animating.
*
* ## Why doing it on the wire is strictly better
*
* Intercept the response and the problem changes shape. The bytes have not been
* decoded yet, so there is no animation to seek back to zero and no second
* decode to pay for. **Cross-origin stops mattering**, because the fulfilment is
* ours: a canvas is tainted by what the page may read, and nothing here asks a
* page to read anything. And the result is the original bytes minus some of
* them, so the palette, the transparency, the dimensions and the compression are
* exactly what the author shipped — where a canvas round-trip re-encodes through
* RGBA and produces a PNG that is a different image from the one under test.
*
* ## What the truncation actually is
*
* A single-frame GIF is a valid GIF, and it is a prefix of the animated one.
* The format is a header, a screen descriptor, an optional global colour table,
* and then a stream of blocks — extensions, image descriptors — ending in a
* trailer. Keep everything up to and including the **first image descriptor and
* its pixel data**, append the trailer byte, and the file is complete and
* static. No decoder, no encoder, no dependency, and no re-encoding.
*
* This is the whole reason it lives in a package that requires a browser rather
* than one that requires an image codec: it does not need one.
*
* @see https://www.w3.org/Graphics/GIF/spec-gif89a.txt
*/
/**
* The first frame of a GIF, as a GIF — or `null` when there is nothing to do.
*
* `null` for anything this cannot honestly improve: bytes that are not a GIF,
* bytes that are a GIF with one frame already, and bytes it could not parse.
* Three different reasons for the same answer, because the caller's move is the
* same in all three — pass the response through untouched — and inventing an
* output for a file we did not understand is how a stabilizer corrupts an asset.
*
* Never throws. This runs inside a request handler, and a stabilizer that can
* take down a page load is worse than the flake it prevents.
*/
export declare function freezeGif(bytes: Uint8Array): Uint8Array | null;
/**
* Whether a response is a GIF, by header first and extension second.
*
* Content type is what the browser will believe, so it decides. The extension is
* a fallback for a server that sends `application/octet-stream` — common enough
* on object storage — and never an override, because a `.gif` served as `png` is
* a PNG to every decoder that matters.
*/
export declare function isGifResponse(headers: Readonly>, url: string): boolean;
//# sourceMappingURL=gif.d.ts.map