Keep each side at 1 or more with fit=outside too
fit=outside works both sides out again from the larger scale, and a side scaled to 1 could come out just under 1 and round down to 0, which libvips refuses: a 49x8192 source at 0x100 and a 49x49 source at 1x1 answered 500. README.md now says what fit=outside does, with the 8192x1 source at 100x0 that comes out at 8192x1, and how a 0 side is worked out from the source's proportions. Model: opus-5-5
This commit is contained in:
@@ -534,8 +534,13 @@ Where:
|
|||||||
- `query` — source query string as under Routes, empty string if none, with `%`
|
- `query` — source query string as under Routes, empty string if none, with `%`
|
||||||
and `:` written as in `path`; neither then holds a `:`, so path `/a:b` with no
|
and `:` written as in `path`; neither then holds a `:`, so path `/a:b` with no
|
||||||
query and path `/a` with query `b:` are signed differently
|
query and path `/a` with query `b:` are signed differently
|
||||||
- `width` — requested width in pixels, `0` for original
|
- `width` — requested width in pixels, or `0`: the width is then worked out from
|
||||||
- `height` — requested height in pixels, `0` for original
|
the source's proportions and the requested height, rounded down but at least
|
||||||
|
1, or is the source's own width when the height is `0` too (the `orig` size)
|
||||||
|
- `height` — requested height in pixels, or `0`: the height is then worked out
|
||||||
|
from the source's proportions and the requested width, rounded down but at
|
||||||
|
least 1, or is the source's own height when the width is `0` too (the `orig`
|
||||||
|
size)
|
||||||
- `format` — output format, one of those listed under Routes, with `original`
|
- `format` — output format, one of those listed under Routes, with `original`
|
||||||
signed as `orig`, `jpg` as `jpeg`, and no format as `jxl`, so a URL with no
|
signed as `orig`, `jpg` as `jpeg`, and no format as `jxl`, so a URL with no
|
||||||
format has the signature of the same URL ending in `.jxl`; `auto` is signed as
|
format has the signature of the same URL ending in `.jxl`; `auto` is signed as
|
||||||
@@ -548,7 +553,10 @@ Where:
|
|||||||
with 400
|
with 400
|
||||||
- `fit` — the URL's `fit` query parameter (cover, contain, fill, inside,
|
- `fit` — the URL's `fit` query parameter (cover, contain, fill, inside,
|
||||||
outside), or `cover` when the URL has no `fit`; a request whose `fit` is
|
outside), or `cover` when the URL has no `fit`; a request whose `fit` is
|
||||||
anything else, an empty `fit=` included, is refused with 400
|
anything else, an empty `fit=` included, is refused with 400. `outside` scales
|
||||||
|
the image to cover the requested size, keeping its proportions, so it can come
|
||||||
|
out larger than that size on one side: an 8192x1 source at `100x0`, which is
|
||||||
|
100x1 by its proportions, comes out at 8192x1
|
||||||
|
|
||||||
The URL's `sig` is the HMAC-SHA256 result in base64url (the URL-safe alphabet of
|
The URL's `sig` is the HMAC-SHA256 result in base64url (the URL-safe alphabet of
|
||||||
RFC 4648) with the trailing `=` padding kept, 44 characters in all. pixa
|
RFC 4648) with the trailing `=` padding kept, 44 characters in all. pixa
|
||||||
|
|||||||
@@ -30,6 +30,20 @@ P2: security: per-origin rate limiting
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-10-16 a size with one side `0` keeps the side computed from the source's
|
||||||
|
proportions at 1 or more (closes #283): it was rounded down, so for a thin
|
||||||
|
source it came out at 0, and libvips then made the size square. An 8192x1
|
||||||
|
source at `100x0` came out at 100x100, and at `1300x0` with `fit=cover` made
|
||||||
|
libvips ask for about 39 GB at once; an 8192x2 source at `100x0` answered 500.
|
||||||
|
`fit=contain` and `fit=inside` work both sides out again from the smaller of
|
||||||
|
the two scales and `fit=outside` from the larger, and each keeps both sides at
|
||||||
|
1 or more too, so a 1x8192 source at `0x100` with `fit=contain`, and a 49x8192
|
||||||
|
source at `0x100` or a 49x49 source at `1x1` with `fit=outside`, no longer
|
||||||
|
answer 500. An 8192x1 source at `1300x0` now comes out at 1300x1, and the
|
||||||
|
process running it alone peaked at about 34 MiB resident. With `fit=outside`
|
||||||
|
the image is scaled to cover the size, so that source at `100x0` comes out at
|
||||||
|
8192x1. `README.md` now says this under Signature Specification, and says how
|
||||||
|
a `0` side is worked out where it said `0` meant the original.
|
||||||
- 2026-10-16 the source URL a request fetches is built with `net/url` from the
|
- 2026-10-16 the source URL a request fetches is built with `net/url` from the
|
||||||
source host, path and query, not joined as text (closes #288). The source
|
source host, path and query, not joined as text (closes #288). The source
|
||||||
path, decoded, is fetched percent-encoded again, so `100%25.png` fetches
|
path, decoded, is fetched percent-encoded again, so `100%25.png` fetches
|
||||||
@@ -43,17 +57,6 @@ P2: security: per-origin rate limiting
|
|||||||
another way, such as with `%2F` in the path, whatever else the path holds, or
|
another way, such as with `%2F` in the path, whatever else the path holds, or
|
||||||
with a user name and password. It also answers 400 for a source path holding a
|
with a user name and password. It also answers 400 for a source path holding a
|
||||||
`..` segment, as `/v1/image/` refuses one.
|
`..` segment, as `/v1/image/` refuses one.
|
||||||
- 2026-10-16 a size with one side `0` keeps the side computed from the source's
|
|
||||||
proportions at 1 or more (closes #283): it was rounded down, so for a thin
|
|
||||||
source it came out at 0, and libvips then made the size square. An 8192x1
|
|
||||||
source at `100x0` came out at 100x100, and at `1300x0` with `fit=cover` made
|
|
||||||
libvips ask for about 39 GB at once; an 8192x2 source at `100x0` answered 500.
|
|
||||||
`fit=contain` and `fit=inside` work both sides out again from the smaller of
|
|
||||||
the two scales, and keep each at 1 or more too, so a 1x8192 source at `0x100`
|
|
||||||
no longer answers 500 there. An 8192x1 source at `1300x0` now comes out at
|
|
||||||
1300x1, and the process running it alone peaked at about 34 MiB resident. With
|
|
||||||
`fit=outside` the image is scaled to cover the size, so that source at `100x0`
|
|
||||||
comes out at 8192x1.
|
|
||||||
- 2026-10-15 a thin source requested with `fit=cover` no longer makes libvips
|
- 2026-10-15 a thin source requested with `fit=cover` no longer makes libvips
|
||||||
build a huge image (closes #282): libvips' thumbnail scaled the whole source
|
build a huge image (closes #282): libvips' thumbnail scaled the whole source
|
||||||
to cover the requested size and copied that into memory before it cut out the
|
to cover the requested size and copied that into memory before it cut out the
|
||||||
|
|||||||
@@ -514,13 +514,16 @@ func (p *ImageProcessor) resize(
|
|||||||
return img.Thumbnail(newW, newH, vips.InterestingNone)
|
return img.Thumbnail(newW, newH, vips.InterestingNone)
|
||||||
|
|
||||||
case FitOutside:
|
case FitOutside:
|
||||||
// Resize so smallest dimension fits, may exceed target on other dimension
|
// Resize so smallest dimension fits, may exceed target on other
|
||||||
|
// dimension. A side scaled to 1 can come out just under 1 in
|
||||||
|
// floating point, as 49 times 1/49 does, and round down to 0, which
|
||||||
|
// libvips refuses as a width, so each side is at least 1.
|
||||||
imgW, imgH := img.Width(), img.Height()
|
imgW, imgH := img.Width(), img.Height()
|
||||||
scaleW := float64(width) / float64(imgW)
|
scaleW := float64(width) / float64(imgW)
|
||||||
scaleH := float64(height) / float64(imgH)
|
scaleH := float64(height) / float64(imgH)
|
||||||
scale := max(scaleW, scaleH)
|
scale := max(scaleW, scaleH)
|
||||||
newW := int(float64(imgW) * scale)
|
newW := max(1, int(float64(imgW)*scale))
|
||||||
newH := int(float64(imgH) * scale)
|
newH := max(1, int(float64(imgH)*scale))
|
||||||
|
|
||||||
// The dimension that exceeds the target is held to the maximum too
|
// The dimension that exceeds the target is held to the maximum too
|
||||||
if newW > MaxOutputDimension || newH > MaxOutputDimension {
|
if newW > MaxOutputDimension || newH > MaxOutputDimension {
|
||||||
|
|||||||
Reference in New Issue
Block a user