102 lines · 3.4 KB
// Package diffs compares two renderings of the same screen.
//
// The comparison is deliberately coarse. squint renders both sides in one
// run on one machine, so there is no font-hinting or architecture noise to
// tolerate -- but a language model is the fine judge downstream, so this
// only has to answer "did anything move", generously, and mark where.
// Being generous here is what keeps a reviewer's attention on the three
// screens that changed instead of the forty that did not.
package diffs

import (
	"fmt"
	"image"
	"image/color"
	"image/draw"
)

// Tolerance is how far one colour channel may move before a pixel counts.
// Both sides come from the same browser in the same run, so this is not
// for anti-aliasing; it is so a single rounding step in a gradient does
// not start a conversation.
const Tolerance = 16

// Threshold is the fraction of pixels that must differ before a shot is
// worth a look. Generous on purpose: the model downstream decides whether
// a real change matters, and a tight number here would hand it noise.
const Threshold = 0.001

// Result is what comparing two renderings found.
type Result struct {
	// Total and Changed count pixels; Fraction is Changed over Total.
	Total    int     `json:"total_pixels"`
	Changed  int     `json:"changed_pixels"`
	Fraction float64 `json:"fraction"`
	// Resized is set when the two renderings are different shapes, which
	// is a change on its own: a page that got taller moved everything
	// below the change.
	Resized string `json:"resized,omitempty"`
	// Diff marks where. Nil when the shapes disagree, since there is
	// nothing to overlay.