The AVIF times given before, 25 seconds with an alpha channel and 15 without, came from quality 85 and 100 only. Measured again with the runtime image's libvips on one thread at qualities 1 to 100, 4096x4096, 8192x2048 and 2048x8192 random pixels take up to about 34 seconds with an alpha channel and 22 without, the slowest at quality 90 to 99. That is under 40, so the limit stays at 16,777,216 pixels. The doc comments, README.md and TODO.md now give those times. WebP and JPEG XL, measured the same way, stay within the times already given, which now say they hold at any quality. The TODO.md entry moves to the top of Completed Steps. Model: opus-5-5
This commit is contained in:
@@ -397,11 +397,12 @@ takes up to about 1 second as JPEG, 15 as PNG and 16 as GIF, the slowest of 8 or
|
|||||||
16 bits per sample, with or without an alpha channel. The WebP and JPEG XL
|
16 bits per sample, with or without an alpha channel. The WebP and JPEG XL
|
||||||
encoders run below libvips' default effort, and AVIF at the lowest effort govips
|
encoders run below libvips' default effort, and AVIF at the lowest effort govips
|
||||||
can set, so that no encode takes more than 40 seconds of the default
|
can set, so that no encode takes more than 40 seconds of the default
|
||||||
`downstream_timeout` of 60: at quality 85 or 100 and 8 or 16 bits per sample,
|
`downstream_timeout` of 60: at any quality and 8 or 16 bits per sample,
|
||||||
8192x8192 random pixels with an alpha channel take up to about 23 seconds as
|
8192x8192 random pixels with an alpha channel take up to about 23 seconds as
|
||||||
WebP and 27 as JPEG XL, and 4096x4096 or 8192x2048 up to about 25 as AVIF, which
|
WebP and 27 as JPEG XL, and 4096x4096, 8192x2048 or 2048x8192 up to about 34 as
|
||||||
would take about 99 at 8192x8192. Without an alpha channel they take up to about
|
AVIF, which at quality 85 would take about 96 at 8192x8192. Without an alpha
|
||||||
16, 13 and 15 seconds. Decoding such a source adds up to about 11 seconds.
|
channel they take up to about 16, 13 and 22 seconds. Decoding such a source adds
|
||||||
|
up to about 11 seconds.
|
||||||
|
|
||||||
The login form (`POST /`) is limited to 5 attempts per minute per client
|
The login form (`POST /`) is limited to 5 attempts per minute per client
|
||||||
address, counting an IPv6 client by its /64; an attempt over the limit is
|
address, counting an IPv6 client by its /64; an attempt over the limit is
|
||||||
|
|||||||
@@ -30,6 +30,18 @@ P2: security: per-origin rate limiting
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-10-15 a WebP, AVIF or JPEG XL encode at the limits takes at most about 34
|
||||||
|
seconds (closes #272): with one libvips thread, 8192x8192 random pixels with
|
||||||
|
an alpha channel took about 61 seconds to encode as WebP, 96 as AVIF and 81 as
|
||||||
|
JPEG XL, so with the default `downstream_timeout` of 60 seconds such an image
|
||||||
|
was never delivered, yet its encode held a processing slot to the end. WebP is
|
||||||
|
now saved at effort 2 and JPEG XL at effort 4, which take up to about 23 and
|
||||||
|
27 seconds. AVIF was already at the lowest effort govips can set, so an AVIF
|
||||||
|
output of more than 16,777,216 pixels is refused with 400 before anything is
|
||||||
|
decoded; 4096x4096, 8192x2048 or 2048x8192 takes up to about 34 seconds. Each
|
||||||
|
time is the slowest at any quality. Resizing with `fit=cover` already decodes
|
||||||
|
the input, so the output's dimensions are worked out before resizing.
|
||||||
|
`README.md` gives the limit and the new times.
|
||||||
- 2026-10-15 the README says how a source URL with a query is written into an
|
- 2026-10-15 the README says how a source URL with a query is written into an
|
||||||
image URL, and the image route accepts it (closes #255): the query follows the
|
image URL, and the image route accepts it (closes #255): the query follows the
|
||||||
source path after `%3F`. pixa now reads the image URL's path decoded once, so
|
source path after `%3F`. pixa now reads the image URL's path decoded once, so
|
||||||
@@ -76,17 +88,6 @@ P2: security: per-origin rate limiting
|
|||||||
directive is removed, and gosec's new path check is marked as not applying to
|
directive is removed, and gosec's new path check is marked as not applying to
|
||||||
the fixed config file locations. The agent guidance moves unchanged from
|
the fixed config file locations. The agent guidance moves unchanged from
|
||||||
`CLAUDE.md` to a root `AGENTS.md`, where `REPO_POLICIES.md` keeps it.
|
`CLAUDE.md` to a root `AGENTS.md`, where `REPO_POLICIES.md` keeps it.
|
||||||
- 2026-10-15 a WebP, AVIF or JPEG XL encode at the limits takes at most about 27
|
|
||||||
seconds (closes #272): with one libvips thread, 8192x8192 random pixels with
|
|
||||||
an alpha channel took about 61 seconds to encode as WebP, 99 as AVIF and 81 as
|
|
||||||
JPEG XL, so with the default `downstream_timeout` of 60 seconds such an image
|
|
||||||
was never delivered, yet its encode held a processing slot to the end. WebP is
|
|
||||||
now saved at effort 2 and JPEG XL at effort 4, which take up to about 23 and
|
|
||||||
27 seconds. AVIF was already at the lowest effort govips can set, so an AVIF
|
|
||||||
output of more than 16,777,216 pixels is refused with 400 before anything is
|
|
||||||
decoded; 4096x4096 or 8192x2048 takes up to about 25 seconds. Resizing with
|
|
||||||
`fit=cover` already decodes the input, so the output's dimensions are worked
|
|
||||||
out before resizing. `README.md` gives the limit and the new times.
|
|
||||||
- 2026-10-15 the request metrics record any method that is not a standard one as
|
- 2026-10-15 the request metrics record any method that is not a standard one as
|
||||||
`other` (closes #274): their `method` label was each request's method as sent,
|
`other` (closes #274): their `method` label was each request's method as sent,
|
||||||
and Go's HTTP server accepts any method name, so a client sending made-up
|
and Go's HTTP server accepts any method name, so a client sending made-up
|
||||||
|
|||||||
@@ -145,9 +145,10 @@ var ErrOutputTooLarge = errors.New("output image dimensions exceed maximum")
|
|||||||
// MaxAVIFOutputPixels is the most pixels an AVIF output may have, so that an
|
// MaxAVIFOutputPixels is the most pixels an AVIF output may have, so that an
|
||||||
// encode takes at most 40 seconds of the default downstream_timeout of 60
|
// encode takes at most 40 seconds of the default downstream_timeout of 60
|
||||||
// seconds; AVIF is already at the lowest effort govips can set (avifEffort).
|
// seconds; AVIF is already at the lowest effort govips can set (avifEffort).
|
||||||
// With one thread, as pixad runs libvips, saving 4096x4096 or 8192x2048
|
// With one thread, as pixad runs libvips, saving 4096x4096, 8192x2048 or
|
||||||
// random pixels with an alpha channel takes up to about 25 seconds, and
|
// 2048x8192 random pixels with an alpha channel takes up to about 34
|
||||||
// 5120x4096 took 39.
|
// seconds, the slowest at any quality and at 8 or 16 bits per sample, and
|
||||||
|
// 5120x4096 at 8 bits already takes about 36.
|
||||||
const MaxAVIFOutputPixels = 4096 * 4096
|
const MaxAVIFOutputPixels = 4096 * 4096
|
||||||
|
|
||||||
// ErrAVIFOutputTooLarge is returned, before anything is decoded, when an AVIF
|
// ErrAVIFOutputTooLarge is returned, before anything is decoded, when an AVIF
|
||||||
@@ -680,8 +681,8 @@ func exportGIF(img *vips.ImageRef) ([]byte, error) {
|
|||||||
// default of 4 so that an encode takes at most 40 seconds of the default
|
// default of 4 so that an encode takes at most 40 seconds of the default
|
||||||
// downstream_timeout of 60 seconds. With one thread, as pixad runs libvips,
|
// downstream_timeout of 60 seconds. With one thread, as pixad runs libvips,
|
||||||
// saving an 8192x8192 image of random pixels with an alpha channel takes up
|
// saving an 8192x8192 image of random pixels with an alpha channel takes up
|
||||||
// to about 23 seconds at 2, and up to about 16 without one; with an alpha
|
// to about 23 seconds at 2, and up to about 16 without one, at any quality;
|
||||||
// channel, 3 takes about 50 seconds and 4 about 61.
|
// with an alpha channel, 3 takes about 50 seconds and 4 about 61.
|
||||||
const webpEffort = 2
|
const webpEffort = 2
|
||||||
|
|
||||||
// exportWebP encodes img as lossy WebP at quality and webpEffort, without
|
// exportWebP encodes img as lossy WebP at quality and webpEffort, without
|
||||||
@@ -697,12 +698,13 @@ func exportWebP(img *vips.ImageRef, quality int) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// avifEffort is the AVIF effort, from 0 (fastest) to 9; 1 is the lowest
|
// avifEffort is the AVIF effort, from 0 (fastest) to 9; 1 is the lowest
|
||||||
// govips can set. With one thread, as pixad runs libvips, 1 takes about 58
|
// govips can set. With one thread, as pixad runs libvips, 1 takes about 52
|
||||||
// seconds to save an 8192x8192 RGB image of random pixels, and about 99
|
// seconds to save an 8192x8192 RGB image of random pixels at quality 85,
|
||||||
// with an alpha channel, against the default downstream_timeout of 60
|
// and about 96 with an alpha channel, against the default
|
||||||
// seconds, so an AVIF output is held to MaxAVIFOutputPixels. On an image of
|
// downstream_timeout of 60 seconds, so an AVIF output is held to
|
||||||
// milder noise, which 1 saves in about 12 seconds, 2 takes nearly a minute
|
// MaxAVIFOutputPixels. On an image of milder noise, which 1 saves in about
|
||||||
// and libvips' default, 4, takes minutes.
|
// 12 seconds, 2 takes nearly a minute and libvips' default, 4, takes
|
||||||
|
// minutes.
|
||||||
const avifEffort = 1
|
const avifEffort = 1
|
||||||
|
|
||||||
// avifBitdepth is the AVIF bit depth, 8 bits per sample for every image.
|
// avifBitdepth is the AVIF bit depth, 8 bits per sample for every image.
|
||||||
@@ -733,8 +735,8 @@ const jxlResolution = 72 / 25.4
|
|||||||
// libvips' default of 7 so that an encode takes at most 40 seconds of the
|
// libvips' default of 7 so that an encode takes at most 40 seconds of the
|
||||||
// default downstream_timeout of 60 seconds. With one thread, as pixad runs
|
// default downstream_timeout of 60 seconds. With one thread, as pixad runs
|
||||||
// libvips, saving an 8192x8192 image of random pixels with an alpha channel
|
// libvips, saving an 8192x8192 image of random pixels with an alpha channel
|
||||||
// takes up to about 27 seconds at 4, and up to about 13 without one; with an
|
// takes up to about 27 seconds at 4, and up to about 13 without one, at any
|
||||||
// alpha channel, 5 takes about 43 seconds and 7 about 81.
|
// quality; with an alpha channel, 5 takes about 43 seconds and 7 about 81.
|
||||||
const jxlEffort = 4
|
const jxlEffort = 4
|
||||||
|
|
||||||
// exportJXL encodes img as JPEG XL at quality and jxlEffort, without
|
// exportJXL encodes img as JPEG XL at quality and jxlEffort, without
|
||||||
|
|||||||
Reference in New Issue
Block a user