/** * `@variance-authority/png/mask` — the difference mask, without a codec. * * `pixelmatch` takes RGBA and returns RGBA. Nothing in the per-pixel work needs * a decoder, and the only reason it ever lived beside one is that every caller * in this repository happened to be holding PNG bytes. A caller holding pixels — * a canvas, a framebuffer, `createImageBitmap` in a review page — should not * have to install `pngjs` to reach the same arithmetic, and a bundler following * this subpath must not find it. * * So the subpath exists, and it exports exactly two things: the padding rule and * the diff. Both matter more than they look, because a diff is now computed in * two places — Node, when a run writes its report, and the browser, when a * reviewer opens a change whose mask was never uploaded. Two ends computing the * same thing from the same inputs is only safe while it is literally the same * code; the moment one of them reimplements padding or re-reads a threshold, the * two disagree silently and the reviewer is looking at a mask the verdict was * not made from. Hence one function, imported by both. */ import { type DiffPolicy, type RowAlignment } from '@variance-authority/raster'; import { type AlignedRows } from './align.js'; export type { AlignedRows } from './align.js'; /** * One decoded image: raw 8-bit RGBA, row-major, no padding. * * The shape `pixelmatch` needs and the smallest thing every decoder agrees on. */ export interface DecodedImage { readonly width: number; readonly height: number; readonly data: Buffer | Uint8Array; } /** A difference, as pixels and a count — whatever the caller wanted rendered. */ export interface PixelDifference { readonly width: number; readonly height: number; readonly data: Uint8Array; /** Pixels the policy called different. The number the verdict is made from. */ readonly changed: number; /** How the rows were paired, when they were: see {@link alignRows}. */ readonly alignment?: RowAlignment; } /** * Copy `image` onto an opaque white canvas, top-left aligned. * * `pixelmatch` requires equal dimensions and Playwright's own `toHaveScreenshot` * simply fails when they differ. Failing is the easy choice and the dishonest * one — it lets a layout change score "detected" without measuring anything. So * both are padded onto the union box and the padding is reported, which is the * more generous treatment: a story that grew by one row differs in that row * rather than in its entire area. * * White because a page's declared canvas is white. Transparent padding would * invent a difference wherever the shorter image's own background is opaque, * which is every subject. */ export declare function padTo(image: DecodedImage, width: number, height: number): DecodedImage; /** * Two images onto one mask, at a policy. * * `diffMask` is the difference between the two things this is asked for. Off, * `pixelmatch` renders the familiar picture — the after image dimmed with the * changed pixels in red — which is what a human opens. On, it writes *only* the * differing pixels and leaves the rest transparent, so the alpha channel is the * mask and nothing has to be recovered from red-on-grey. * * When the rows align ({@link alignRows}), each after row is compared with the * before row that shows the same content, on the after image's canvas, and an * after row with no partner is marked in full. Otherwise the two are compared * position by position on the union box. `alignment` is the caller's, when it * computed one already for another policy over the same two images, and `null` * when it asked and there was none. */ export declare function differencePixels(before: DecodedImage, after: DecodedImage, policy?: DiffPolicy, { diffMask, alignment: given, }?: { readonly diffMask?: boolean; readonly alignment?: AlignedRows | null; }): PixelDifference; //# sourceMappingURL=mask.d.ts.map