From 930d4a3ac91c226741fb14d48c2d29ff0edeaafb Mon Sep 17 00:00:00 2001 From: DonislawDev Date: Sat, 29 Aug 2026 12:07:42 +0200 Subject: [PATCH] format: a GIF moves, and WEBP is the twenty second format BREAKING: generated bytes change for gif Two formats, one reason. A GIF that cannot animate and a WebP that does not exist both leave a tester unable to answer a question about their own site. ## The GIF moves Reported from use rather than found here: a generated GIF went into an upload form, came back a still picture, and nothing about that said whether the site keeps animations, flattens them to the first frame, or re-encodes them. The plan had declared "animated" and "frame_count" since the format was written, so the manifest could describe an animation and nothing could produce one. Every GIF now carries a marker travelling across the picture in three frames. frames is a setting from 1 to 60. Measured before choosing, at 640x480 and three frames: * a square patch disposed "restore to previous" +329 B * a full width band redrawn each frame +18626 B * the same band, flattened in the base picture +1302 B The first, and the disposal rule it leans on was measured rather than feared: Pillow and ffmpeg compose the frames and find one marker in each with no trail, the Windows Imaging Component and Chromium both count three frames. A separate measurement fixed something that would have cost every file: with no GIF.Config the encoder writes no global colour table and gives every frame its own, so a 12 px square cost 233 B instead of 41 B - 192 B of it a second copy of the palette. The minimum rises from 41 B to 114 B, because the number a format announces has to be one a plain run accepts, and a plain run animates. **--set frames=1 is the way back**, byte for byte. The proof is not a sentence: the golden case gif_64kib_one_frame carries 659e4880..., which is the hash that was pinned under gif_64kib until today. ## WEBP, written rather than borrowed x/image/webp at v0.43.0 holds decode.go and doc.go, so there was no encoder to take. Pure Go encoders exist outside it and were rejected for one reason: their next release would move the hashes in other people's CI, and D11 is ours to keep. The bitstream is 203 lines and compresses nothing on purpose. Three channels declare all 256 literals at eight bits, so the canonical code for a symbol is that symbol, no Huffman tree is built, and a pixel costs exactly 24 bits. The size is then arithmetic that inverts, so the picture GROWS to fill the request instead of being a thumbnail followed by filler - the shape BMP and TIFF have. The padding channel was unverified since the project began, and the note describing it named the wrong problem. Decoder tolerance was never the issue: an unknown chunk at the end passes all six readers. The issue is that every RIFF chunk block costs an EVEN number of bytes, so a file built only of chunks can only have an even length. Hence two stages - a private chunk for the bulk, one to seven bytes after the payload for the rest - and no dead zone at all, which neither PNG nor GIF manage. A negative control is what makes the reader list mean anything: a truncated WebP is accepted by ffprobe and by the Windows Imaging Component, so the evidence rests on the four readers that can say no. Pixels are compared, not merely decoded, in Pillow and in Chromium. ## Two defects found by guards rather than by reading The first encoder built the whole file in memory and carried a comment explaining why it had to - "a Huffman stream is not a sequence of whole bytes". True, and not a reason: the partial byte is one byte of state. The guard measured 67598496 B of allocation for a 67108864 B file and refused. Writing through to the output moved no byte of any file, which the pinned hashes prove. Both new packages then crossed the size and branching ceilings, and are split by job rather than counted upwards - gif and webp each read as container, pixels and bitstream now. Ten mutations, all caught. An eleventh was written and thrown away before it reached the list: mutating the oracle to decode only the first frame breaks nothing, because a valid file decodes fine from frame one. --- CHANGELOG.md | 37 ++ README.md | 21 +- internal/format/all/all.go | 1 + internal/format/gif/animation.go | 98 ++++ internal/format/gif/gif.go | 174 +++---- internal/format/gif/picture.go | 113 +++++ internal/format/webp/picture.go | 102 ++++ internal/format/webp/vp8l.go | 203 ++++++++ internal/format/webp/webp.go | 469 ++++++++++++++++++ internal/guard/animation_test.go | 230 +++++++++ internal/guard/generatorbytes_test.go | 37 ++ internal/guard/layers_test.go | 3 + internal/guard/oracle_test.go | 2 +- internal/guard/parity_test.go | 4 + internal/guard/testdata/generator-golden.json | 35 +- .../screens/generate-menu-hovered.png | Bin 61438 -> 61440 bytes .../screens/generate-menu-hovered.xml | 6 +- .../testdata/screens/generate-menu-keyed.png | Bin 61506 -> 61509 bytes .../testdata/screens/generate-menu-keyed.xml | 6 +- .../guard/testdata/screens/generate-menu.png | Bin 61300 -> 61303 bytes .../guard/testdata/screens/generate-menu.xml | 6 +- .../testdata/screens/preset-menu-setting.png | Bin 76830 -> 76868 bytes .../testdata/screens/preset-menu-setting.xml | 6 +- internal/guard/textformats_test.go | 2 +- internal/gui/parts/filekind.go | 1 + internal/oracle/oracle.go | 2 +- internal/oracle/scripts.go | 18 +- internal/oracle/strict.py | 47 +- web/public/faq/index.html | 4 +- web/public/formats/index.html | 32 +- web/public/index.html | 14 +- web/public/pl/faq/index.html | 4 +- web/public/pl/formaty/index.html | 32 +- web/public/pl/index.html | 14 +- web/public/social.html | 4 +- 35 files changed, 1550 insertions(+), 177 deletions(-) create mode 100644 internal/format/gif/animation.go create mode 100644 internal/format/gif/picture.go create mode 100644 internal/format/webp/picture.go create mode 100644 internal/format/webp/vp8l.go create mode 100644 internal/format/webp/webp.go create mode 100644 internal/guard/animation_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index eadfc3b..4abeaa0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,45 @@ because it turns other people's test suites red. ## [Unreleased] +### Breaking + +- **A generated GIF now moves, so its bytes are different.** A GIF is the one + picture format here that can hold more than one frame, and a still one told + you nothing about how the system under test treats an animation - whether it + keeps it, flattens it to the first frame, or re-encodes it. Every GIF now + carries a marker that travels across the picture in three frames, and the + manifest says `animated` and `frame_count` for each file. + + Two things change with it. The smallest GIF this tool will write goes from + 41 B to 114 B, because the number a format announces as its minimum has to be + a number a plain run accepts, and a plain run animates. And the bytes of every + GIF change, so a suite pinning their hashes will go red. + + **The way back is `--set frames=1`**, or `frames: 1` on a target in a recipe. + That takes the plain encoder and writes the same bytes this tool wrote before, + to the byte - there is a pinned hash proving it. + ### Added +- **WEBP, the twenty second format.** Lossless, one frame, no alpha. + `tfg generate --format webp --size 300kb` writes a picture worth 300 kB rather + than a thumbnail followed by filler, because the encoder measures out three + bytes a pixel and the size is therefore arithmetic - the same shape as BMP and + TIFF. `width` and `height` can be set, and naming one lets the other be worked + out from the size. The smallest WEBP this produces is 148 B. + + **Every size from that minimum upwards is reachable, with no gaps.** No other + format here manages that. A WebP is made of RIFF chunks and a chunk always + costs an even number of bytes, so the padding is in two parts: a private chunk + for the bulk, and up to seven bytes after it for the rest. + + There is no lossy variant and no `quality`. Lossy WebP is VP8, which is a + different codec rather than a setting, and `tfg formats webp` says what this + build writes rather than implying more. + +- **`frames` on GIF**, from 1 to 60, default 3. How many frames the animation + has. Set it to 1 for a still picture. + - **TIFF, the twenty first format.** Uncompressed, RGB, one page, little-endian. `tfg generate --format tiff --size 300kb` writes a picture worth 300 kB rather than a thumbnail followed by filler, because TIFF stores its pixels diff --git a/README.md b/README.md index 5819016..e292550 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ **Testing Files Generator** is a tool for QA engineers and developers who need real files to test against - an upload form, a parser, anything that takes a file and -has an opinion about it. You pick one of its 21 formats and the size you want, +has an opinion about it. You pick one of its 22 formats and the size you want, and you get **exactly that**: ask for a 10 MB PDF and you get a PDF that a reader will open, at 10 MB to the byte. Every run also leaves a manifest saying **what your system should do with each file**, which is the part other generators leave @@ -23,7 +23,7 @@ needs it finds out it exists. - **Hit an exact size, to the byte** - ask for 10485761 bytes and get exactly that, never a silently rounded file. -- **Write 21 real formats** - a generated PNG opens in an image viewer, a DOCX +- **Write 22 real formats** - a generated PNG opens in an image viewer, a DOCX opens in Word, a ZIP extracts. Not padded zeros with an extension. - **Say what should happen to each file** - the manifest carries an expected outcome, so your test reads the assertion instead of you writing it out. @@ -76,18 +76,18 @@ reference is below it. ## 📁 Formats it generates -Twenty one, and every one is a **real file of that format** - it opens in the +Twenty two, and every one is a **real file of that format** - it opens in the software that owns it, at the exact size you asked for: | group | formats | |---|---| | 📄 **Documents** | `pdf`, `docx` (Word), `xlsx` (Excel), `pptx` (PowerPoint) | -| 🖼️ **Images** | `png`, `jpg`, `bmp`, `gif`, `ico`, `svg`, `tiff` | +| 🖼️ **Images** | `png`, `jpg`, `bmp`, `gif`, `ico`, `svg`, `tiff`, `webp` | | 📝 **Text and markup** | `txt`, `md`, `csv`, `json`, `xml`, `html`, `log` | | 🗜️ **Archives** | `zip`, `targz` (`.tar.gz`) | | 🔊 **Audio** | `wav` | -Coming next: `7z`, `webp`, `mp3`, `mp4`. +Coming next: `7z`, `mp3`, `mp4`. Most of them take settings of their own - image dimensions, JPEG quality, PDF page count, rows and columns in a spreadsheet, what goes inside an archive. See @@ -437,7 +437,7 @@ ignored quietly: `extends`, `with`, `policy`, `engine`, `defaults.fill`, ## 📁 Formats in detail -The twenty one formats are listed near the top of this file. Each is produced at an +The twenty two formats are listed near the top of this file. Each is produced at an exact size and checked against independent readers before it ships - a PNG is opened and its pixels compared, a DOCX is read back by three separate libraries, an archive is extracted. @@ -455,7 +455,8 @@ recipe. `tfg formats ` prints the allowed range or list for each: | format | settings | |---|---| | `pdf` | `pages`, `page_size` | -| `png`, `bmp`, `gif`, `tiff` | `width`, `height` | +| `png`, `bmp`, `tiff`, `webp` | `width`, `height` | +| `gif` | `width`, `height`, `frames` | | `jpg` | `width`, `height`, `quality` | | `ico` | `width`, `height`, `embed` | | `wav` | `sample_rate`, `bit_depth`, `channels`, `content` | @@ -659,17 +660,17 @@ a valid one of its format. ### Which formats are coming next? -`7z`, `webp`, `mp3` and `mp4`. +`7z`, `mp3` and `mp4`. ## 🚧 Where this is Honest scope, because a tool that oversells itself wastes your afternoon. -**Working end to end:** twenty one formats, recipes, presets, the desktop window, +**Working end to end:** twenty two formats, recipes, presets, the desktop window, `generate`, `validate`, `verify`, `cleanup`, boundary sets, archive contents, size ranges, per format settings, manifests and every exit code above. -**Not there yet:** four more formats. The preset catalogue has one entry so far. +**Not there yet:** three more formats. The preset catalogue has one entry so far. The recipe keys listed under [Not built yet](#not-built-yet). The Linux downloads are unsigned. diff --git a/internal/format/all/all.go b/internal/format/all/all.go index 029b60e..6eb05a0 100644 --- a/internal/format/all/all.go +++ b/internal/format/all/all.go @@ -26,6 +26,7 @@ import ( _ "github.com/donislawdev/TestingFilesGenerator/internal/format/tiff" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/txt" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/wav" + _ "github.com/donislawdev/TestingFilesGenerator/internal/format/webp" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/xlsx" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/xmlfile" _ "github.com/donislawdev/TestingFilesGenerator/internal/format/zip" diff --git a/internal/format/gif/animation.go b/internal/format/gif/animation.go new file mode 100644 index 0000000..a1bccea --- /dev/null +++ b/internal/format/gif/animation.go @@ -0,0 +1,98 @@ +// Animation, which is the whole reason this format is in the set twice over. +// +// A GIF is the only picture format here that can carry more than one frame, so +// a still one cannot tell a tester whether the system under test keeps an +// animation, flattens it to the first frame, or re-encodes it. What moves is a +// single bright square, redrawn on its own each frame and disposed with +// "restore to previous" so it leaves no trail. +// +// Split out of gif.go on 2026-08-29 because that file reached 478 lines and +// this project counts how many files crowd the size ceiling. The counter is +// meant to fall. +package gif + +import ( + "fmt" + "image" + stdgif "image/gif" + "io" + "strconv" +) + +// frameCount reads the frames setting, which is the one thing about a GIF that +// no other image format here has to answer. +func frameCount(props map[string]string) (int, error) { + raw, ok := props["frames"] + if !ok || raw == "" { + return defaultFrames, nil + } + n, err := strconv.Atoi(raw) + if err != nil { + return 0, fmt.Errorf("gif: frames must be a whole number, got %q", raw) + } + if n < minFrames || n > maxFrames { + return 0, fmt.Errorf("gif: frames must be between %d and %d, got %d", minFrames, maxFrames, n) + } + return n, nil +} + +// marker is where the travelling square sits on frame i, and how big it is. +// +// It rides at three quarters of the height rather than the middle, because the +// label is burned into a band across the top and the two would collide on a +// short picture. +func marker(width, height, frames, i int) (x, y, side int) { + side = width / markerDivisor + if side > maxMarkerSide { + side = maxMarkerSide + } + if side < 1 { + side = 1 + } + if side > height { + side = height + } + x = (width - side) * i / frames + y = (height - side) * 3 / 4 + return x, y, side +} + +// markerFrame is one step of the animation: the square alone, at its own +// offset, and nothing else. Keeping it to the square is what stops the frames +// costing as much as the picture, in bytes and in memory both. +func markerFrame(m memo, i int) *image.Paletted { + x, y, side := marker(m.width, m.height, m.frames, i) + img := image.NewPaletted(image.Rect(x, y, x+side, y+side), buildPalette(paletteSize(m.width, m.height))) + for j := range img.Pix { + img.Pix[j] = labelInk + } + return img +} + +func encode(w io.Writer, m memo) error { + if m.frames <= 1 { + // The plain encoder, byte for byte what this package wrote before it + // could animate. Reached by asking for frames: 1. + return stdgif.Encode(w, picture(m), &stdgif.Options{NumColors: 256}) + } + + base := picture(m) + g := &stdgif.GIF{ + LoopCount: 0, + // Without this the encoder writes no global colour table and gives + // every frame its own. Measured: a 12 px square then cost 233 B + // instead of 41 B, because 192 B of it was a second copy of the + // palette. + Config: image.Config{ColorModel: base.Palette, Width: m.width, Height: m.height}, + Image: make([]*image.Paletted, 0, m.frames), + } + g.Image = append(g.Image, base) + g.Delay = append(g.Delay, frameDelay) + g.Disposal = append(g.Disposal, stdgif.DisposalNone) + for i := 1; i < m.frames; i++ { + g.Image = append(g.Image, markerFrame(m, i)) + g.Delay = append(g.Delay, frameDelay) + g.Disposal = append(g.Disposal, stdgif.DisposalPrevious) + } + return stdgif.EncodeAll(w, g) +} diff --git a/internal/format/gif/gif.go b/internal/format/gif/gif.go index d05cadd..0703482 100644 --- a/internal/format/gif/gif.go +++ b/internal/format/gif/gif.go @@ -10,14 +10,30 @@ // byte costs five, because a sub block pays for its own length. Sizes one, // two and four bytes above the bare picture are therefore unreachable, and // the generator says so instead of rounding. +// +// The picture moves, and that is the point of the format rather than a +// decoration. A GIF is the one image format here that can carry more than one +// frame, so a still one tells a tester nothing about whether the system under +// test keeps an animation, flattens it to the first frame, or re-encodes it. +// Every file therefore carries a marker that travels across the picture, and +// frames says how many steps it takes. +// +// Only the marker is redrawn. Frames after the first are small patches placed +// where the marker lands, disposed with "restore to previous" so the one +// underneath comes back and no trail is left. Measured on 2026-08-29 against +// four independent decoders - Pillow and ffmpeg compose the frames and show a +// single marker in each, the Windows Imaging Component and Chromium both count +// the frames - and against the alternative of redrawing a full width band, +// which cost 18626 B a file at 640x480 where this costs 329 B. +// +// frames: 1 asks for a single picture and takes the plain encoder, which is +// what this package wrote before animation existed. It is the way back to +// those bytes for anybody who pinned them. package gif import ( "context" "fmt" - "image" - "image/color" - stdgif "image/gif" "io" "strconv" @@ -54,6 +70,27 @@ const ( minDimension = 1 maxDimension = 20000 + // A still GIF cannot answer the question a tester asks of one, so three + // is the default: enough for the marker to be somewhere different every + // time, and cheap. Measured at 640x480, three frames cost 329 B over the + // same picture written as a single frame. + defaultFrames = 3 + minFrames = 1 + // Sixty frames run for just over seven seconds at the delay below. The + // ceiling is here because every frame after the first is held in memory + // until the file is written, not because the format minds. + maxFrames = 60 + + // frameDelay is in hundredths of a second, which is the unit the format + // uses. Twelve is slow enough to see and fast enough that a whole cycle + // fits in a glance. + frameDelay = 12 + + // markerSide is a fraction of the width, floored so it never vanishes and + // capped so a huge picture does not put megabytes into every frame. + markerDivisor = 8 + maxMarkerSide = 128 + // The picture is held in memory while it is encoded, one byte per pixel // plus the encoder's own working set. The same budget as PNG, which has // the same shape of cost. @@ -96,6 +133,12 @@ func init() { Min: minDimension, Max: maxDimension, Unit: "pixels", Detail: "How tall the picture is. Left out, a size is chosen that fits the bytes you asked for.", }, + { + Name: "frames", Kind: format.PropertyInt, + Min: minFrames, Max: maxFrames, + Default: strconv.Itoa(defaultFrames), + Detail: "How many frames the animation has. Set it to 1 for a still picture.", + }, }, JointLimits: []format.JointLimit{{ Of: "width", By: "height", Max: maxPixels, @@ -111,6 +154,7 @@ type generator struct{} type memo struct { width, height int + frames int seed uint64 label string // body is the encoded picture up to but not including the trailer. @@ -160,8 +204,8 @@ func (generator) Plan(r format.Request) (format.Plan, error) { "width": w, "height": h, "palette": paletteSize(w, h), - "animated": false, - "frame_count": 1, + "animated": m.frames > 1, + "frame_count": m.frames, }, } @@ -351,6 +395,11 @@ func chooseSize(r format.Request, label string) (memo, error) { _, wSet := r.Properties["width"] _, hSet := r.Properties["height"] + frames, err := frameCount(r.Properties) + if err != nil { + return memo{}, err + } + if wSet || hSet { w, err := dimension(r.Properties, "width", 640) if err != nil { @@ -363,7 +412,7 @@ func chooseSize(r format.Request, label string) (memo, error) { if err := checkJointLimits(w, h); err != nil { return memo{}, err } - m := memo{width: w, height: h, seed: r.Seed, label: label} + m := memo{width: w, height: h, frames: frames, seed: r.Seed, label: label} body, err := encodedBodySize(m) if err != nil { return memo{}, err @@ -374,7 +423,7 @@ func chooseSize(r format.Request, label string) (memo, error) { var smallest memo for _, rung := range sizeLadder { - m := memo{width: rung[0], height: rung[1], seed: r.Seed, label: label} + m := memo{width: rung[0], height: rung[1], frames: frames, seed: r.Seed, label: label} body, err := encodedBodySize(m) if err != nil { return memo{}, err @@ -405,110 +454,6 @@ func dimension(props map[string]string, key string, fallback int) (int, error) { return n, nil } -// paletteSize is how many entries the colour table gets. -// -// It follows the picture rather than being fixed at 256, and the reason is the -// smallest file this format can produce. A GIF writes its colour table in -// full, three bytes an entry, so a fixed 256 entry table puts 768 bytes into a -// one pixel picture and pushes the minimum from about fifty bytes to eight -// hundred. A generator for testing has to be able to make small files. -// -// The table is a power of two because the format says so. Two slots are always -// reserved for the label, and the gradient takes what is left. -func paletteSize(width, height int) int { - // The gradient walks x+y, so a picture cannot show more distinct shades - // than the length of that diagonal. - distinct := width + height - 1 - if distinct > maxGradient { - distinct = maxGradient - } - need := reservedSlots + distinct - // Four is the floor: two label slots plus at least two shades. - size := 4 - for size < need { - size *= 2 - } - if size > 256 { - size = 256 - } - return size -} - -// palettes are built once, when the package loads, and handed out from there. -// -// A color.Palette is a slice of interfaces, so every entry put into one boxes -// a colour onto the heap - 256 objects for a full table, every time a picture -// was built. Measured: 300 allocations to write one file against a ceiling of -// 128. Building them up front moves that cost out of the write entirely, and -// there are only seven possible tables because the size is a power of two. -var palettes = func() map[int]color.Palette { - out := map[int]color.Palette{} - for size := 4; size <= 256; size *= 2 { - out[size] = makePalette(size) - } - return out -}() - -// palette holds the two label colours in fixed slots so the rasteriser lands -// on them exactly rather than on whatever happens to be nearest, and fills the -// rest with a spread the gradient indexes straight into. No quantiser runs, -// which is what keeps the encoding cheap and the bytes the same everywhere. -func buildPalette(size int) color.Palette { - if p, ok := palettes[size]; ok { - return p - } - return makePalette(size) -} - -func makePalette(size int) color.Palette { - p := make(color.Palette, size) - p[labelBackground] = color.RGBA{R: 16, G: 16, B: 16, A: 255} - p[labelInk] = color.RGBA{R: 240, G: 240, B: 240, A: 255} - shades := size - reservedSlots - for i := reservedSlots; i < size; i++ { - // A smooth ramp across whatever room the table has, so the picture - // reads as a gradient the way the other image formats do. An earlier - // version multiplied the index by odd numbers and wrapped, which - // spread the colours nicely and looked like interference on screen - - // and cost size as well, because neighbouring pixels that share - // nothing are what LZW is worst at. - t := 0 - if shades > 1 { - t = (i - reservedSlots) * 255 / (shades - 1) - } - blue := 2 * t - if t > 127 { - blue = 2 * (255 - t) - } - p[i] = color.RGBA{R: uint8(t), G: uint8(255 - t), B: uint8(blue), A: 255} - } - return p -} - -func picture(m memo) *image.Paletted { - size := paletteSize(m.width, m.height) - shades := size - reservedSlots - if shades < 1 { - shades = 1 - } - img := image.NewPaletted(image.Rect(0, 0, m.width, m.height), buildPalette(size)) - off := int(m.seed % 256) - for y := 0; y < m.height; y++ { - row := img.Pix[y*img.Stride : y*img.Stride+m.width] - for x := 0; x < m.width; x++ { - row[x] = byte(reservedSlots + (x+y+off)%shades) - } - } - if m.label != "" && imagelabel.Fits(m.width, len(m.label)) { - imagelabel.Draw(img, m.label) - } - return img -} - -func encode(w io.Writer, m memo) error { - return stdgif.Encode(w, picture(m), &stdgif.Options{NumColors: 256}) -} - func encodedBodySize(m memo) (int64, error) { holder := &tailHolder{w: io.Discard, keep: trailerSize} if err := encode(holder, m); err != nil { @@ -519,8 +464,13 @@ func encodedBodySize(m memo) (int64, error) { // minimumBytes is the smallest file this generator can produce: a one pixel // picture with no label and no comment. +// +// It counts the default number of frames rather than one, because the number +// a format announces has to be a number a plain run will accept, and a plain +// run animates. Asking for frames: 1 reaches something smaller, and that is +// the setting saying so. func minimumBytes() int64 { - body, err := encodedBodySize(memo{width: 1, height: 1}) + body, err := encodedBodySize(memo{width: 1, height: 1, frames: defaultFrames}) if err != nil { return 1 << 62 } diff --git a/internal/format/gif/picture.go b/internal/format/gif/picture.go new file mode 100644 index 0000000..0648966 --- /dev/null +++ b/internal/format/gif/picture.go @@ -0,0 +1,113 @@ +// The pixels and the colour table. +// +// Split out of gif.go on 2026-08-29, when animation pushed that file over the +// line count this project crowds against. The three files are three jobs: the +// container and the size arithmetic, this one, and the frames. +package gif + +import ( + "image" + "image/color" + + "github.com/donislawdev/TestingFilesGenerator/internal/format/imagelabel" +) + +// paletteSize is how many entries the colour table gets. +// +// It follows the picture rather than being fixed at 256, and the reason is the +// smallest file this format can produce. A GIF writes its colour table in +// full, three bytes an entry, so a fixed 256 entry table puts 768 bytes into a +// one pixel picture and pushes the minimum from about fifty bytes to eight +// hundred. A generator for testing has to be able to make small files. +// +// The table is a power of two because the format says so. Two slots are always +// reserved for the label, and the gradient takes what is left. +func paletteSize(width, height int) int { + // The gradient walks x+y, so a picture cannot show more distinct shades + // than the length of that diagonal. + distinct := width + height - 1 + if distinct > maxGradient { + distinct = maxGradient + } + need := reservedSlots + distinct + // Four is the floor: two label slots plus at least two shades. + size := 4 + for size < need { + size *= 2 + } + if size > 256 { + size = 256 + } + return size +} + +// palettes are built once, when the package loads, and handed out from there. +// +// A color.Palette is a slice of interfaces, so every entry put into one boxes +// a colour onto the heap - 256 objects for a full table, every time a picture +// was built. Measured: 300 allocations to write one file against a ceiling of +// 128. Building them up front moves that cost out of the write entirely, and +// there are only seven possible tables because the size is a power of two. +var palettes = func() map[int]color.Palette { + out := map[int]color.Palette{} + for size := 4; size <= 256; size *= 2 { + out[size] = makePalette(size) + } + return out +}() + +// palette holds the two label colours in fixed slots so the rasteriser lands +// on them exactly rather than on whatever happens to be nearest, and fills the +// rest with a spread the gradient indexes straight into. No quantiser runs, +// which is what keeps the encoding cheap and the bytes the same everywhere. +func buildPalette(size int) color.Palette { + if p, ok := palettes[size]; ok { + return p + } + return makePalette(size) +} + +func makePalette(size int) color.Palette { + p := make(color.Palette, size) + p[labelBackground] = color.RGBA{R: 16, G: 16, B: 16, A: 255} + p[labelInk] = color.RGBA{R: 240, G: 240, B: 240, A: 255} + shades := size - reservedSlots + for i := reservedSlots; i < size; i++ { + // A smooth ramp across whatever room the table has, so the picture + // reads as a gradient the way the other image formats do. An earlier + // version multiplied the index by odd numbers and wrapped, which + // spread the colours nicely and looked like interference on screen - + // and cost size as well, because neighbouring pixels that share + // nothing are what LZW is worst at. + t := 0 + if shades > 1 { + t = (i - reservedSlots) * 255 / (shades - 1) + } + blue := 2 * t + if t > 127 { + blue = 2 * (255 - t) + } + p[i] = color.RGBA{R: uint8(t), G: uint8(255 - t), B: uint8(blue), A: 255} + } + return p +} + +func picture(m memo) *image.Paletted { + size := paletteSize(m.width, m.height) + shades := size - reservedSlots + if shades < 1 { + shades = 1 + } + img := image.NewPaletted(image.Rect(0, 0, m.width, m.height), buildPalette(size)) + off := int(m.seed % 256) + for y := 0; y < m.height; y++ { + row := img.Pix[y*img.Stride : y*img.Stride+m.width] + for x := 0; x < m.width; x++ { + row[x] = byte(reservedSlots + (x+y+off)%shades) + } + } + if m.label != "" && imagelabel.Fits(m.width, len(m.label)) { + imagelabel.Draw(img, m.label) + } + return img +} diff --git a/internal/format/webp/picture.go b/internal/format/webp/picture.go new file mode 100644 index 0000000..3752cf8 --- /dev/null +++ b/internal/format/webp/picture.go @@ -0,0 +1,102 @@ +// The pixels: what the picture shows and how a row of it reaches the coder. +// +// Split out of webp.go on 2026-08-29, when the format crossed the line count +// this project crowds against. The three files are three jobs - the container +// and the size arithmetic, this one, and the bitstream in vp8l.go. +package webp + +import ( + "context" + "image" + "image/color" + "io" + + "github.com/donislawdev/TestingFilesGenerator/internal/format/imagelabel" +) + +// writePicture codes the picture straight into w and reports how many bytes it +// handed over. +// +// Nothing but one row and the label band is held: the bit writer drains into w +// as it fills, so a request for gigabytes costs the same memory as a small one. +func writePicture(ctx context.Context, w io.Writer, m memo) (int64, error) { + off := int(m.seed % 256) + band := labelBand(m, off) + bandH := 0 + if band != nil { + bandH = band.Bounds().Dy() + } + + row := make([]byte, m.width*samplesPerPixel) + bw := newBitWriter(w) + var stopped error + writeStream(bw, m.width, m.height, func(y int) []byte { + if y%64 == 0 && stopped == nil { + stopped = interrupted(ctx) + } + if y < bandH { + copyBandRow(row, band, y, m.width) + } else { + fillRow(row, y, m.width, off) + } + return row + }) + written, err := bw.flush() + if stopped != nil { + return written, stopped + } + return written, err +} + +// interrupted reports a cancelled run, and exists so the row callback stays two +// levels deep rather than three. This project counts how many functions nest +// that far and the count is meant to fall. +func interrupted(ctx context.Context) error { + select { + case <-ctx.Done(): + return ctx.Err() + default: + return nil + } +} + +func fillRow(row []byte, y, width, off int) { + for x := 0; x < width; x++ { + row[x*samplesPerPixel] = uint8((x + off) % 256) + row[x*samplesPerPixel+1] = uint8((y + off) % 256) + row[x*samplesPerPixel+2] = uint8((x + y + off) % 256) + } +} + +func labelBand(m memo, off int) *image.RGBA { + if m.label == "" || !imagelabel.Fits(m.width, len(m.label)) { + return nil + } + h := maxBandHeight + if m.height < h { + h = m.height + } + img := image.NewRGBA(image.Rect(0, 0, m.width, h)) + for y := 0; y < h; y++ { + for x := 0; x < m.width; x++ { + img.SetRGBA(x, y, color.RGBA{ + R: uint8((x + off) % 256), + G: uint8((y + off) % 256), + B: uint8((x + y + off) % 256), + A: 255, + }) + } + } + imagelabel.Draw(img, m.label) + return img +} + +func copyBandRow(row []byte, band *image.RGBA, y, width int) { + base := band.PixOffset(0, y) + for x := 0; x < width; x++ { + p := base + x*4 + row[x*samplesPerPixel] = band.Pix[p] + row[x*samplesPerPixel+1] = band.Pix[p+1] + row[x*samplesPerPixel+2] = band.Pix[p+2] + } +} diff --git a/internal/format/webp/vp8l.go b/internal/format/webp/vp8l.go new file mode 100644 index 0000000..c424be2 --- /dev/null +++ b/internal/format/webp/vp8l.go @@ -0,0 +1,203 @@ +// The VP8L bitstream, which is the lossless half of WebP. +// +// x/image/webp decodes and does not encode, so a WebP means writing this +// ourselves. The arrangement here is deliberately the dullest legal one the +// format allows, and the reason is the promise this tool makes rather than any +// property of WebP: a file has to come out at an exact size, so the size has to +// be arithmetic that can be inverted. +// +// - no transforms, no colour cache, no meta Huffman, no backward references +// - green, red and blue each get a complete code in which all 256 literals +// are eight bits long, so the canonical code for a symbol IS that symbol +// and a pixel always costs 24 bits +// - alpha gets a one symbol code, which costs no bits per pixel at all +// +// A real encoder would compress. This one measures out three bytes a pixel on +// purpose, which is what lets a picture GROW to fill the bytes that were asked +// for instead of being a thumbnail followed by filler - the same shape as BMP +// and TIFF. +package webp + +import "io" + +// The order the format reads the nineteen code length symbols in. +var codeLengthOrder = [19]int{17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} + +const ( + // literals is how many symbols a colour channel can take. + literals = 256 + // greenAlphabet carries the literals plus the length prefixes that a + // backward reference would use. We never emit one, but the code still has + // to declare a length for every symbol. + greenAlphabet = literals + 24 + + // codeLengthsUsed reaches index 13 of the order above, which is where the + // symbol meaning "eight bits" sits. Anything shorter cannot say it. + codeLengthsUsed = 14 + + // headerBits is every bit before the first pixel. Written out as a sum so + // that changing any part of the stream above forces this to be changed + // with it, rather than leaving a number nobody can trace. + headerBits = 8 + 14 + 14 + 1 + 3 + // signature, width, height, alpha hint, version + 3 + // no transform, no colour cache, no meta Huffman + (1 + 4 + codeLengthsUsed*3 + 1 + greenAlphabet) + // green + (1 + 4 + codeLengthsUsed*3 + 1 + literals) + // red + (1 + 4 + codeLengthsUsed*3 + 1 + literals) + // blue + (1 + 1 + 1 + 8) + // alpha, one symbol, eight bit + (1 + 1 + 1 + 1) // distance, one symbol, one bit + + // bitsPerPixel is three channels of eight bits. Alpha costs nothing. + bitsPerPixel = 24 +) + +// streamBytes is how long the bitstream is for a picture of this many pixels. +// +// The pixel part is a whole number of bytes, so the header is the only part +// that has to be rounded, and it is rounded once. +func streamBytes(pixels int64) int64 { + return (headerBits+7)/8 + pixels*bitsPerPixel/8 +} + +// bitWriter writes least significant bit first, which is the order VP8L reads. +// +// It writes THROUGH to an io.Writer rather than collecting the file, because a +// generator here may be asked for gigabytes and the regression surface says +// none of them holds the whole file in memory. The first version of this +// package did collect it, with a comment explaining that a Huffman stream is +// not a sequence of whole bytes - which is true and is not a reason. The +// partial byte is one byte of state, not a file. +type bitWriter struct { + to io.Writer + buf []byte + acc uint64 + bits uint + err error + // written counts the bytes handed to the writer, so the caller can check + // the arithmetic that sized the chunk header it already sent. + written int64 +} + +func newBitWriter(to io.Writer) *bitWriter { + return &bitWriter{to: to, buf: make([]byte, 0, 32*1024)} +} + +func (w *bitWriter) write(value uint32, n uint) { + w.acc |= uint64(value&(1<= 8 { + w.buf = append(w.buf, byte(w.acc)) + w.acc >>= 8 + w.bits -= 8 + } + if len(w.buf) >= 32*1024 { + w.drain() + } +} + +func (w *bitWriter) drain() { + if w.err != nil || len(w.buf) == 0 { + return + } + n, err := w.to.Write(w.buf) + w.written += int64(n) + w.buf = w.buf[:0] + w.err = err +} + +// flush empties the buffer and the partial byte, and reports the first error +// any write hit. +func (w *bitWriter) flush() (int64, error) { + if w.bits > 0 { + w.buf = append(w.buf, byte(w.acc)) + w.acc, w.bits = 0, 0 + } + w.drain() + return w.written, w.err +} + +// reverseByte returns the eight bits of v in the opposite order. +// +// Huffman codes travel most significant bit first through a stream that is +// otherwise least significant bit first, the same convention DEFLATE uses. +// With every literal eight bits long the canonical code for symbol s is s, so +// emitting one is emitting s backwards. +func reverseByte(v uint8) uint32 { + var out uint32 + for i := uint(0); i < 8; i++ { + out = out<<1 | uint32(v>>i)&1 + } + return out +} + +// writeFlatCode declares a code in which every literal is eight bits long and +// every symbol above the literals is unused. +// +// The code length alphabet needs two symbols to be a prefix code at all, so it +// carries 0 and 8 with one bit each. Symbol 0 sorts first and gets code 0, +// symbol 8 gets code 1. +func writeFlatCode(w *bitWriter, alphabet int) { + w.write(0, 1) // not a simple code + w.write(codeLengthsUsed-4, 4) + for i := 0; i < codeLengthsUsed; i++ { + length := uint32(0) + if codeLengthOrder[i] == 0 || codeLengthOrder[i] == 8 { + length = 1 + } + w.write(length, 3) + } + w.write(0, 1) // a length is read for every symbol in the alphabet + for s := 0; s < alphabet; s++ { + if s < literals { + w.write(1, 1) // symbol 8 + } else { + w.write(0, 1) // symbol 0, unused + } + } +} + +// writeSingleSymbolCode declares a code carrying one symbol, which then costs +// nothing to emit. +func writeSingleSymbolCode(w *bitWriter, symbol uint32, eightBit bool) { + w.write(1, 1) // simple + w.write(0, 1) // one symbol + if eightBit { + w.write(1, 1) + w.write(symbol, 8) + } else { + w.write(0, 1) + w.write(symbol, 1) + } +} + +// writeStream emits the whole bitstream. row is called once per row and hands +// back width*3 bytes in red, green, blue order. +func writeStream(w *bitWriter, width, height int, row func(y int) []byte) { + w.write(0x2F, 8) + w.write(uint32(width-1), 14) + w.write(uint32(height-1), 14) + w.write(0, 1) // no alpha in use + w.write(0, 3) // version + + w.write(0, 1) // no transform + w.write(0, 1) // no colour cache + w.write(0, 1) // no meta Huffman + + writeFlatCode(w, greenAlphabet) + writeFlatCode(w, literals) + writeFlatCode(w, literals) + writeSingleSymbolCode(w, 255, true) // alpha, opaque everywhere + writeSingleSymbolCode(w, 0, false) // distance, never used + + for y := 0; y < height; y++ { + px := row(y) + for x := 0; x < width; x++ { + // Green first. That is the order the format reads a pixel in, and + // getting it wrong produces a picture that decodes cleanly with + // its channels swapped - which is why the guard compares pixels + // rather than only opening the file. + w.write(reverseByte(px[x*3+1]), 8) + w.write(reverseByte(px[x*3]), 8) + w.write(reverseByte(px[x*3+2]), 8) + } + } +} diff --git a/internal/format/webp/webp.go b/internal/format/webp/webp.go new file mode 100644 index 0000000..9b951fc --- /dev/null +++ b/internal/format/webp/webp.go @@ -0,0 +1,469 @@ +// Package webp generates lossless WebP images. +// +// The third format whose size is arithmetic rather than whatever an encoder +// decides, after BMP and TIFF, and it is built that way on purpose: a request +// for 10 MB is answered with a picture worth 10 MB instead of a thumbnail +// followed by filler nobody can see. The bitstream lives in vp8l.go and says +// there why it compresses nothing. +// +// Written by hand rather than taken from a library, and the reason is +// measured rather than assumed: x/image/webp at v0.43.0 holds decode.go and +// doc.go and nothing else, so the ecosystem offers no encoder to take. Pure Go +// encoders exist outside it, and taking one would have put somebody else's +// release inside the byte stability contract D11 - their next version would +// move the hashes in our users' test suites. See docs/STACK.md section 4.2. +// +// Lossless only. There is no quality setting and no lossy variant, because +// lossy WebP is VP8, which needs a transform, a quantiser and an arithmetic +// coder - out of proportion to what this format has to do here. That is a +// scope decision written down rather than a fidelity level quietly lowered, +// and tfg formats says so. +// +// The padding channel is two stages, and the second exists for a reason worth +// stating: every RIFF chunk block costs an EVEN number of bytes - eight of +// header, the payload, and a pad byte when the payload is odd. A file built +// only out of chunks can therefore only ever have an even length, and half of +// every size anybody could ask for would be unreachable. So the bulk goes in a +// private chunk, and one to seven bytes after the end of the RIFF payload +// carry whatever is left. Measured on six readers (docs/MVP-FORMATS.md section +// 2.13): there is no dead zone at all, which is better than PNG or GIF manage. +package webp + +import ( + "context" + "encoding/binary" + "fmt" + "io" + "math/rand/v2" + "strconv" + + "github.com/donislawdev/TestingFilesGenerator/internal/core" + "github.com/donislawdev/TestingFilesGenerator/internal/format" + "github.com/donislawdev/TestingFilesGenerator/internal/format/imagelabel" +) + +const ( + generatorVersion = "1" + + // riffHeader is "RIFF", the size, and "WEBP". + riffHeader = 12 + // chunkHeader is a four character name and a four byte size. + chunkHeader = 4 + + // paddingName is the private chunk the filler travels in. Unknown chunks + // are what the container sets aside to be ignored, so this is the channel + // the format itself describes. + paddingName = "TFGp" + + // tailMax is how many bytes may sit after the RIFF payload. Seven is + // everything a chunk cannot reach on its own, and no more - the bulk + // belongs inside the container. + tailMax = 7 + + samplesPerPixel = 3 + + minDimension = 1 + maxDimension = 16383 // the format stores each side less one in fourteen bits + + // A RIFF size is a four byte unsigned field. + maxFileBytes = 1<<32 - 1 + + // The tallest label band the rasteriser produces, so the rows carrying the + // label are built once and the rest of the picture streams past. + maxBandHeight = 24 +) + +func init() { + format.Register(format.Descriptor{ + ID: "webp", + Extension: ".webp", + Fidelity: format.FidelityFull, + Determinism: format.DeterminismByte, + + MinBytes: bareBytes(minDimension, minDimension), + + Padding: format.PaddingChannel{ + // Measured against six independent readers - Pillow, ffprobe, + // exiftool, x/image, the Windows Imaging Component and Chromium - + // on files this generator writes, with the pixels compared rather + // than only decoded. + // + // A chunk placed BEFORE the image chunk was tried and refused by + // two of them, so it is not this. A negative control matters here + // more than usual: a truncated WebP is accepted by ffprobe and by + // the Windows Imaging Component, so those two cannot say no about + // this format and the evidence rests on the four that can. + Name: "a private chunk, with the odd byte after the payload", + Where: format.PlacementEnd, + Capacity: maxFileBytes, + }, + Label: format.LabelVisible, + Oracle: "pillow", + Properties: []format.Property{ + { + Name: "width", Kind: format.PropertyInt, + Min: minDimension, Max: maxDimension, Unit: "pixels", + Detail: "How wide the picture is. Left out, the picture is sized to fill the bytes you asked for.", + }, + { + Name: "height", Kind: format.PropertyInt, + Min: minDimension, Max: maxDimension, Unit: "pixels", + Detail: "How tall the picture is. Left out, the picture is sized to fill the bytes you asked for.", + }, + }, + GeneratorVersion: generatorVersion, + Generator: generator{}, + }) +} + +type generator struct{} + +type memo struct { + width, height int + seed uint64 + label string + // chunk is how many bytes of filler the private chunk carries, and tail + // how many sit after the RIFF payload. A chunk of -1 means none at all, + // which is not the same as one carrying nothing. + chunk int64 + tail int64 +} + +// bareBytes is the file with no padding of any kind. +func bareBytes(width, height int) int64 { + stream := streamBytes(int64(width) * int64(height)) + return riffHeader + chunkHeader + 4 + stream + stream%2 +} + +func (generator) Plan(r format.Request) (format.Plan, error) { + label := "" + if r.Label { + label = core.Label("webp", r.Bytes, r.Seed) + } + + w, h, err := chooseSize(r) + if err != nil { + return format.Plan{}, err + } + + bare := bareBytes(w, h) + if r.Bytes < bare { + return format.Plan{}, &format.BelowMinimumError{ + Format: "WEBP", + Requested: r.Bytes, + Minimum: bare, + Reason: fmt.Sprintf( + "a %dx%d picture is %d B of pixels at three bytes each, and the container and the coding tables take another %d B", + w, h, int64(w)*int64(h)*samplesPerPixel, bare-int64(w)*int64(h)*samplesPerPixel), + Hint: fmt.Sprintf("Ask for %d B or more, or set a smaller width and height", bare), + } + } + if r.Bytes > maxFileBytes { + return format.Plan{}, &format.AboveMaximumError{ + Format: "WEBP", + Requested: r.Bytes, + Maximum: maxFileBytes, + Reason: "a WebP declares its length in a four byte field, so the format cannot describe a file this large", + Hint: "Ask for 4 GiB or less, or pick a format with no length field of its own such as gif.", + } + } + + m := memo{width: w, height: h, seed: r.Seed, label: label} + settlePadding(&m, r.Bytes-bare) + + p := format.Plan{ + Bytes: r.Bytes, + Exact: true, + Determinism: format.DeterminismByte, + Properties: map[string]any{ + "width": w, + "height": h, + "compression": "lossless", + "bit_depth": 24, + "animated": false, + "frame_count": 1, + }, + } + + labelled := r.Label && imagelabel.Fits(w, len(label)) + if r.Label && !labelled { + p.Notes = append(p.Notes, format.Note{ + Code: "label_omitted", + Detail: fmt.Sprintf( + "The picture is %d px wide and the label needs more room, so this file carries no visible label. Its name and the manifest still identify it.", + w), + }) + } + p.Properties[format.PropertyLabelEmbedded] = labelled + p.Memo = m + return p, nil +} + +// settlePadding decides how the bytes above the bare picture are spent. +// +// Under eight there is no room for a chunk at all, so they go after the RIFF +// payload. From eight upwards the chunk carries an even payload and the tail +// carries nothing or one byte, which is what makes every size reachable - the +// chunk alone could only ever step in twos. +func settlePadding(m *memo, delta int64) { + m.chunk = -1 + switch { + case delta <= 0: + m.tail = 0 + case delta <= tailMax: + m.tail = delta + default: + m.tail = (delta - chunkHeader - 4) % 2 + m.chunk = delta - chunkHeader - 4 - m.tail + } +} + +// chooseSize settles the picture size. +// +// Named dimensions are used as given. Left out, the picture is grown to fill +// the request, because a pixel always costs three bytes here and the size is +// therefore arithmetic. What is left over goes into the padding. +func chooseSize(r format.Request) (int, int, error) { + _, wSet := r.Properties["width"] + _, hSet := r.Properties["height"] + + if wSet || hSet { + w, err := dimension(r.Properties, "width", 0) + if err != nil { + return 0, 0, err + } + h, err := dimension(r.Properties, "height", 0) + if err != nil { + return 0, 0, err + } + switch { + case wSet && hSet: + return w, h, nil + case wSet: + return w, fillHeight(r.Bytes, w), nil + default: + return fillWidth(r.Bytes, h), h, nil + } + } + + avail := (r.Bytes - bareBytes(minDimension, minDimension)) / samplesPerPixel + if avail < 1 { + return minDimension, minDimension, nil + } + // A square puts the most pixels into the request and is what a person + // expects when they said nothing. + side := int(isqrt(uint64(avail + 1))) + if side < minDimension { + side = minDimension + } + if side > maxDimension { + side = maxDimension + } + for side > minDimension && bareBytes(side, side) > r.Bytes { + side-- + } + return side, side, nil +} + +func fillHeight(bytes int64, width int) int { + h := int64(minDimension) + if width >= minDimension { + room := bytes - bareBytes(width, minDimension) + if room > 0 { + h += room / (int64(width) * samplesPerPixel) + } + } + if h > maxDimension { + h = maxDimension + } + for h > minDimension && bareBytes(width, int(h)) > bytes { + h-- + } + return int(h) +} + +func fillWidth(bytes int64, height int) int { + w := int64(minDimension) + if height >= minDimension { + room := bytes - bareBytes(minDimension, height) + if room > 0 { + w += room / (int64(height) * samplesPerPixel) + } + } + if w > maxDimension { + w = maxDimension + } + for w > minDimension && bareBytes(int(w), height) > bytes { + w-- + } + return int(w) +} + +// isqrt is the whole number square root, worked out rather than taken from +// floating point so the answer is the same on every machine. +func isqrt(n uint64) uint64 { + if n == 0 { + return 0 + } + x := n + y := (x + 1) / 2 + for y < x { + x = y + y = (x + n/x) / 2 + } + return x +} + +func dimension(props map[string]string, key string, fallback int) (int, error) { + raw, ok := props[key] + if !ok || raw == "" { + return fallback, nil + } + n, err := strconv.Atoi(raw) + if err != nil { + return 0, fmt.Errorf("webp: %s must be a whole number of pixels, got %q", key, raw) + } + if n < minDimension || n > maxDimension { + return 0, fmt.Errorf("webp: %s must be between %d and %d pixels, got %d", key, minDimension, maxDimension, n) + } + return n, nil +} + +func (generator) Write(ctx context.Context, w io.Writer, p format.Plan) error { + m, ok := p.Memo.(memo) + if !ok { + return fmt.Errorf("webp: the plan was not produced by this generator") + } + + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + // The length of the bitstream is arithmetic, so the headers can go out + // before a single pixel is coded and nothing has to be held back. + stream := streamBytes(int64(m.width) * int64(m.height)) + body := chunkHeader + 4 + stream + stream%2 + if m.chunk >= 0 { + body += chunkHeader + 4 + m.chunk + } + + if err := writeContainer(w, body, stream); err != nil { + return err + } + + written, err := writePicture(ctx, w, m) + if err != nil { + return err + } + // The chunk header above already promised this number. A mismatch would + // leave a file every reader mistrusts, so it is an error rather than a + // silent short write. + if written != stream { + return fmt.Errorf("webp: the bitstream came to %d B where the header promised %d B", written, stream) + } + if stream%2 == 1 { + if err := writeAll(w, []byte{0}); err != nil { + return err + } + } + + if m.chunk >= 0 { + if err := writeFiller(ctx, w, paddingName, m.seed, m.chunk); err != nil { + return err + } + } + if m.tail > 0 { + return writeAll(w, filler(m.seed+1, m.tail)) + } + return nil +} + +// writeContainer emits everything before the first coded pixel: the RIFF +// header, the form name, and the header of the chunk the bitstream goes in. +// +// It is a function of its own rather than five more error checks inside Write, +// because this project counts how many functions carry a lot of decisions and +// Write was the sixth to reach the band. +func writeContainer(w io.Writer, body, stream int64) error { + for _, part := range []struct { + text string + num uint32 + }{ + {text: "RIFF"}, + {num: uint32(4 + body)}, + {text: "WEBP"}, + {text: "VP8L"}, + {num: uint32(stream)}, + } { + var err error + if part.text != "" { + err = writeAll(w, []byte(part.text)) + } else { + err = writeUint32(w, part.num) + } + if err != nil { + return err + } + } + return nil +} + +// writeFiller emits the padding chunk without holding its payload in memory. +func writeFiller(ctx context.Context, w io.Writer, name string, seed uint64, size int64) error { + if err := writeAll(w, []byte(name)); err != nil { + return err + } + if err := writeUint32(w, uint32(size)); err != nil { + return err + } + rng := core.NewRand(seed) + buf := make([]byte, 32*1024) + for left := size; left > 0; { + n := int64(len(buf)) + if left < n { + n = left + } + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + fillBytes(buf[:n], rng) + if err := writeAll(w, buf[:n]); err != nil { + return err + } + left -= n + } + if size%2 == 1 { + return writeAll(w, []byte{0}) + } + return nil +} + +func filler(seed uint64, size int64) []byte { + out := make([]byte, size) + fillBytes(out, core.NewRand(seed)) + return out +} + +func fillBytes(b []byte, rng *rand.Rand) { + for i := 0; i < len(b); i += 8 { + v := rng.Uint64() + for j := 0; j < 8 && i+j < len(b); j++ { + b[i+j] = byte(v >> (8 * uint(j))) + } + } +} + +func writeUint32(w io.Writer, v uint32) error { + var b [4]byte + binary.LittleEndian.PutUint32(b[:], v) + return writeAll(w, b[:]) +} + +func writeAll(w io.Writer, b []byte) error { + _, err := w.Write(b) + return err +} diff --git a/internal/guard/animation_test.go b/internal/guard/animation_test.go new file mode 100644 index 0000000..15b605d --- /dev/null +++ b/internal/guard/animation_test.go @@ -0,0 +1,230 @@ +package guard + +import ( + "encoding/binary" + "fmt" + "testing" + + "github.com/donislawdev/TestingFilesGenerator/internal/engine" + "github.com/donislawdev/TestingFilesGenerator/internal/format" +) + +// An animated format that writes one frame answers none of the question a +// tester asks of it. +// +// The complaint this guards against was reported from use rather than found +// here: a GIF went into an upload form, came back out as a still picture, and +// nothing about that told anybody whether the site keeps animations, flattens +// them to the first frame, or re-encodes them. A file that cannot tell those +// three apart is not a test file for this format. +// +// The pinned hashes in generatorbytes_test.go already stop the bytes moving. +// They say nothing about what the bytes ARE - a generator that quietly went +// back to writing one frame would drift, get a new hash written down, and pass +// for ever after. This reads the file back and asks whether the animation is +// in it. +// +// Read rather than asked: the structure below is parsed out of the bytes the +// engine wrote, not taken from the plan. Asking the generator to confirm its +// own intention is the shape of guard this project has been caught by before. + +// gifStructure is what a reader finds when it walks a GIF data stream. +type gifStructure struct { + globalTable int + frames int + localTables int + comments int + controls int + loopBlocks int + // lefts is the horizontal offset of each image descriptor, in order. A + // marker that travels puts a different number in each. + lefts []int +} + +// walkGIF parses the block structure. It is deliberately strict: anything it +// does not recognise is an error rather than a block to skip, because a guard +// that shrugs at an unknown byte cannot tell a malformed file from a valid one. +func walkGIF(b []byte) (gifStructure, error) { + var s gifStructure + if len(b) < 13 { + return s, fmt.Errorf("the file is %d B and the screen descriptor alone needs 13 B", len(b)) + } + if string(b[:3]) != "GIF" { + return s, fmt.Errorf("the file does not start with a GIF signature") + } + packed := b[10] + pos := 13 + if packed&0x80 != 0 { + s.globalTable = 1 << ((packed & 0x07) + 1) + pos += 3 * s.globalTable + } + + blocks := func(p int) (int, error) { + for { + if p >= len(b) { + return 0, fmt.Errorf("a sub block chain runs past the end of the file") + } + n := int(b[p]) + p++ + if n == 0 { + return p, nil + } + p += n + } + } + + for { + if pos >= len(b) { + return s, fmt.Errorf("the file ends with no trailer") + } + marker := b[pos] + pos++ + switch marker { + case 0x3B: + if pos != len(b) { + return s, fmt.Errorf("the trailer is at %d and %d B follow it", pos-1, len(b)-pos) + } + return s, nil + case 0x21: + if pos >= len(b) { + return s, fmt.Errorf("an extension has no label") + } + switch b[pos] { + case 0xFE: + s.comments++ + case 0xF9: + s.controls++ + case 0xFF: + s.loopBlocks++ + } + pos++ + next, err := blocks(pos) + if err != nil { + return s, err + } + pos = next + case 0x2C: + if pos+9 > len(b) { + return s, fmt.Errorf("an image descriptor runs past the end of the file") + } + s.frames++ + s.lefts = append(s.lefts, int(binary.LittleEndian.Uint16(b[pos:pos+2]))) + local := b[pos+8] + pos += 9 + if local&0x80 != 0 { + s.localTables++ + pos += 3 * (1 << ((local & 0x07) + 1)) + } + if pos >= len(b) { + return s, fmt.Errorf("an image has no code size") + } + pos++ + next, err := blocks(pos) + if err != nil { + return s, err + } + pos = next + default: + return s, fmt.Errorf("the byte %#02x at offset %d is not a block marker", marker, pos-1) + } + } +} + +func TestAGeneratedGifReallyCarriesAnAnimation(t *testing.T) { + target := engine.Target{ + ID: "g", Format: "gif", Sizes: engine.Uniform(1, 65536), Label: true, + Properties: map[string]string{"width": "64", "height": "64"}, + } + b := generateOne(t, target) + + s, err := walkGIF(b) + if err != nil { + t.Fatalf("reading back the generated GIF: %v", err) + } + + d, err := format.Get("gif") + if err != nil { + t.Fatal(err) + } + want := 0 + for _, p := range d.Properties { + if p.Name == "frames" { + if _, e := fmt.Sscanf(p.Default, "%d", &want); e != nil { + t.Fatalf("the frames setting declares %q as its default and that is not a number", p.Default) + } + } + } + if want < 2 { + t.Fatalf("the frames setting defaults to %d, so a plain run writes a still picture and "+ + "a tester learns nothing about how the system under test treats an animation", want) + } + + if s.frames != want { + t.Errorf("a plain GIF holds %d frame(s) and the format declares %d as its default", + s.frames, want) + } + if s.controls != want { + t.Errorf("%d frame(s) carry %d graphic control block(s) - without one a frame has no delay, "+ + "and a reader is free to show the whole animation in an instant", s.frames, s.controls) + } + if s.loopBlocks != 1 { + t.Errorf("the file carries %d looping block(s), so the animation plays once and a tester "+ + "who blinks sees a still picture", s.loopBlocks) + } + + // The marker has to be somewhere different in every frame. Equal offsets + // would still decode, still animate on paper, and show nothing moving. + seen := map[int]bool{} + for i, left := range s.lefts { + if seen[left] { + t.Errorf("frame %d starts at x=%d and so does an earlier one, so nothing appears to move", i, left) + } + seen[left] = true + } + + // One table for the whole file. Measured on 2026-08-29: without it every + // frame carries its own copy of the palette, and a 12 px square cost 233 B + // instead of 41 B. + if s.globalTable == 0 { + t.Error("the file has no global colour table, so every frame carries its own copy of the palette") + } + if s.localTables != 0 { + t.Errorf("%d frame(s) carry their own colour table on top of the global one", s.localTables) + } + + // The padding channel still has to be there, because the size is exact. + if s.comments != 1 { + t.Errorf("the file carries %d comment block(s) and the padding channel is the comment", s.comments) + } + if len(b) != 65536 { + t.Errorf("the file is %d B where 65536 B was asked for", len(b)) + } +} + +func TestAStillGifIsStillAvailableAndSaysSo(t *testing.T) { + target := engine.Target{ + ID: "g", Format: "gif", Sizes: engine.Uniform(1, 65536), Label: true, + Properties: map[string]string{"width": "64", "height": "64", "frames": "1"}, + } + b := generateOne(t, target) + + s, err := walkGIF(b) + if err != nil { + t.Fatalf("reading back the generated GIF: %v", err) + } + if s.frames != 1 { + t.Errorf("frames: 1 produced %d frame(s)", s.frames) + } + // A single frame goes through the plain encoder, which writes neither a + // control block nor a looping block. Those two absences are what make the + // bytes the same as the ones this package wrote before it could animate, + // and generatorbytes_test.go pins that with the hash the animated case + // used to carry. + if s.controls != 0 || s.loopBlocks != 0 { + t.Errorf("a still GIF carries %d control block(s) and %d looping block(s), so it is not "+ + "the file the plain encoder writes", s.controls, s.loopBlocks) + } + if len(b) != 65536 { + t.Errorf("the file is %d B where 65536 B was asked for", len(b)) + } +} diff --git a/internal/guard/generatorbytes_test.go b/internal/guard/generatorbytes_test.go index 627d8b6..ed0231a 100644 --- a/internal/guard/generatorbytes_test.go +++ b/internal/guard/generatorbytes_test.go @@ -85,8 +85,45 @@ func goldenCases() map[string]engine.Target { // rather than in the code, and this is what closes it. "tiff_64kib_width_only": {ID: "g", Format: "tiff", Sizes: engine.Uniform(1, 65536), Label: true, Properties: map[string]string{"width": "128"}}, + // WebP, pinned from three sides. Its size is arithmetic rather than + // whatever a compressor decides, so a drift here can be a wrong SIZE and + // not only different bytes - the same shape as BMP and TIFF. + "webp_64kib": {ID: "g", Format: "webp", Sizes: engine.Uniform(1, 65536), Label: true, + Properties: map[string]string{"width": "64", "height": "48"}}, + + // One side named, so the other is worked out from the bytes that are + // left. TIFF found by measurement that a case naming both sides and a + // case naming neither both miss that arithmetic entirely. + "webp_64kib_width_only": {ID: "g", Format: "webp", Sizes: engine.Uniform(1, 65536), Label: true, + Properties: map[string]string{"width": "100"}}, + + // An odd size, which is the case the padding was rebuilt for. Every RIFF + // chunk block costs an even number of bytes, so without the tail after + // the payload this request could not be answered at all. + "webp_odd_size": {ID: "g", Format: "webp", Sizes: engine.Uniform(1, 65537), Label: true, + Properties: map[string]string{"width": "64", "height": "48"}}, + "gif_64kib": {ID: "g", Format: "gif", Sizes: engine.Uniform(1, 65536), Label: true, Properties: map[string]string{"width": "64", "height": "64"}}, + + // The still GIF, which is a different encoder rather than the same one + // with a smaller number. frames: 1 takes the plain path and writes no + // control block, no loop block and no second image descriptor, so the + // case above never reaches any of that arithmetic and a change to it + // would move nobody's bytes that anything here measures. + // + // It is also the way back to the bytes this package wrote before it + // could animate, which is a promise the package comment makes. Pinning + // it is what stops that sentence from being a sentence. + "gif_64kib_one_frame": {ID: "g", Format: "gif", Sizes: engine.Uniform(1, 65536), Label: true, + Properties: map[string]string{"width": "64", "height": "64", "frames": "1"}}, + + // Enough frames that the marker lands somewhere different from either + // end, so the arithmetic placing it is measured rather than assumed. + // With three frames a wrong divisor still puts the square inside the + // picture and nothing notices. + "gif_64kib_eight_frames": {ID: "g", Format: "gif", Sizes: engine.Uniform(1, 65536), Label: true, + Properties: map[string]string{"width": "64", "height": "64", "frames": "8"}}, "ico_32kib": {ID: "g", Format: "ico", Sizes: engine.Uniform(1, 32768), Label: true, Properties: map[string]string{"width": "32", "height": "32"}}, diff --git a/internal/guard/layers_test.go b/internal/guard/layers_test.go index 1398aeb..1fe2f1b 100644 --- a/internal/guard/layers_test.go +++ b/internal/guard/layers_test.go @@ -57,6 +57,7 @@ var layer = map[string]int{ "internal/format/zip": 1, "internal/format/targz": 1, "internal/format/tiff": 1, + "internal/format/webp": 1, "internal/format/wav": 1, "internal/recipe": 2, @@ -104,6 +105,7 @@ var sameLayerAllowed = map[string][]string{ "internal/format/zip", "internal/format/targz", "internal/format/tiff", + "internal/format/webp", "internal/format/wav", }, "internal/format/imagelabel": {"internal/format"}, @@ -128,6 +130,7 @@ var sameLayerAllowed = map[string][]string{ "internal/format/zip": {"internal/format", "internal/format/imagelabel"}, "internal/format/targz": {"internal/format"}, "internal/format/tiff": {"internal/format", "internal/format/imagelabel"}, + "internal/format/webp": {"internal/format", "internal/format/imagelabel"}, "internal/format/wav": {"internal/format", "internal/format/imagelabel"}, "internal/preset": {"internal/recipe"}, diff --git a/internal/guard/oracle_test.go b/internal/guard/oracle_test.go index f090c21..b0f88ea 100644 --- a/internal/guard/oracle_test.go +++ b/internal/guard/oracle_test.go @@ -143,7 +143,7 @@ func TestEveryFormatSurvivesItsReferenceTool(t *testing.T) { var structurallyChecked = map[string]bool{ "png": true, "wav": true, "pdf": true, "zip": true, "targz": true, "log": true, "csv": true, "json": true, "xml": true, "svg": true, "html": true, - "bmp": true, "gif": true, "ico": true, "jpg": true, "tiff": true, + "bmp": true, "gif": true, "ico": true, "jpg": true, "tiff": true, "webp": true, "docx": true, "xlsx": true, "pptx": true, // Nothing to check against beyond "these are the bytes we meant", so they // have one layer and it is honest to say so out loud. diff --git a/internal/guard/parity_test.go b/internal/guard/parity_test.go index 895f334..5557e1d 100644 --- a/internal/guard/parity_test.go +++ b/internal/guard/parity_test.go @@ -84,6 +84,7 @@ var reachableFromTheWindow = []string{ "format:svg", "format:targz", "format:tiff", + "format:webp", "format:txt", "format:wav", "format:xml", @@ -101,6 +102,7 @@ var reachableFromTheWindow = []string{ "property:xlsx.columns", "property:xlsx.rows", "property:bmp.width", + "property:gif.frames", "property:gif.height", "property:gif.width", "property:ico.embed", @@ -118,6 +120,8 @@ var reachableFromTheWindow = []string{ "property:targz.entry_size", "property:tiff.height", "property:tiff.width", + "property:webp.height", + "property:webp.width", "property:wav.bit_depth", "property:wav.channels", "property:wav.content", diff --git a/internal/guard/testdata/generator-golden.json b/internal/guard/testdata/generator-golden.json index ffaa4ee..87f6211 100644 --- a/internal/guard/testdata/generator-golden.json +++ b/internal/guard/testdata/generator-golden.json @@ -28,9 +28,19 @@ "measured_on": "2026-08-19" }, "gif_64kib": { + "bytes": 65536, + "sha256": "ff48902dceca395b00db2ede471825f4b224a2ee82063c330022efd60c4158b2", + "measured_on": "2026-08-29" + }, + "gif_64kib_eight_frames": { + "bytes": 65536, + "sha256": "73f49717016a4f1ed53131645974973250c9e1a830704af3a6faf9415cd60c90", + "measured_on": "2026-08-29" + }, + "gif_64kib_one_frame": { "bytes": 65536, "sha256": "659e48806e3abe402148f8246921769d66f3ea9d2f73e94888a3fb7abcf76977", - "measured_on": "2026-08-19" + "measured_on": "2026-08-29" }, "html_8kib": { "bytes": 8192, @@ -115,14 +125,14 @@ "sha256": "172e2e47dda124de9cdbc122b55d25c2fc20de4c78ab963bbf6c7645da247bbd", "measured_on": "2026-08-29" }, - "tiff_64kib_width_only": { + "tiff_64kib": { "bytes": 65536, - "sha256": "c5c38af41809c7e98333fc2a6bdcca36a955f70ab4413dbfde9b9ec4dd3d0b8f", + "sha256": "4d174b53a1603f63b1cd49307f793540190b2d03e26f60b91ca767a93d610340", "measured_on": "2026-08-29" }, - "tiff_64kib": { + "tiff_64kib_width_only": { "bytes": 65536, - "sha256": "4d174b53a1603f63b1cd49307f793540190b2d03e26f60b91ca767a93d610340", + "sha256": "c5c38af41809c7e98333fc2a6bdcca36a955f70ab4413dbfde9b9ec4dd3d0b8f", "measured_on": "2026-08-29" }, "txt_4kib": { @@ -137,6 +147,21 @@ "bytes": 32768, "sha256": "7f1de29ead6fd51cad8675133054f77f760c9f867cc26351260e5340e5201b3a" }, + "webp_64kib": { + "bytes": 65536, + "sha256": "de9034bd6315f0a51fd8fe1b99adfa5719597f7c3d7cdaba1d3b8624754bf89e", + "measured_on": "2026-08-29" + }, + "webp_64kib_width_only": { + "bytes": 65536, + "sha256": "0b56974137d6bd3c5923b2d2dff713efdc93e34c49a59c283ebdceb410541951", + "measured_on": "2026-08-29" + }, + "webp_odd_size": { + "bytes": 65537, + "sha256": "cab2df93e3a618f27b927f7fc3fc99e30787c640c2cb23a14effd5745f19dfff", + "measured_on": "2026-08-29" + }, "xlsx_32kib": { "bytes": 32768, "sha256": "11c19f918b1a996634117117c63e337513db7cadaa1872880482b59abfc7e1da", diff --git a/internal/guard/testdata/screens/generate-menu-hovered.png b/internal/guard/testdata/screens/generate-menu-hovered.png index 791854335c9b89c23e865dd2996bc37f71eb64b9..4777881a5d69663f4bbf1db2ea95bf59b2b68701 100644 GIT binary patch delta 34112 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 Dv;g;! delta 34203 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�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 - + @@ -525,8 +525,8 @@ - - + + diff --git a/internal/guard/testdata/screens/generate-menu-keyed.png b/internal/guard/testdata/screens/generate-menu-keyed.png index 7ef39217f39cf02e815e858fe238f92d338ee1e2..17473510dd1a5ed84003cdcbf4e8e19fecbbb34b 100644 GIT binary patch delta 29187 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 delta 29289 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 X{wcD)KO2o-Bz0BoQ?LL0=hpuKBsh%z diff --git a/internal/guard/testdata/screens/generate-menu-keyed.xml b/internal/guard/testdata/screens/generate-menu-keyed.xml index a33bd5d..75fa16f 100644 --- a/internal/guard/testdata/screens/generate-menu-keyed.xml +++ b/internal/guard/testdata/screens/generate-menu-keyed.xml @@ -428,7 +428,7 @@ - + @@ -525,8 +525,8 @@ - - + + diff --git a/internal/guard/testdata/screens/generate-menu.png b/internal/guard/testdata/screens/generate-menu.png index 27ed2a3f8f8082f8e1556905b286a7baf849ed18..31f4c410b30ea6ac44cfbea53e7f99ed1c9767d9 100644 GIT binary patch delta 20015 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 diff --git a/internal/guard/testdata/screens/generate-menu.xml b/internal/guard/testdata/screens/generate-menu.xml index 108dfff..322493f 100644 --- a/internal/guard/testdata/screens/generate-menu.xml +++ b/internal/guard/testdata/screens/generate-menu.xml @@ -428,7 +428,7 @@ - + @@ -525,8 +525,8 @@ - - + + diff --git a/internal/guard/testdata/screens/preset-menu-setting.png b/internal/guard/testdata/screens/preset-menu-setting.png index 8e0fe3f1c3688214d2f75f15670595584945c59d..e247c136eb9bbd4e813147f284ff01e2080c7355 100644 GIT binary patch delta 20246 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 ThjReU!(dL^IolRmd*AyHPad^8 delta 20211 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 diff --git a/internal/guard/testdata/screens/preset-menu-setting.xml b/internal/guard/testdata/screens/preset-menu-setting.xml index 33d6c61..527b84b 100644 --- a/internal/guard/testdata/screens/preset-menu-setting.xml +++ b/internal/guard/testdata/screens/preset-menu-setting.xml @@ -416,7 +416,7 @@ - + @@ -516,8 +516,8 @@ - - + + diff --git a/internal/guard/textformats_test.go b/internal/guard/textformats_test.go index c667a85..e9f652c 100644 --- a/internal/guard/textformats_test.go +++ b/internal/guard/textformats_test.go @@ -446,7 +446,7 @@ func TestAnSVGDrawingCarriesRealShapes(t *testing.T) { // already written down cannot, by construction, find what is missing from them. var textFormats = []string{"txt", "md", "log", "csv", "json", "xml", "html", "svg"} -var binaryFormats = []string{"bmp", "docx", "gif", "ico", "jpg", "pdf", "png", "pptx", "targz", "tiff", "wav", "xlsx", "zip"} +var binaryFormats = []string{"bmp", "docx", "gif", "ico", "jpg", "pdf", "png", "pptx", "targz", "tiff", "wav", "webp", "xlsx", "zip"} // Every registered format is on exactly one of the two lists above. // diff --git a/internal/gui/parts/filekind.go b/internal/gui/parts/filekind.go index 2c7dd4a..cd2382e 100644 --- a/internal/gui/parts/filekind.go +++ b/internal/gui/parts/filekind.go @@ -93,6 +93,7 @@ var fileKinds = map[string]fileKind{ "png": kindPicture, "svg": kindPicture, "tiff": kindPicture, + "webp": kindPicture, "docx": kindDocument, "pdf": kindDocument, "pptx": kindDocument, diff --git a/internal/oracle/oracle.go b/internal/oracle/oracle.go index aee677b..fffbb79 100644 --- a/internal/oracle/oracle.go +++ b/internal/oracle/oracle.go @@ -351,7 +351,7 @@ func Strict(formatID, path string) Result { func StrictKnows(formatID string) bool { switch formatID { case "png", "wav", "pdf", "zip", "targz", "log", "csv", "json", "xml", "svg", "html", - "bmp", "gif", "ico", "jpg", "tiff", "docx", "xlsx", "pptx": + "bmp", "gif", "ico", "jpg", "tiff", "webp", "docx", "xlsx", "pptx": return true } return false diff --git a/internal/oracle/scripts.go b/internal/oracle/scripts.go index 1945486..cbf9194 100644 --- a/internal/oracle/scripts.go +++ b/internal/oracle/scripts.go @@ -238,14 +238,24 @@ finally: // pillowScript opens the image and forces every pixel to be decoded, so a // truncated or malformed image fails rather than passing on its header alone. +// +// Every frame, not only the first. GIF started writing animations on +// 2026-08-29 and until then this decoded frame one and stopped, which means a +// second frame could have been malformed and the oracle would have said OK. +// The loop costs nothing on a still picture, where there is one frame to walk. const pillowScript = ` import sys try: - from PIL import Image + from PIL import Image, ImageSequence except ImportError: print("SKIP no pillow"); sys.exit(0) im = Image.open(sys.argv[1]) -im.load() -im.convert("RGBA").tobytes() -print("OK", im.format, im.width, im.height) +frames = 0 +for frame in ImageSequence.Iterator(im): + frame.load() + frame.convert("RGBA").tobytes() + frames += 1 +if frames < 1: + print("FAIL the reader found no frame at all"); sys.exit(1) +print("OK", im.format, im.width, im.height, "frames", frames) ` diff --git a/internal/oracle/strict.py b/internal/oracle/strict.py index 4b49db0..c230c17 100644 --- a/internal/oracle/strict.py +++ b/internal/oracle/strict.py @@ -1218,11 +1218,56 @@ def check_pptx(data): "ppt/theme/theme1.xml"], "PowerPoint presentation", "pptx") +def check_webp(data): + if data[:4] != b"RIFF" or data[8:12] != b"WEBP": + fail("the signature is not a WebP signature") + if len(data) < 20: + fail(f"the file is {len(data)} B and the container alone needs 20 B") + + declared = struct.unpack(" len(data): + fail(f"the header says the payload runs to {payload_end} and the file is {len(data)} B") + trailing = len(data) - payload_end + if trailing > 7: + fail(f"{trailing} B sit after the RIFF payload, and only the odd byte belongs there - " + "the bulk of the padding belongs in a chunk") + + pos, image, private, seen = 12, 0, 0, [] + while pos + 8 <= payload_end: + tag = data[pos:pos + 4] + size = struct.unpack(" payload_end: + fail(f"the chunk {tag.decode('latin1')!r} says {size} B and only " + f"{payload_end - pos - 8} B are left") + seen.append(tag.decode("latin1")) + if tag in (b"VP8L", b"VP8 ", b"VP8X"): + image += 1 + if tag == b"VP8L" and data[pos + 8] != 0x2F: + fail("the lossless stream does not start with its signature byte") + else: + private += 1 + pos = end + (size & 1) + + if pos != payload_end: + fail(f"the chunks end at {pos} and the payload ends at {payload_end}") + if image != 1: + fail(f"the file carries {image} image chunks and a still WebP has one") + + ok(f"riff {declared} B, chunks {seen}, {private} private, {trailing} B after the payload") + + CHECKS = {"png": check_png, "wav": check_wav, "pdf": check_pdf, "zip": check_zip, "log": check_log, "csv": check_csv, "json": check_json, "xml": check_xml, "svg": check_svg, "html": check_html, "targz": check_targz, "bmp": check_bmp, "gif": check_gif, "ico": check_ico, "jpg": check_jpg, - "tiff": check_tiff, + "tiff": check_tiff, "webp": check_webp, "docx": check_docx, "xlsx": check_xlsx, "pptx": check_pptx} if __name__ == "__main__": diff --git a/web/public/faq/index.html b/web/public/faq/index.html index 32211bd..dc8aa5e 100644 --- a/web/public/faq/index.html +++ b/web/public/faq/index.html @@ -134,7 +134,7 @@

