v0.32.0 0617278

webp_decoder.go RawHistoryFolder

1package favicon
2
3import (
4	"errors"
5	"image"
6	"math"
7
8	"github.com/bnema/purego-webp/libwebp"
9)
10
11const (
12	// maxWebPInputBytes bounds untrusted compressed favicon input before it is
13	// handed to libwebp.
14	maxWebPInputBytes = 5 << 20
15	// maxWebPDimension and maxWebPPixels bound the final RGBA allocation.
16	maxWebPDimension = 4096
17	maxWebPPixels    = 4 << 20
18)
19
20var (
21	errWebPInputTooLarge   = errors.New("webp favicon input exceeds size limit")
22	errWebPImageTooLarge   = errors.New("webp favicon dimensions exceed size limit")
23	errWebPInvalidMetadata = errors.New("invalid webp favicon metadata")
24)
25
26// webpRuntime is the narrow infrastructure seam around the dynamically loaded
27// libwebp binding. It deliberately exposes only Go values, keeping backend
28// types out of ports and the domain.
29type webpRuntime interface {
30	Info(data []byte) (width, height int, err error)
31	DecodeRGBAInto(data, pix []byte, stride, width, height int) error
32}
33
34type libwebpRuntime struct{}
35
36func (libwebpRuntime) Info(data []byte) (int, int, error) {
37	width, height, ok, err := libwebp.WebPGetInfo(data)
38	if err != nil {
39		return 0, 0, err
40	}
41	if !ok {
42		return 0, 0, errWebPInvalidMetadata
43	}
44	return width, height, nil
45}
46
47func (libwebpRuntime) DecodeRGBAInto(data, pix []byte, stride, width, height int) error {
48	return libwebp.WebPDecodeRGBAIntoWithInfo(data, pix, stride, width, height)
49}
50
51// webPDecoder owns the failure boundary for the optional libwebp runtime.
52type webPDecoder struct{ runtime webpRuntime }
53
54func newWebPDecoder(runtime webpRuntime) *webPDecoder { return &webPDecoder{runtime: runtime} }
55
56func newDefaultWebPDecoder() *webPDecoder { return newWebPDecoder(libwebpRuntime{}) }
57
58func (d *webPDecoder) Decode(data []byte) (*image.NRGBA, error) {
59	if len(data) == 0 {
60		return nil, errWebPInvalidMetadata
61	}
62	if len(data) > maxWebPInputBytes {
63		return nil, errWebPInputTooLarge
64	}
65	if d == nil || d.runtime == nil {
66		return nil, errors.New("webp decoder unavailable")
67	}
68	width, height, err := d.runtime.Info(data)
69	if err != nil {
70		return nil, err
71	}
72	if width <= 0 || height <= 0 {
73		return nil, errWebPInvalidMetadata
74	}
75	if width > maxWebPDimension || height > maxWebPDimension || width > maxWebPPixels/height {
76		return nil, errWebPImageTooLarge
77	}
78	if width > math.MaxInt/4 {
79		return nil, errWebPImageTooLarge
80	}
81	stride := width * 4
82	if height > math.MaxInt/stride {
83		return nil, errWebPImageTooLarge
84	}
85
86	// Allocate exactly the destination buffer used by libwebp; no native image
87	// buffer or second decoded copy crosses this adapter boundary.
88	img := image.NewNRGBA(image.Rect(0, 0, width, height))
89	if err := d.runtime.DecodeRGBAInto(data, img.Pix, img.Stride, width, height); err != nil {
90		return nil, err
91	}
92	return img, nil
93}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close