format: AVIF is the twenty third format, and its encoder is somebody else's - #23
Merged
Conversation
…else's The first format here whose pixels are coded by a library rather than by code in this repository. AV1 is too large to write by hand for one format - the coefficient tables alone in the nearest implementation are fourteen times the size of this project's whole WebP encoder - so the encoder is github.com/gen2brain/gav1d, pinned, pure Go, with an empty go.mod of its own. Every size from the minimum of 311 B upwards is reachable with no gaps. The padding travels in a free box, which is what the container sets aside for space that means nothing, and it takes any length at all. Measured against Pillow on files this encoder produces, with a negative control: Pillow refuses a truncated file and a corrupted payload, while ffprobe accepts both and therefore witnesses nothing. The picture goes up to 40 megapixels, the same ceiling PNG, JPG and GIF use, so Full HD and 4K are both in reach. Left alone it is the largest of a fixed set that fits the size asked for, up to 640x480, which is what JPG does. Three things were found by measuring rather than by reading, and each is guarded now: - The library this started with reached the network. gen2brain/avif runs its codec as WebAssembly through wazero, and wazero imports net for WASI sockets, so the command line binary linked a socket for the first time. That binary not linking net is a promise this project keeps and checks, so the road was abandoned after being built. gav1d costs 2.30 MB against 6.02 MB and reaches nothing. - The encoder's AVX2 path reads past the end of a buffer. A 640x256 picture kills the process, in two runs out of three, so it turns on what the heap looks like. One size out of 240 crashed with the assembly and none without it, and the bytes are identical either way. The tag that removes it lives in .github/build-tags and every command that compiles this project reads that file rather than carrying a copy. - Planning coded the picture to learn its size, so previewing a thousand files cost 51 seconds where BMP costs a fifth of one. Each step of the size ladder now carries a measured ceiling, planning is arithmetic again, and the encode happens while writing. Byte stability is measured on three systems and two architectures rather than on one: Windows, Linux and macOS on arm64 produce the same five files, byte for byte.
The dependency gate asks two questions - whether the module graph moved, and what cmd/tfg actually links - and the second one still named the two modules this binary carried before AVIF. The half that reached the runner rather than the local gate is the interesting part: preflight was only asking the first question, so it said 66 modules unchanged while CI failed on a list nobody local was reading. It asks both now, and takes the second list from this file rather than carrying a copy.
The runner installs the distribution's Pillow, which cannot open an AVIF at all - PIL.UnidentifiedImageError on a file the structural checker had just called sound, while every other picture format passed. So the job was failing on the file for a reason that had nothing to do with the file. The newest Pillow is now installed for the same interpreter the oracle reaches for, and then ASKED whether it can read one. No version is named: the question is what this Pillow can do, not when the support landed. A Pillow that cannot would make this job green while proving nothing about AVIF, which is the exact failure the job exists to prevent. The package comment for avif also stopped being true when the encode moved out of planning, and says what the code does now.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AVIF joins the list, and it is the first format here whose pixels are coded by
somebody else's encoder rather than by code in this repository.
What it does
One frame, 8 bit, 4:2:0, in an ISO base media container.
width,heightandqualitycan be set, and the picture goes up to 40 megapixels - the sameceiling PNG, JPG and GIF use - so Full HD and 4K are both in reach. Left alone,
the picture is the largest of a fixed set that fits the size asked for, up to
640x480, which is what JPG does.
Every size from its minimum of 311 B upwards is reachable, with no gaps. The
padding travels in a
freebox, the box the container sets aside for space thatmeans nothing, and it takes any length at all.
Why a borrowed encoder
AV1 is too large to write by hand for one format. The coefficient tables alone
in the nearest implementation are fourteen times the size of this project's
entire WebP encoder, and the whole of it is half again the size of this whole
program. The encoder is
github.com/gen2brain/gav1d, pinned, written in Go,with an empty
go.modof its own - so it brings nothing else along, needs no Ccompiler, and links no socket.
Raising it moves bytes, which puts it in the same class as the Go compiler this
project already pins.
Three things measurement changed
The library this started with reached the network.
gen2brain/avifruns itscodec as WebAssembly through
wazero, andwazeroimportsnetfor WASIsockets - so the command line binary linked a socket for the first time. That
binary not linking
netis a promise this project keeps and checks, so the roadwas abandoned after being built and measured.
gav1dcosts 2.30 MB against6.02 MB, encodes five times faster, allocates twenty six times less, and
reaches nothing.
The encoder's AVX2 path reads past the end of a buffer. A 640x256 picture
kills the process - in two runs out of three, so it turns on what the heap looks
like rather than on the input alone. One size out of 240 crashed with the
assembly and none without it, and the bytes are identical either way. The tag
that removes it lives in
.github/build-tags, and every command that compilesthis project reads that file rather than carrying a copy. Probe:
tools/probes/avifasm.Planning coded the picture to learn its size, so previewing a thousand files
cost 51 seconds where BMP costs a fifth of one, and twenty thousand never
finished inside the test timeout. Each step of the size ladder now carries a
measured ceiling, planning is arithmetic again, and the encode happens while
writing. A thousand files now preview in 0.208 s.
Evidence
(WSL) and macOS on arm64 produce the same five files, byte for byte. Pinned in
generator-golden.jsonas well.refuses a truncated one and a corrupted payload. ffprobe accepts all three
broken files, so it witnesses nothing - the evidence rests on Pillow and on a
structural checker that walks the box tree, which catches five deliberate
breaks out of five.
readable.
repaired along the way, three of them older than this branch.
Binaries: command line 8 010 752 -> 10 417 664 B, window 52 041 709 B.
Full record, including the roads turned down and what they cost:
docs/STACK.mdsection 4.2.1.🤖 Generated with Claude Code