Frequently asked questions

Which formats are coming next?

-

7z, tiff, webp, mp3 and mp4. 21 formats work end to end today.

+

7z, tiff, webp, mp3 and mp4. 22 formats work end to end today.

@@ -205,7 +205,7 @@

Frequently asked questions

{ "@type": "Question", "name": "Which formats are coming next?", - "acceptedAnswer": { "@type": "Answer", "text": "7z, tiff, webp, mp3 and mp4. 21 formats work end to end today." } + "acceptedAnswer": { "@type": "Answer", "text": "7z, tiff, webp, mp3 and mp4. 22 formats work end to end today." } }, { "@type": "Question", diff --git a/web/public/formats/index.html b/web/public/formats/index.html index 41449da..9030561 100644 --- a/web/public/formats/index.html +++ b/web/public/formats/index.html @@ -3,7 +3,7 @@ -21 Supported File Formats - PDF, DOCX, PNG, ZIP and More +22 Supported File Formats - PDF, DOCX, PNG, ZIP and More @@ -12,7 +12,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -74,7 +74,7 @@
-

21 file formats, every one generated at an exact size

+

22 file formats, every one generated at an exact size

Each of these is a real file of that format. It opens in the software that owns it, and it is exactly the number of bytes you asked for. None of them is padded zeros with an extension @@ -117,7 +117,7 @@

21 file formats, every one generated at an exact size

gif .gif - 41 + 114 full pillow @@ -219,6 +219,13 @@

21 file formats, every one generated at an exact size

full ffprobe + + webp + .webp + 148 + full + pillow + xlsx .xlsx @@ -319,6 +326,11 @@

Settings each format accepts

height 1 - 20000 pixels + + + frames + 1 - 60 + ico width @@ -419,6 +431,16 @@

Settings each format accepts

content noise, silence, sweep, tone + + webp + width + 1 - 16383 pixels + + + + height + 1 - 16383 pixels + xlsx rows diff --git a/web/public/index.html b/web/public/index.html index f7e2926..60de359 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -3,7 +3,7 @@ -Test File Generator for QA - Exact Size, 21 Real Formats +Test File Generator for QA - Exact Size, 22 Real Formats @@ -12,7 +12,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -87,7 +87,7 @@

Generate real test files at any exact size

- PDF, PNG, DOCX, ZIP - 21 formats in all, and every one is a + PDF, PNG, DOCX, ZIP - 22 formats in all, and every one is a real file that opens in the software that owns it, at exactly the size you asked for. Each run also writes down what your application is supposed to do with each file. Command line and desktop window, free and open source, working entirely on your machine. @@ -109,7 +109,7 @@

Generate real test files at any exact size

  • - 21 + 22

    real formats, each one opening in the software that owns it

  • @@ -229,7 +229,7 @@

    Built for a suite that runs unattended

    Ask for 10485761 bytes and get exactly that. A size a format cannot reach is an error with a reason, never a file of the wrong size.

  • -

    21 real formats

    +

    22 real formats

    Not padded zeros with an extension. A generated PNG opens in an image viewer, a DOCX opens in Word, a ZIP extracts. Each one is checked against independent readers before it ships.

  • @@ -310,7 +310,7 @@

    Where this is today

    state of it.

    - Working end to end: 21 formats, recipes, presets, the desktop + Working end to end: 22 formats, recipes, presets, the desktop window, generate, validate, verify, cleanup, boundary sets, archive contents, size ranges, per format settings, manifests and every exit code.

    diff --git a/web/public/pl/faq/index.html b/web/public/pl/faq/index.html index e41f24e..e377f87 100644 --- a/web/public/pl/faq/index.html +++ b/web/public/pl/faq/index.html @@ -135,7 +135,7 @@

    Najczęstsze pytania

    Jakie formaty są następne w kolejce?

    -

    7z, tiff, webp, mp3 i mp4. Formatów działających dziś od początku do końca jest 21.

    +

    7z, tiff, webp, mp3 i mp4. Formatów działających dziś od początku do końca jest 22.

    @@ -206,7 +206,7 @@

    Najczęstsze pytania

    { "@type": "Question", "name": "Jakie formaty są następne w kolejce?", - "acceptedAnswer": { "@type": "Answer", "text": "7z, tiff, webp, mp3 i mp4. Formatów działających dziś od początku do końca jest 21." } + "acceptedAnswer": { "@type": "Answer", "text": "7z, tiff, webp, mp3 i mp4. Formatów działających dziś od początku do końca jest 22." } }, { "@type": "Question", diff --git a/web/public/pl/formaty/index.html b/web/public/pl/formaty/index.html index 370d63d..3d5b1ea 100644 --- a/web/public/pl/formaty/index.html +++ b/web/public/pl/formaty/index.html @@ -3,7 +3,7 @@ -21 formatów plików testowych - PDF, DOCX, PNG, ZIP +22 formatów plików testowych - PDF, DOCX, PNG, ZIP @@ -12,7 +12,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -74,7 +74,7 @@
    -

    21 formatów plików, każdy generowany o dokładnym rozmiarze

    +

    22 formatów plików, każdy generowany o dokładnym rozmiarze

    Każdy z nich to prawdziwy plik tego formatu. Otwiera się w programie, do którego należy, i ma dokładnie tyle bajtów, ile zamówiłeś. Żaden nie jest zerami z doklejonym rozszerzeniem. @@ -116,7 +116,7 @@

    21 formatów plików, każdy generowany o dokładnym rozmiarze

    gif .gif - 41 + 114 full pillow @@ -218,6 +218,13 @@

    21 formatów plików, każdy generowany o dokładnym rozmiarze

    full ffprobe + + webp + .webp + 148 + full + pillow + xlsx .xlsx @@ -319,6 +326,11 @@

    Ustawienia, które przyjmuje każdy format

    height 1 - 20000 pikseli + + + frames + 1 - 60 + ico width @@ -419,6 +431,16 @@

    Ustawienia, które przyjmuje każdy format

    content noise, silence, sweep, tone + + webp + width + 1 - 16383 pikseli + + + + height + 1 - 16383 pikseli + xlsx rows diff --git a/web/public/pl/index.html b/web/public/pl/index.html index 8e904b9..b4a07e9 100644 --- a/web/public/pl/index.html +++ b/web/public/pl/index.html @@ -3,7 +3,7 @@ -Generator plików testowych o zadanym rozmiarze - 21 formatów +Generator plików testowych o zadanym rozmiarze - 22 formatów @@ -12,7 +12,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -87,7 +87,7 @@

    Generuj pliki testowe o zadanym rozmiarze

    - PDF, PNG, DOCX, ZIP - razem 21 formatów, a każdy to + PDF, PNG, DOCX, ZIP - razem 22 formatów, a każdy to prawdziwy plik, który otwiera się w programie, do którego należy, i ma dokładnie taki rozmiar, o jaki poprosisz. Każdy przebieg zapisuje też, co Twoja aplikacja ma z każdym plikiem zrobić. Wiersz poleceń i okno, darmowe i otwarte, działające wyłącznie na Twojej maszynie. @@ -109,7 +109,7 @@

    Generuj pliki testowe o zadanym rozmiarze

    • - 21 + 22

      prawdziwych formatów, każdy otwiera się w programie, do którego należy

    • @@ -229,7 +229,7 @@

      Zbudowane pod zestaw, który chodzi bez nadzoru

      Poproś o 10485761 bajtów i tyle dostaniesz. Rozmiar nieosiągalny dla formatu to błąd z powodem, nigdy plik o innym rozmiarze.

    • -

      21 prawdziwych formatów

      +

      22 prawdziwych formatów

      Nie zera z doklejonym rozszerzeniem. Wygenerowany PNG otwiera się w przeglądarce obrazów, DOCX w Wordzie, a ZIP się rozpakowuje. Każdy format jest sprawdzany niezależnym czytnikiem, zanim trafi do wydania.

    • @@ -310,7 +310,7 @@

      Gdzie to dziś jest

      faktyczny.

      - Działa od początku do końca: 21 formatów, przepisy, presety, + Działa od początku do końca: 22 formatów, przepisy, presety, okno, generate, validate, verify, cleanup, zestawy graniczne, zawartość archiwów, zakresy rozmiarów, ustawienia formatów, manifesty i wszystkie kody wyjścia. diff --git a/web/public/social.html b/web/public/social.html index da40984..f06b7c8 100644 --- a/web/public/social.html +++ b/web/public/social.html @@ -210,12 +210,12 @@

      Real test files.
      At any exact size.

      - 21 formats that open in the software that owns them, plus a manifest + 22 formats that open in the software that owns them, plus a manifest saying how your system should react to each file.

      • exact to the byte
      • -
      • 21 real formats
      • +
      • 22 real formats
      • same bytes every run
      • GUI + CLI
      • built for CI