cmux-next: cap Chief pictures by pixels before decoding, and one GIF cap
Merged
TE
18d ago+239+239+012345678901234567890123456789-37-37-01234567890123456789
Follow-ups from the review of manaflow-ai/cmux#21737 (Chief pictures). Stacked on #21737: the base is leo/next-chief-pictures. After #21737 merges, retarget this to feat-cmux-next.
What changes
- Pixel cap before decoding.
- A still's bytes (20 MB) and pixels (50 megapixels,
STILL_MAX_PIXELS) are checked as soon as it's chosen, before the circle preview shows it. - A small file that would decode to gigabytes is refused with "The image must be 50 megapixels or fewer."
- Before, the preview and
createImageBitmapdecoded at full size, and the 20 MB check ran only on save.
- A still's bytes (20 MB) and pixels (50 megapixels,
- Scaled decode. The renderer asks
createImageBitmapfor the picture already scaled to what the 512 px square needs (resizeWidth/resizeHeight), then crops. It never holds a full-size bitmap. - One GIF cap. The native Chief Settings cap drops from 5 MB to the daemon's 1 MB, matching the Chief sheet. The native error text says 1 MB in all 21 locales.
Strings
chief.picture.pixels, in all 21 locales.home.engine.pictureUnreadable: the size changes from 5 MB to 1 MB in all 21 locales.
Tests
test/home-chief-picture.test.ts: a 30,000 × 30,000 still is refused as pixels without reaching the renderer, plus withinPixels bounds. 4/4 pass. vp fmt, vp lint and tsc are clean on the changed files.
Deferred to phase 5 (home.chiefPictureMotion)
- Animated pictures that follow Reduce Motion and stop while hidden.
squared()flattening a non-square GIF to a still PNG in the tile.
WINDOW
None.
Changelog
none
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Caps Chief picture stills by pixels before they are decoded, and aligns the native GIF cap with the daemon's.
- Stills over 20 MB or 50 megapixels are refused before the preview decodes, with "The image must be 50 megapixels or fewer."
- The renderer asks
createImageBitmapto scale the picture to the 512 px square before cropping, so it never holds a full-size bitmap. - The native Chief Settings GIF cap drops from 5 MB to the daemon's 1 MB, matching the Chief sheet, with the string updated in all 21 locales.