detached 513887c

Merge pull request #346 from bnema/feat/webp-favicons

feat(favicon): decode WebP favicons safely
commit
513887caaed76906369620157f1c762fb4b16793
author
bnema · · 2026-07-14 17:26 UTC
committer
GitHub · · 2026-07-14 17:26 UTC
merge of
45b5ee0 + d921a00 · diff against the first parent
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
19 files · +1902 -11
M README.md +3 -2
@@ -134,7 +134,7 @@ Dumber uses Chromium Embedded Framework by default. WebKitGTK is available as a
134134 On Arch Linux, install the CEF runtime with:
135135
136136 ```bash
137-sudo pacman -S cef
137+sudo pacman -S cef libwebp
138138 ```
139139
140140 For hardware video decoding, `cef-vaapi` is also available from the AUR as an optional CEF build.
@@ -179,7 +179,7 @@ CEF OSR frame rate adapts to the active Wayland monitor refresh rate when both `
179179 **Arch Linux:**
180180
181181 ```bash
182-sudo pacman -S cef webkitgtk-6.0 gtk4 gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va
182+sudo pacman -S cef webkitgtk-6.0 gtk4 libwebp gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va
183183 ```
184184
185185 **Debian/Ubuntu:**
@@ -213,6 +213,7 @@ Set `ENV=dev` to use `.dev/dumber/` for config and data instead of XDG paths.
213213 - CEF runtime (default backend)
214214 - WebKitGTK 6.0 development/runtime packages (fallback backend and runtime checks)
215215 - Brotli for compressed systemviews assets
216+- libwebp runtime for WebP favicon decoding (for example `libwebp` on Arch)
216217
217218 Systemviews assets are generated with `go tool templ` and Go's `js/wasm` toolchain; no root Node toolchain is required.
218219
@@ -134,7 +134,7 @@ Dumber uses Chromium Embedded Framework by default. WebKitGTK is available as a
134 On Arch Linux, install the CEF runtime with:134 On Arch Linux, install the CEF runtime with:
135 135
136 ```bash136 ```bash
137-sudo pacman -S cef137+sudo pacman -S cef libwebp
138 ```138 ```
139 139
140 For hardware video decoding, `cef-vaapi` is also available from the AUR as an optional CEF build.140 For hardware video decoding, `cef-vaapi` is also available from the AUR as an optional CEF build.
@@ -179,7 +179,7 @@ CEF OSR frame rate adapts to the active Wayland monitor refresh rate when both `
179 **Arch Linux:**179 **Arch Linux:**
180 180
181 ```bash181 ```bash
182-sudo pacman -S cef webkitgtk-6.0 gtk4 gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va182+sudo pacman -S cef webkitgtk-6.0 gtk4 libwebp gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va
183 ```183 ```
184 184
185 **Debian/Ubuntu:**185 **Debian/Ubuntu:**
@@ -213,6 +213,7 @@ Set `ENV=dev` to use `.dev/dumber/` for config and data instead of XDG paths.
213 - CEF runtime (default backend)213 - CEF runtime (default backend)
214 - WebKitGTK 6.0 development/runtime packages (fallback backend and runtime checks)214 - WebKitGTK 6.0 development/runtime packages (fallback backend and runtime checks)
215 - Brotli for compressed systemviews assets215 - Brotli for compressed systemviews assets
216+- libwebp runtime for WebP favicon decoding (for example `libwebp` on Arch)
216 217
217 Systemviews assets are generated with `go tool templ` and Go's `js/wasm` toolchain; no root Node toolchain is required.218 Systemviews assets are generated with `go tool templ` and Go's `js/wasm` toolchain; no root Node toolchain is required.
218 219
M aur/dumber-browser-bin/.SRCINFO +1 -0
@@ -8,6 +8,7 @@ pkgbase = dumber-browser-bin
88 depends = gtk4
99 depends = cef
1010 depends = webkitgtk-6.0
11+ depends = libwebp
1112 optdepends = gst-plugins-base: Base media codecs
1213 optdepends = gst-plugins-good: Additional media codecs
1314 optdepends = gst-plugins-bad: Extended media codecs
@@ -8,6 +8,7 @@ pkgbase = dumber-browser-bin
8 depends = gtk48 depends = gtk4
9 depends = cef9 depends = cef
10 depends = webkitgtk-6.010 depends = webkitgtk-6.0
11+ depends = libwebp
11 optdepends = gst-plugins-base: Base media codecs12 optdepends = gst-plugins-base: Base media codecs
12 optdepends = gst-plugins-good: Additional media codecs13 optdepends = gst-plugins-good: Additional media codecs
13 optdepends = gst-plugins-bad: Extended media codecs14 optdepends = gst-plugins-bad: Extended media codecs
M aur/dumber-browser-bin/PKGBUILD +1 -1
@@ -6,7 +6,7 @@ pkgdesc="A minimal keyboard-driven browser for tiling WMs"
66 arch=('x86_64')
77 url="https://github.com/bnema/dumber"
88 license=('MIT')
9-depends=('gtk4' 'cef' 'webkitgtk-6.0')
9+depends=('gtk4' 'cef' 'webkitgtk-6.0' 'libwebp')
1010 optdepends=(
1111 'gst-plugins-base: Base media codecs'
1212 'gst-plugins-good: Additional media codecs'
@@ -6,7 +6,7 @@ pkgdesc="A minimal keyboard-driven browser for tiling WMs"
6 arch=('x86_64')6 arch=('x86_64')
7 url="https://github.com/bnema/dumber"7 url="https://github.com/bnema/dumber"
8 license=('MIT')8 license=('MIT')
9-depends=('gtk4' 'cef' 'webkitgtk-6.0')9+depends=('gtk4' 'cef' 'webkitgtk-6.0' 'libwebp')
10 optdepends=(10 optdepends=(
11 'gst-plugins-base: Base media codecs'11 'gst-plugins-base: Base media codecs'
12 'gst-plugins-good: Additional media codecs'12 'gst-plugins-good: Additional media codecs'
M aur/dumber-browser-git/.SRCINFO +1 -0
@@ -11,6 +11,7 @@ pkgbase = dumber-browser-git
1111 depends = gtk4
1212 depends = cef
1313 depends = webkitgtk-6.0
14+ depends = libwebp
1415 optdepends = gst-plugins-base: Base media codecs
1516 optdepends = gst-plugins-good: Additional media codecs
1617 optdepends = gst-plugins-bad: Extended media codecs
@@ -11,6 +11,7 @@ pkgbase = dumber-browser-git
11 depends = gtk411 depends = gtk4
12 depends = cef12 depends = cef
13 depends = webkitgtk-6.013 depends = webkitgtk-6.0
14+ depends = libwebp
14 optdepends = gst-plugins-base: Base media codecs15 optdepends = gst-plugins-base: Base media codecs
15 optdepends = gst-plugins-good: Additional media codecs16 optdepends = gst-plugins-good: Additional media codecs
16 optdepends = gst-plugins-bad: Extended media codecs17 optdepends = gst-plugins-bad: Extended media codecs
M aur/dumber-browser-git/PKGBUILD +1 -1
@@ -7,7 +7,7 @@ arch=('x86_64')
77 url="https://github.com/bnema/dumber"
88 license=('MIT')
99 makedepends=('go>=1.26' 'git' 'brotli')
10-depends=('gtk4' 'cef' 'webkitgtk-6.0')
10+depends=('gtk4' 'cef' 'webkitgtk-6.0' 'libwebp')
1111 optdepends=(
1212 'gst-plugins-base: Base media codecs'
1313 'gst-plugins-good: Additional media codecs'
@@ -7,7 +7,7 @@ arch=('x86_64')
7 url="https://github.com/bnema/dumber"7 url="https://github.com/bnema/dumber"
8 license=('MIT')8 license=('MIT')
9 makedepends=('go>=1.26' 'git' 'brotli')9 makedepends=('go>=1.26' 'git' 'brotli')
10-depends=('gtk4' 'cef' 'webkitgtk-6.0')10+depends=('gtk4' 'cef' 'webkitgtk-6.0' 'libwebp')
11 optdepends=(11 optdepends=(
12 'gst-plugins-base: Base media codecs'12 'gst-plugins-base: Base media codecs'
13 'gst-plugins-good: Additional media codecs'13 'gst-plugins-good: Additional media codecs'
M flatpak/dev.bnema.Dumber.yml +1 -0
@@ -1,6 +1,7 @@
11 id: dev.bnema.Dumber
22 runtime: org.gnome.Platform
33 runtime-version: '49'
4+# org.gnome.Platform provides libwebp at runtime for purego WebP favicon decoding.
45 sdk: org.gnome.Sdk
56 command: dumber
67
@@ -1,6 +1,7 @@
1 id: dev.bnema.Dumber1 id: dev.bnema.Dumber
2 runtime: org.gnome.Platform2 runtime: org.gnome.Platform
3 runtime-version: '49'3 runtime-version: '49'
4+# org.gnome.Platform provides libwebp at runtime for purego WebP favicon decoding.
4 sdk: org.gnome.Sdk5 sdk: org.gnome.Sdk
5 command: dumber6 command: dumber
6 7
M go.mod +1 -0
@@ -10,6 +10,7 @@ require (
1010 github.com/bnema/purego-cef2gtk v0.8.4-0.20260714160309-bbd397409ebe
1111 github.com/bnema/purego-pipewire v0.1.5-0.20260714124450-6504b9cdf02a
1212 github.com/bnema/purego-sqlite v0.1.4-0.20260714131321-3614fe683b9c
13+ github.com/bnema/purego-webp v0.2.1-0.20260714152238-7bc9c402fdf6
1314 github.com/bnema/puregotk v0.7.1-0.20260714170452-0b6b9b901234
1415 github.com/charmbracelet/bubbles v1.0.0
1516 github.com/charmbracelet/bubbletea v1.3.10
@@ -10,6 +10,7 @@ require (
10 github.com/bnema/purego-cef2gtk v0.8.4-0.20260714160309-bbd397409ebe10 github.com/bnema/purego-cef2gtk v0.8.4-0.20260714160309-bbd397409ebe
11 github.com/bnema/purego-pipewire v0.1.5-0.20260714124450-6504b9cdf02a11 github.com/bnema/purego-pipewire v0.1.5-0.20260714124450-6504b9cdf02a
12 github.com/bnema/purego-sqlite v0.1.4-0.20260714131321-3614fe683b9c12 github.com/bnema/purego-sqlite v0.1.4-0.20260714131321-3614fe683b9c
13+ github.com/bnema/purego-webp v0.2.1-0.20260714152238-7bc9c402fdf6
13 github.com/bnema/puregotk v0.7.1-0.20260714170452-0b6b9b90123414 github.com/bnema/puregotk v0.7.1-0.20260714170452-0b6b9b901234
14 github.com/charmbracelet/bubbles v1.0.015 github.com/charmbracelet/bubbles v1.0.0
15 github.com/charmbracelet/bubbletea v1.3.1016 github.com/charmbracelet/bubbletea v1.3.10
M go.sum +2 -0 generated file: collapsed
M internal/application/usecase/favicon_test.go +19 -0
@@ -404,6 +404,25 @@ func TestFaviconObserveConversionErrorDoesNotMutateExistingAssets(t *testing.T)
404404 }
405405 }
406406
407+func TestFaviconObserveUnavailableWebPPreservesCachedAssets(t *testing.T) {
408+ fx := newFaviconFixture(t)
409+ fx.seedOriginal([]byte("old"))
410+ fx.blobs.png["example.com"] = []byte("old-png")
411+ fx.blobs.sized["example.com"] = map[int][]byte{32: []byte("old-32")}
412+ fx.converter.errByContentType = map[string]error{"image/webp": ErrFaviconMiss}
413+
414+ _, err := fx.uc.Observe(context.Background(), "https://example.com", "https://example.com/favicon.webp", []byte("webp"), favicon.SourceEngine, "image/webp")
415+ if !errors.Is(err, ErrFaviconMiss) {
416+ t.Fatalf("Observe err=%v, want favicon miss", err)
417+ }
418+ if string(fx.blobs.original["example.com"]) != "old" || string(fx.blobs.png["example.com"]) != "old-png" || string(fx.blobs.sized["example.com"][32]) != "old-32" {
419+ t.Fatalf("cached assets changed after unavailable WebP decoder")
420+ }
421+ if fx.blobs.writeOriginals != 0 || fx.blobs.removeDerived != 0 || fx.invalidators.calls != 0 {
422+ t.Fatalf("unavailable decoder mutated cache: writes=%d removes=%d invalidations=%d", fx.blobs.writeOriginals, fx.blobs.removeDerived, fx.invalidators.calls)
423+ }
424+}
425+
407426 func TestFaviconEnsureSizedPropagatesReadSizedErrors(t *testing.T) {
408427 fx := newFaviconFixture(t)
409428 fx.seedOriginal([]byte("old"))
@@ -404,6 +404,25 @@ func TestFaviconObserveConversionErrorDoesNotMutateExistingAssets(t *testing.T)
404 }404 }
405 }405 }
406 406
407+func TestFaviconObserveUnavailableWebPPreservesCachedAssets(t *testing.T) {
408+ fx := newFaviconFixture(t)
409+ fx.seedOriginal([]byte("old"))
410+ fx.blobs.png["example.com"] = []byte("old-png")
411+ fx.blobs.sized["example.com"] = map[int][]byte{32: []byte("old-32")}
412+ fx.converter.errByContentType = map[string]error{"image/webp": ErrFaviconMiss}
413+
414+ _, err := fx.uc.Observe(context.Background(), "https://example.com", "https://example.com/favicon.webp", []byte("webp"), favicon.SourceEngine, "image/webp")
415+ if !errors.Is(err, ErrFaviconMiss) {
416+ t.Fatalf("Observe err=%v, want favicon miss", err)
417+ }
418+ if string(fx.blobs.original["example.com"]) != "old" || string(fx.blobs.png["example.com"]) != "old-png" || string(fx.blobs.sized["example.com"][32]) != "old-32" {
419+ t.Fatalf("cached assets changed after unavailable WebP decoder")
420+ }
421+ if fx.blobs.writeOriginals != 0 || fx.blobs.removeDerived != 0 || fx.invalidators.calls != 0 {
422+ t.Fatalf("unavailable decoder mutated cache: writes=%d removes=%d invalidations=%d", fx.blobs.writeOriginals, fx.blobs.removeDerived, fx.invalidators.calls)
423+ }
424+}
425+
407 func TestFaviconEnsureSizedPropagatesReadSizedErrors(t *testing.T) {426 func TestFaviconEnsureSizedPropagatesReadSizedErrors(t *testing.T) {
408 fx := newFaviconFixture(t)427 fx := newFaviconFixture(t)
409 fx.seedOriginal([]byte("old"))428 fx.seedOriginal([]byte("old"))
M internal/infrastructure/favicon/converter.go +19 -7
@@ -16,17 +16,25 @@ import (
1616 )
1717
1818 // ImageConverter converts safe favicon image formats into normalized PNGs.
19-type ImageConverter struct{}
19+type ImageConverter struct {
20+ webp *webPDecoder
21+}
22+
23+func NewImageConverter() *ImageConverter { return &ImageConverter{webp: newDefaultWebPDecoder()} }
2024
21-func NewImageConverter() *ImageConverter { return &ImageConverter{} }
25+// newImageConverterWithWebPRuntime provides an infrastructure test seam while
26+// application ports remain independent of the libwebp implementation.
27+func newImageConverterWithWebPRuntime(runtime webpRuntime) *ImageConverter {
28+ return &ImageConverter{webp: newWebPDecoder(runtime)}
29+}
2230
23-func (*ImageConverter) Convert(ctx context.Context, original []byte, contentType string, sizes []int) (*appport.ConvertedFavicon, error) {
31+func (c *ImageConverter) Convert(ctx context.Context, original []byte, contentType string, sizes []int) (*appport.ConvertedFavicon, error) {
2432 _ = ctx
2533 if len(original) == 0 {
2634 return nil, fmt.Errorf("%w: empty image", appport.ErrFaviconMiss)
2735 }
2836
29- img, err := decodeFaviconImage(original, normalizeContentType(contentType))
37+ img, err := decodeFaviconImage(original, normalizeContentType(contentType), c.webp)
3038 if err != nil {
3139 return nil, err
3240 }
@@ -48,7 +56,7 @@ func (*ImageConverter) Convert(ctx context.Context, original []byte, contentType
4856 return out, nil
4957 }
5058
51-func decodeFaviconImage(data []byte, ct string) (image.Image, error) {
59+func decodeFaviconImage(data []byte, ct string, webp *webPDecoder) (image.Image, error) {
5260 switch ct {
5361 case "image/svg+xml":
5462 return nil, fmt.Errorf("%w: svg favicon conversion is disabled", appport.ErrFaviconMiss)
@@ -59,9 +67,13 @@ func decodeFaviconImage(data []byte, ct string) (image.Image, error) {
5967 }
6068 return img, nil
6169 case "image/webp":
62- return nil, fmt.Errorf("%w: webp favicon conversion is disabled", appport.ErrFaviconMiss)
70+ img, err := webp.Decode(data)
71+ if err != nil {
72+ return nil, fmt.Errorf("%w: decode webp favicon: %w", appport.ErrFaviconMiss, err)
73+ }
74+ return img, nil
6375 }
64- if ct != "" && ct != "image/png" && ct != "image/jpeg" && ct != "image/gif" && ct != "image/webp" {
76+ if ct != "" && ct != "image/png" && ct != "image/jpeg" && ct != "image/gif" {
6577 return nil, fmt.Errorf("%w: unsupported favicon content type %s", appport.ErrFaviconMiss, ct)
6678 }
6779 img, _, err := image.Decode(bytes.NewReader(data))
@@ -16,17 +16,25 @@ import (
16 )16 )
17 17
18 // ImageConverter converts safe favicon image formats into normalized PNGs.18 // ImageConverter converts safe favicon image formats into normalized PNGs.
19-type ImageConverter struct{}19+type ImageConverter struct {
20+ webp *webPDecoder
21+}
22+
23+func NewImageConverter() *ImageConverter { return &ImageConverter{webp: newDefaultWebPDecoder()} }
20 24
21-func NewImageConverter() *ImageConverter { return &ImageConverter{} }25+// newImageConverterWithWebPRuntime provides an infrastructure test seam while
26+// application ports remain independent of the libwebp implementation.
27+func newImageConverterWithWebPRuntime(runtime webpRuntime) *ImageConverter {
28+ return &ImageConverter{webp: newWebPDecoder(runtime)}
29+}
22 30
23-func (*ImageConverter) Convert(ctx context.Context, original []byte, contentType string, sizes []int) (*appport.ConvertedFavicon, error) {31+func (c *ImageConverter) Convert(ctx context.Context, original []byte, contentType string, sizes []int) (*appport.ConvertedFavicon, error) {
24 _ = ctx32 _ = ctx
25 if len(original) == 0 {33 if len(original) == 0 {
26 return nil, fmt.Errorf("%w: empty image", appport.ErrFaviconMiss)34 return nil, fmt.Errorf("%w: empty image", appport.ErrFaviconMiss)
27 }35 }
28 36
29- img, err := decodeFaviconImage(original, normalizeContentType(contentType))37+ img, err := decodeFaviconImage(original, normalizeContentType(contentType), c.webp)
30 if err != nil {38 if err != nil {
31 return nil, err39 return nil, err
32 }40 }
@@ -48,7 +56,7 @@ func (*ImageConverter) Convert(ctx context.Context, original []byte, contentType
48 return out, nil56 return out, nil
49 }57 }
50 58
51-func decodeFaviconImage(data []byte, ct string) (image.Image, error) {59+func decodeFaviconImage(data []byte, ct string, webp *webPDecoder) (image.Image, error) {
52 switch ct {60 switch ct {
53 case "image/svg+xml":61 case "image/svg+xml":
54 return nil, fmt.Errorf("%w: svg favicon conversion is disabled", appport.ErrFaviconMiss)62 return nil, fmt.Errorf("%w: svg favicon conversion is disabled", appport.ErrFaviconMiss)
@@ -59,9 +67,13 @@ func decodeFaviconImage(data []byte, ct string) (image.Image, error) {
59 }67 }
60 return img, nil68 return img, nil
61 case "image/webp":69 case "image/webp":
62- return nil, fmt.Errorf("%w: webp favicon conversion is disabled", appport.ErrFaviconMiss)70+ img, err := webp.Decode(data)
71+ if err != nil {
72+ return nil, fmt.Errorf("%w: decode webp favicon: %w", appport.ErrFaviconMiss, err)
73+ }
74+ return img, nil
63 }75 }
64- if ct != "" && ct != "image/png" && ct != "image/jpeg" && ct != "image/gif" && ct != "image/webp" {76+ if ct != "" && ct != "image/png" && ct != "image/jpeg" && ct != "image/gif" {
65 return nil, fmt.Errorf("%w: unsupported favicon content type %s", appport.ErrFaviconMiss, ct)77 return nil, fmt.Errorf("%w: unsupported favicon content type %s", appport.ErrFaviconMiss, ct)
66 }78 }
67 img, _, err := image.Decode(bytes.NewReader(data))79 img, _, err := image.Decode(bytes.NewReader(data))
A internal/infrastructure/favicon/testdata/alpha.webp +0 -0 binary file: no text diff

binary file: no text diff

A internal/infrastructure/favicon/webp_decoder.go +93 -0
@@ -0,0 +1,93 @@
1+package favicon
2+
3+import (
4+ "errors"
5+ "image"
6+ "math"
7+
8+ "github.com/bnema/purego-webp/libwebp"
9+)
10+
11+const (
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+
20+var (
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.
29+type webpRuntime interface {
30+ Info(data []byte) (width, height int, err error)
31+ DecodeRGBAInto(data, pix []byte, stride, width, height int) error
32+}
33+
34+type libwebpRuntime struct{}
35+
36+func (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+
47+func (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.
52+type webPDecoder struct{ runtime webpRuntime }
53+
54+func newWebPDecoder(runtime webpRuntime) *webPDecoder { return &webPDecoder{runtime: runtime} }
55+
56+func newDefaultWebPDecoder() *webPDecoder { return newWebPDecoder(libwebpRuntime{}) }
57+
58+func (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+}
@@ -0,0 +1,93 @@
1+package favicon
2+
3+import (
4+ "errors"
5+ "image"
6+ "math"
7+
8+ "github.com/bnema/purego-webp/libwebp"
9+)
10+
11+const (
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+
20+var (
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.
29+type webpRuntime interface {
30+ Info(data []byte) (width, height int, err error)
31+ DecodeRGBAInto(data, pix []byte, stride, width, height int) error
32+}
33+
34+type libwebpRuntime struct{}
35+
36+func (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+
47+func (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.
52+type webPDecoder struct{ runtime webpRuntime }
53+
54+func newWebPDecoder(runtime webpRuntime) *webPDecoder { return &webPDecoder{runtime: runtime} }
55+
56+func newDefaultWebPDecoder() *webPDecoder { return newWebPDecoder(libwebpRuntime{}) }
57+
58+func (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+}
A internal/infrastructure/favicon/webp_decoder_test.go +92 -0
@@ -0,0 +1,92 @@
1+package favicon
2+
3+import (
4+ "bytes"
5+ "context"
6+ "errors"
7+ "image"
8+ "image/color"
9+ "image/png"
10+ "os"
11+ "testing"
12+
13+ appport "github.com/bnema/dumber/internal/application/port"
14+)
15+
16+func TestConverterWebPConvertsAlphaFixture(t *testing.T) {
17+ data, err := os.ReadFile("testdata/alpha.webp")
18+ if err != nil {
19+ t.Fatal(err)
20+ }
21+ conv := NewImageConverter()
22+ out, err := conv.Convert(context.Background(), data, "image/webp", []int{32})
23+ if err != nil {
24+ t.Fatal(err)
25+ }
26+ img, err := png.Decode(bytes.NewReader(out.PNG))
27+ if err != nil {
28+ t.Fatal(err)
29+ }
30+ if got := color.NRGBAModel.Convert(img.At(0, 0)).(color.NRGBA); got.A != 64 || got.R != 255 {
31+ t.Fatalf("alpha pixel = %#v, want red alpha 64", got)
32+ }
33+ if sized, err := png.Decode(bytes.NewReader(out.SizedPNG[32])); err != nil || sized.Bounds() != image.Rect(0, 0, 32, 32) {
34+ t.Fatalf("sized WebP = %v, %v", sized.Bounds(), err)
35+ }
36+}
37+
38+func TestConverterWebPFailuresAreFaviconMisses(t *testing.T) {
39+ for _, tc := range []struct {
40+ name string
41+ data []byte
42+ dec webpRuntime
43+ }{
44+ {name: "truncated", data: []byte("RIFF\x04\x00\x00\x00WEBPVP8 "), dec: &fakeWebPRuntime{infoErr: errors.New("truncated")}},
45+ {name: "unavailable", data: []byte("webp"), dec: &fakeWebPRuntime{infoErr: errors.New("libwebp unavailable")}},
46+ } {
47+ t.Run(tc.name, func(t *testing.T) {
48+ conv := newImageConverterWithWebPRuntime(tc.dec)
49+ if _, err := conv.Convert(context.Background(), tc.data, "image/webp", nil); !errors.Is(err, appport.ErrFaviconMiss) {
50+ t.Fatalf("err = %v, want favicon miss", err)
51+ }
52+ })
53+ }
54+}
55+
56+func TestWebPDecoderRejectsInputAndDecodedLimitsBeforeAllocation(t *testing.T) {
57+ for _, tc := range []struct {
58+ name string
59+ data []byte
60+ width, height int
61+ }{
62+ {name: "input", data: bytes.Repeat([]byte("x"), maxWebPInputBytes+1), width: 1, height: 1},
63+ {name: "dimension", data: []byte("webp"), width: maxWebPDimension + 1, height: 1},
64+ {name: "pixels", data: []byte("webp"), width: maxWebPDimension, height: maxWebPDimension},
65+ } {
66+ t.Run(tc.name, func(t *testing.T) {
67+ runtime := &fakeWebPRuntime{width: tc.width, height: tc.height}
68+ _, err := newWebPDecoder(runtime).Decode(tc.data)
69+ if err == nil {
70+ t.Fatal("Decode succeeded")
71+ }
72+ if runtime.decodeCalls != 0 {
73+ t.Fatalf("decode calls = %d, want no allocation/decode", runtime.decodeCalls)
74+ }
75+ })
76+ }
77+}
78+
79+type fakeWebPRuntime struct {
80+ width, height int
81+ infoErr error
82+ decodeCalls int
83+}
84+
85+func (r *fakeWebPRuntime) Info(_ []byte) (int, int, error) { return r.width, r.height, r.infoErr }
86+func (r *fakeWebPRuntime) DecodeRGBAInto(_, pix []byte, _, _, _ int) error {
87+ r.decodeCalls++
88+ for i := range pix {
89+ pix[i] = 0xff
90+ }
91+ return nil
92+}
@@ -0,0 +1,92 @@
1+package favicon
2+
3+import (
4+ "bytes"
5+ "context"
6+ "errors"
7+ "image"
8+ "image/color"
9+ "image/png"
10+ "os"
11+ "testing"
12+
13+ appport "github.com/bnema/dumber/internal/application/port"
14+)
15+
16+func TestConverterWebPConvertsAlphaFixture(t *testing.T) {
17+ data, err := os.ReadFile("testdata/alpha.webp")
18+ if err != nil {
19+ t.Fatal(err)
20+ }
21+ conv := NewImageConverter()
22+ out, err := conv.Convert(context.Background(), data, "image/webp", []int{32})
23+ if err != nil {
24+ t.Fatal(err)
25+ }
26+ img, err := png.Decode(bytes.NewReader(out.PNG))
27+ if err != nil {
28+ t.Fatal(err)
29+ }
30+ if got := color.NRGBAModel.Convert(img.At(0, 0)).(color.NRGBA); got.A != 64 || got.R != 255 {
31+ t.Fatalf("alpha pixel = %#v, want red alpha 64", got)
32+ }
33+ if sized, err := png.Decode(bytes.NewReader(out.SizedPNG[32])); err != nil || sized.Bounds() != image.Rect(0, 0, 32, 32) {
34+ t.Fatalf("sized WebP = %v, %v", sized.Bounds(), err)
35+ }
36+}
37+
38+func TestConverterWebPFailuresAreFaviconMisses(t *testing.T) {
39+ for _, tc := range []struct {
40+ name string
41+ data []byte
42+ dec webpRuntime
43+ }{
44+ {name: "truncated", data: []byte("RIFF\x04\x00\x00\x00WEBPVP8 "), dec: &fakeWebPRuntime{infoErr: errors.New("truncated")}},
45+ {name: "unavailable", data: []byte("webp"), dec: &fakeWebPRuntime{infoErr: errors.New("libwebp unavailable")}},
46+ } {
47+ t.Run(tc.name, func(t *testing.T) {
48+ conv := newImageConverterWithWebPRuntime(tc.dec)
49+ if _, err := conv.Convert(context.Background(), tc.data, "image/webp", nil); !errors.Is(err, appport.ErrFaviconMiss) {
50+ t.Fatalf("err = %v, want favicon miss", err)
51+ }
52+ })
53+ }
54+}
55+
56+func TestWebPDecoderRejectsInputAndDecodedLimitsBeforeAllocation(t *testing.T) {
57+ for _, tc := range []struct {
58+ name string
59+ data []byte
60+ width, height int
61+ }{
62+ {name: "input", data: bytes.Repeat([]byte("x"), maxWebPInputBytes+1), width: 1, height: 1},
63+ {name: "dimension", data: []byte("webp"), width: maxWebPDimension + 1, height: 1},
64+ {name: "pixels", data: []byte("webp"), width: maxWebPDimension, height: maxWebPDimension},
65+ } {
66+ t.Run(tc.name, func(t *testing.T) {
67+ runtime := &fakeWebPRuntime{width: tc.width, height: tc.height}
68+ _, err := newWebPDecoder(runtime).Decode(tc.data)
69+ if err == nil {
70+ t.Fatal("Decode succeeded")
71+ }
72+ if runtime.decodeCalls != 0 {
73+ t.Fatalf("decode calls = %d, want no allocation/decode", runtime.decodeCalls)
74+ }
75+ })
76+ }
77+}
78+
79+type fakeWebPRuntime struct {
80+ width, height int
81+ infoErr error
82+ decodeCalls int
83+}
84+
85+func (r *fakeWebPRuntime) Info(_ []byte) (int, int, error) { return r.width, r.height, r.infoErr }
86+func (r *fakeWebPRuntime) DecodeRGBAInto(_, pix []byte, _, _, _ int) error {
87+ r.decodeCalls++
88+ for i := range pix {
89+ pix[i] = 0xff
90+ }
91+ return nil
92+}
A vendor/github.com/bnema/purego-webp/LICENSE +21 -0 generated file: collapsed
A vendor/github.com/bnema/purego-webp/internal/libwebp/generated_symbols.go +513 -0
@@ -0,0 +1,513 @@
1+// Code generated by ./cmd/gen; DO NOT EDIT.
2+
3+package libwebp
4+
5+var (
6+ xWebPGetInfo func(data *byte, dataSize uintptr, width *int32, height *int32) int32
7+ xWebPDecodeRGBA func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
8+ xWebPDecodeARGB func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
9+ xWebPDecodeBGRA func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
10+ xWebPDecodeRGB func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
11+ xWebPDecodeBGR func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
12+ xWebPDecodeRGBAInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
13+ xWebPDecodeARGBInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
14+ xWebPDecodeBGRAInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
15+ xWebPDecodeRGBInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
16+ xWebPDecodeBGRInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
17+ xWebPDecodeYUV func(data *byte, dataSize uintptr, width *int32, height *int32, u **byte, v **byte, stride *int32, uvStride *int32) *byte
18+ xWebPDecodeYUVInto func(data *byte, dataSize uintptr, luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32) *byte
19+ xWebPGetFeaturesInternal func(data *byte, dataSize uintptr, features *WebPBitstreamFeatures, abiVersion int32) VP8StatusCode
20+ xWebPInitDecBufferInternal func(buffer *WebPDecBuffer, abiVersion int32) int32
21+ xWebPFreeDecBuffer func(buffer *WebPDecBuffer)
22+ xWebPInitDecoderConfigInternal func(config *WebPDecoderConfig, abiVersion int32) int32
23+ xWebPValidateDecoderConfig func(config *WebPDecoderConfig) int32
24+ xWebPDecode func(data *byte, dataSize uintptr, config *WebPDecoderConfig) VP8StatusCode
25+ xWebPINewDecoder func(outputBuffer *WebPDecBuffer) uintptr
26+ xWebPINewRGB func(csp int32, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) uintptr
27+ xWebPINewYUVA func(luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32, a *byte, aSize uintptr, aStride int32) uintptr
28+ xWebPINewYUV func(luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32) uintptr
29+ xWebPIDelete func(idec uintptr)
30+ xWebPIAppend func(idec uintptr, data *byte, dataSize uintptr) VP8StatusCode
31+ xWebPIUpdate func(idec uintptr, data *byte, dataSize uintptr) VP8StatusCode
32+ xWebPIDecGetRGB func(idec uintptr, lastY *int32, width *int32, height *int32, stride *int32) *byte
33+ xWebPIDecGetYUVA func(idec uintptr, lastY *int32, u **byte, v **byte, a **byte, width *int32, height *int32, stride *int32, uvStride *int32, aStride *int32) *byte
34+ xWebPIDecodedArea func(idec uintptr, left *int32, top *int32, width *int32, height *int32) *WebPDecBuffer
35+ xWebPIDecode func(data *byte, dataSize uintptr, config *WebPDecoderConfig) uintptr
36+ xWebPEncodeRGBA func(rgba *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr
37+ xWebPEncodeRGB func(rgb *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr
38+ xWebPEncodeBGR func(bgr *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr
39+ xWebPEncodeBGRA func(bgra *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr
40+ xWebPEncodeLosslessRGBA func(rgba *byte, width int32, height int32, stride int32, output **byte) uintptr
41+ xWebPEncodeLosslessRGB func(rgb *byte, width int32, height int32, stride int32, output **byte) uintptr
42+ xWebPEncodeLosslessBGR func(bgr *byte, width int32, height int32, stride int32, output **byte) uintptr
43+ xWebPEncodeLosslessBGRA func(bgra *byte, width int32, height int32, stride int32, output **byte) uintptr
44+ xWebPConfigInitInternal func(config *WebPConfig, preset int32, quality float32, abiVersion int32) int32
45+ xWebPConfigLosslessPreset func(config *WebPConfig, level int32) int32
46+ xWebPValidateConfig func(config *WebPConfig) int32
47+ xWebPMemoryWriterInit func(writer *WebPMemoryWriter)
48+ xWebPMemoryWriterClear func(writer *WebPMemoryWriter)
49+ xWebPMemoryWrite func(data *byte, dataSize uintptr, picture *WebPPicture) int32
50+ xWebPPictureInitInternal func(picture *WebPPicture, abiVersion int32) int32
51+ xWebPPictureAlloc func(picture *WebPPicture) int32
52+ xWebPPictureFree func(picture *WebPPicture)
53+ xWebPPictureCopy func(src *WebPPicture, dst *WebPPicture) int32
54+ xWebPPictureCrop func(picture *WebPPicture, left int32, top int32, width int32, height int32) int32
55+ xWebPPictureView func(src *WebPPicture, left int32, top int32, width int32, height int32, dst *WebPPicture) int32
56+ xWebPPictureIsView func(picture *WebPPicture) int32
57+ xWebPPictureRescale func(picture *WebPPicture, width int32, height int32) int32
58+ xWebPPictureImportRGB func(picture *WebPPicture, rgb *byte, rgbStride int32) int32
59+ xWebPPictureImportRGBA func(picture *WebPPicture, rgba *byte, rgbaStride int32) int32
60+ xWebPPictureImportRGBX func(picture *WebPPicture, rgbx *byte, rgbxStride int32) int32
61+ xWebPPictureImportBGR func(picture *WebPPicture, bgr *byte, bgrStride int32) int32
62+ xWebPPictureImportBGRA func(picture *WebPPicture, bgra *byte, bgraStride int32) int32
63+ xWebPPictureImportBGRX func(picture *WebPPicture, bgrx *byte, bgrxStride int32) int32
64+ xWebPPictureARGBToYUVA func(picture *WebPPicture, colorspace int32) int32
65+ xWebPPictureARGBToYUVADithered func(picture *WebPPicture, colorspace int32, dithering float32) int32
66+ xWebPPictureSharpARGBToYUVA func(picture *WebPPicture) int32
67+ xWebPPictureSmartARGBToYUVA func(picture *WebPPicture) int32
68+ xWebPPictureYUVAToARGB func(picture *WebPPicture) int32
69+ xWebPCleanupTransparentArea func(picture *WebPPicture)
70+ xWebPPictureHasTransparency func(picture *WebPPicture) int32
71+ xWebPBlendAlpha func(picture *WebPPicture, backgroundRGB uint32)
72+ xWebPPlaneDistortion func(src *byte, srcStride uintptr, ref *byte, refStride uintptr, width int32, height int32, xStep uintptr, distType int32, distortion *float32, result *float32) int32
73+ xWebPPictureDistortion func(src *WebPPicture, ref *WebPPicture, metricType int32, result *float32) int32
74+ xWebPEncode func(config *WebPConfig, picture *WebPPicture) int32
75+ xWebPFree func(ptr uintptr)
76+ xWebPGetDecoderVersion func() int32
77+ xWebPGetEncoderVersion func() int32
78+)
79+
80+func WebPGetInfo(data *byte, dataSize uintptr, width *int32, height *int32) int32 {
81+ return xWebPGetInfo(data, dataSize, width, height)
82+}
83+func WebPDecodeRGBA(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
84+ return xWebPDecodeRGBA(data, dataSize, width, height)
85+}
86+func WebPDecodeARGB(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
87+ return xWebPDecodeARGB(data, dataSize, width, height)
88+}
89+func WebPDecodeBGRA(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
90+ return xWebPDecodeBGRA(data, dataSize, width, height)
91+}
92+func WebPDecodeRGB(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
93+ return xWebPDecodeRGB(data, dataSize, width, height)
94+}
95+func WebPDecodeBGR(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
96+ return xWebPDecodeBGR(data, dataSize, width, height)
97+}
98+func WebPDecodeRGBAInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
99+ return xWebPDecodeRGBAInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
100+}
101+func WebPDecodeARGBInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
102+ return xWebPDecodeARGBInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
103+}
104+func WebPDecodeBGRAInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
105+ return xWebPDecodeBGRAInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
106+}
107+func WebPDecodeRGBInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
108+ return xWebPDecodeRGBInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
109+}
110+func WebPDecodeBGRInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
111+ return xWebPDecodeBGRInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
112+}
113+func WebPDecodeYUV(data *byte, dataSize uintptr, width *int32, height *int32, u **byte, v **byte, stride *int32, uvStride *int32) *byte {
114+ return xWebPDecodeYUV(data, dataSize, width, height, u, v, stride, uvStride)
115+}
116+func WebPDecodeYUVInto(data *byte, dataSize uintptr, luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32) *byte {
117+ return xWebPDecodeYUVInto(data, dataSize, luma, lumaSize, lumaStride, u, uSize, uStride, v, vSize, vStride)
118+}
119+func WebPGetFeaturesInternal(data *byte, dataSize uintptr, features *WebPBitstreamFeatures, abiVersion int32) VP8StatusCode {
120+ return xWebPGetFeaturesInternal(data, dataSize, features, abiVersion)
121+}
122+func WebPInitDecBufferInternal(buffer *WebPDecBuffer, abiVersion int32) int32 {
123+ return xWebPInitDecBufferInternal(buffer, abiVersion)
124+}
125+func WebPFreeDecBuffer(buffer *WebPDecBuffer) {
126+ xWebPFreeDecBuffer(buffer)
127+}
128+func WebPInitDecoderConfigInternal(config *WebPDecoderConfig, abiVersion int32) int32 {
129+ return xWebPInitDecoderConfigInternal(config, abiVersion)
130+}
131+func WebPValidateDecoderConfig(config *WebPDecoderConfig) int32 {
132+ return xWebPValidateDecoderConfig(config)
133+}
134+func WebPDecode(data *byte, dataSize uintptr, config *WebPDecoderConfig) VP8StatusCode {
135+ return xWebPDecode(data, dataSize, config)
136+}
137+func WebPINewDecoder(outputBuffer *WebPDecBuffer) uintptr {
138+ return xWebPINewDecoder(outputBuffer)
139+}
140+func WebPINewRGB(csp int32, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) uintptr {
141+ return xWebPINewRGB(csp, outputBuffer, outputBufferSize, outputStride)
142+}
143+func WebPINewYUVA(luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32, a *byte, aSize uintptr, aStride int32) uintptr {
144+ return xWebPINewYUVA(luma, lumaSize, lumaStride, u, uSize, uStride, v, vSize, vStride, a, aSize, aStride)
145+}
146+func WebPINewYUV(luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32) uintptr {
147+ return xWebPINewYUV(luma, lumaSize, lumaStride, u, uSize, uStride, v, vSize, vStride)
148+}
149+func WebPIDelete(idec uintptr) {
150+ xWebPIDelete(idec)
151+}
152+func WebPIAppend(idec uintptr, data *byte, dataSize uintptr) VP8StatusCode {
153+ return xWebPIAppend(idec, data, dataSize)
154+}
155+func WebPIUpdate(idec uintptr, data *byte, dataSize uintptr) VP8StatusCode {
156+ return xWebPIUpdate(idec, data, dataSize)
157+}
158+func WebPIDecGetRGB(idec uintptr, lastY *int32, width *int32, height *int32, stride *int32) *byte {
159+ return xWebPIDecGetRGB(idec, lastY, width, height, stride)
160+}
161+func WebPIDecGetYUVA(idec uintptr, lastY *int32, u **byte, v **byte, a **byte, width *int32, height *int32, stride *int32, uvStride *int32, aStride *int32) *byte {
162+ return xWebPIDecGetYUVA(idec, lastY, u, v, a, width, height, stride, uvStride, aStride)
163+}
164+func WebPIDecodedArea(idec uintptr, left *int32, top *int32, width *int32, height *int32) *WebPDecBuffer {
165+ return xWebPIDecodedArea(idec, left, top, width, height)
166+}
167+func WebPIDecode(data *byte, dataSize uintptr, config *WebPDecoderConfig) uintptr {
168+ return xWebPIDecode(data, dataSize, config)
169+}
170+func WebPEncodeRGBA(rgba *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr {
171+ return xWebPEncodeRGBA(rgba, width, height, stride, quality, output)
172+}
173+func WebPEncodeRGB(rgb *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr {
174+ return xWebPEncodeRGB(rgb, width, height, stride, quality, output)
175+}
176+func WebPEncodeBGR(bgr *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr {
177+ return xWebPEncodeBGR(bgr, width, height, stride, quality, output)
178+}
179+func WebPEncodeBGRA(bgra *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr {
180+ return xWebPEncodeBGRA(bgra, width, height, stride, quality, output)
181+}
182+func WebPEncodeLosslessRGBA(rgba *byte, width int32, height int32, stride int32, output **byte) uintptr {
183+ return xWebPEncodeLosslessRGBA(rgba, width, height, stride, output)
184+}
185+func WebPEncodeLosslessRGB(rgb *byte, width int32, height int32, stride int32, output **byte) uintptr {
186+ return xWebPEncodeLosslessRGB(rgb, width, height, stride, output)
187+}
188+func WebPEncodeLosslessBGR(bgr *byte, width int32, height int32, stride int32, output **byte) uintptr {
189+ return xWebPEncodeLosslessBGR(bgr, width, height, stride, output)
190+}
191+func WebPEncodeLosslessBGRA(bgra *byte, width int32, height int32, stride int32, output **byte) uintptr {
192+ return xWebPEncodeLosslessBGRA(bgra, width, height, stride, output)
193+}
194+func WebPConfigInitInternal(config *WebPConfig, preset int32, quality float32, abiVersion int32) int32 {
195+ return xWebPConfigInitInternal(config, preset, quality, abiVersion)
196+}
197+func WebPConfigLosslessPreset(config *WebPConfig, level int32) int32 {
198+ return xWebPConfigLosslessPreset(config, level)
199+}
200+func WebPValidateConfig(config *WebPConfig) int32 {
201+ return xWebPValidateConfig(config)
202+}
203+func WebPMemoryWriterInit(writer *WebPMemoryWriter) {
204+ xWebPMemoryWriterInit(writer)
205+}
206+func WebPMemoryWriterClear(writer *WebPMemoryWriter) {
207+ xWebPMemoryWriterClear(writer)
208+}
209+func WebPMemoryWrite(data *byte, dataSize uintptr, picture *WebPPicture) int32 {
210+ return xWebPMemoryWrite(data, dataSize, picture)
211+}
212+func WebPPictureInitInternal(picture *WebPPicture, abiVersion int32) int32 {
213+ return xWebPPictureInitInternal(picture, abiVersion)
214+}
215+func WebPPictureAlloc(picture *WebPPicture) int32 {
216+ return xWebPPictureAlloc(picture)
217+}
218+func WebPPictureFree(picture *WebPPicture) {
219+ xWebPPictureFree(picture)
220+}
221+func WebPPictureCopy(src *WebPPicture, dst *WebPPicture) int32 {
222+ return xWebPPictureCopy(src, dst)
223+}
224+func WebPPictureCrop(picture *WebPPicture, left int32, top int32, width int32, height int32) int32 {
225+ return xWebPPictureCrop(picture, left, top, width, height)
226+}
227+func WebPPictureView(src *WebPPicture, left int32, top int32, width int32, height int32, dst *WebPPicture) int32 {
228+ return xWebPPictureView(src, left, top, width, height, dst)
229+}
230+func WebPPictureIsView(picture *WebPPicture) int32 {
231+ return xWebPPictureIsView(picture)
232+}
233+func WebPPictureRescale(picture *WebPPicture, width int32, height int32) int32 {
234+ return xWebPPictureRescale(picture, width, height)
235+}
236+func WebPPictureImportRGB(picture *WebPPicture, rgb *byte, rgbStride int32) int32 {
237+ return xWebPPictureImportRGB(picture, rgb, rgbStride)
238+}
239+func WebPPictureImportRGBA(picture *WebPPicture, rgba *byte, rgbaStride int32) int32 {
240+ return xWebPPictureImportRGBA(picture, rgba, rgbaStride)
241+}
242+func WebPPictureImportRGBX(picture *WebPPicture, rgbx *byte, rgbxStride int32) int32 {
243+ return xWebPPictureImportRGBX(picture, rgbx, rgbxStride)
244+}
245+func WebPPictureImportBGR(picture *WebPPicture, bgr *byte, bgrStride int32) int32 {
246+ return xWebPPictureImportBGR(picture, bgr, bgrStride)
247+}
248+func WebPPictureImportBGRA(picture *WebPPicture, bgra *byte, bgraStride int32) int32 {
249+ return xWebPPictureImportBGRA(picture, bgra, bgraStride)
250+}
251+func WebPPictureImportBGRX(picture *WebPPicture, bgrx *byte, bgrxStride int32) int32 {
252+ return xWebPPictureImportBGRX(picture, bgrx, bgrxStride)
253+}
254+func WebPPictureARGBToYUVA(picture *WebPPicture, colorspace int32) int32 {
255+ return xWebPPictureARGBToYUVA(picture, colorspace)
256+}
257+func WebPPictureARGBToYUVADithered(picture *WebPPicture, colorspace int32, dithering float32) int32 {
258+ return xWebPPictureARGBToYUVADithered(picture, colorspace, dithering)
259+}
260+func WebPPictureSharpARGBToYUVA(picture *WebPPicture) int32 {
261+ return xWebPPictureSharpARGBToYUVA(picture)
262+}
263+func WebPPictureSmartARGBToYUVA(picture *WebPPicture) int32 {
264+ return xWebPPictureSmartARGBToYUVA(picture)
265+}
266+func WebPPictureYUVAToARGB(picture *WebPPicture) int32 {
267+ return xWebPPictureYUVAToARGB(picture)
268+}
269+func WebPCleanupTransparentArea(picture *WebPPicture) {
270+ xWebPCleanupTransparentArea(picture)
271+}
272+func WebPPictureHasTransparency(picture *WebPPicture) int32 {
273+ return xWebPPictureHasTransparency(picture)
274+}
275+func WebPBlendAlpha(picture *WebPPicture, backgroundRGB uint32) {
276+ xWebPBlendAlpha(picture, backgroundRGB)
277+}
278+func WebPPlaneDistortion(src *byte, srcStride uintptr, ref *byte, refStride uintptr, width int32, height int32, xStep uintptr, distType int32, distortion *float32, result *float32) int32 {
279+ return xWebPPlaneDistortion(src, srcStride, ref, refStride, width, height, xStep, distType, distortion, result)
280+}
281+func WebPPictureDistortion(src *WebPPicture, ref *WebPPicture, metricType int32, result *float32) int32 {
282+ return xWebPPictureDistortion(src, ref, metricType, result)
283+}
284+func WebPEncode(config *WebPConfig, picture *WebPPicture) int32 {
285+ return xWebPEncode(config, picture)
286+}
287+func WebPFree(ptr uintptr) {
288+ xWebPFree(ptr)
289+}
290+func WebPGetDecoderVersion() int32 {
291+ return xWebPGetDecoderVersion()
292+}
293+func WebPGetEncoderVersion() int32 {
294+ return xWebPGetEncoderVersion()
295+}
296+func registerAll(lib uintptr) error {
297+ if err := register(lib, &xWebPGetInfo, "WebPGetInfo"); err != nil {
298+ return err
299+ }
300+ if err := register(lib, &xWebPDecodeRGBA, "WebPDecodeRGBA"); err != nil {
301+ return err
302+ }
303+ if err := register(lib, &xWebPDecodeARGB, "WebPDecodeARGB"); err != nil {
304+ return err
305+ }
306+ if err := register(lib, &xWebPDecodeBGRA, "WebPDecodeBGRA"); err != nil {
307+ return err
308+ }
309+ if err := register(lib, &xWebPDecodeRGB, "WebPDecodeRGB"); err != nil {
310+ return err
311+ }
312+ if err := register(lib, &xWebPDecodeBGR, "WebPDecodeBGR"); err != nil {
313+ return err
314+ }
315+ if err := register(lib, &xWebPDecodeRGBAInto, "WebPDecodeRGBAInto"); err != nil {
316+ return err
317+ }
318+ if err := register(lib, &xWebPDecodeARGBInto, "WebPDecodeARGBInto"); err != nil {
319+ return err
320+ }
321+ if err := register(lib, &xWebPDecodeBGRAInto, "WebPDecodeBGRAInto"); err != nil {
322+ return err
323+ }
324+ if err := register(lib, &xWebPDecodeRGBInto, "WebPDecodeRGBInto"); err != nil {
325+ return err
326+ }
327+ if err := register(lib, &xWebPDecodeBGRInto, "WebPDecodeBGRInto"); err != nil {
328+ return err
329+ }
330+ if err := register(lib, &xWebPDecodeYUV, "WebPDecodeYUV"); err != nil {
331+ return err
332+ }
333+ if err := register(lib, &xWebPDecodeYUVInto, "WebPDecodeYUVInto"); err != nil {
334+ return err
335+ }
336+ if err := register(lib, &xWebPGetFeaturesInternal, "WebPGetFeaturesInternal"); err != nil {
337+ return err
338+ }
339+ if err := register(lib, &xWebPInitDecBufferInternal, "WebPInitDecBufferInternal"); err != nil {
340+ return err
341+ }
342+ if err := register(lib, &xWebPFreeDecBuffer, "WebPFreeDecBuffer"); err != nil {
343+ return err
344+ }
345+ if err := register(lib, &xWebPInitDecoderConfigInternal, "WebPInitDecoderConfigInternal"); err != nil {
346+ return err
347+ }
348+ registerOptional(lib, &xWebPValidateDecoderConfig, "WebPValidateDecoderConfig")
349+ if err := register(lib, &xWebPDecode, "WebPDecode"); err != nil {
350+ return err
351+ }
352+ if err := register(lib, &xWebPINewDecoder, "WebPINewDecoder"); err != nil {
353+ return err
354+ }
355+ if err := register(lib, &xWebPINewRGB, "WebPINewRGB"); err != nil {
356+ return err
357+ }
358+ if err := register(lib, &xWebPINewYUVA, "WebPINewYUVA"); err != nil {
359+ return err
360+ }
361+ if err := register(lib, &xWebPINewYUV, "WebPINewYUV"); err != nil {
362+ return err
363+ }
364+ if err := register(lib, &xWebPIDelete, "WebPIDelete"); err != nil {
365+ return err
366+ }
367+ if err := register(lib, &xWebPIAppend, "WebPIAppend"); err != nil {
368+ return err
369+ }
370+ if err := register(lib, &xWebPIUpdate, "WebPIUpdate"); err != nil {
371+ return err
372+ }
373+ if err := register(lib, &xWebPIDecGetRGB, "WebPIDecGetRGB"); err != nil {
374+ return err
375+ }
376+ if err := register(lib, &xWebPIDecGetYUVA, "WebPIDecGetYUVA"); err != nil {
377+ return err
378+ }
379+ if err := register(lib, &xWebPIDecodedArea, "WebPIDecodedArea"); err != nil {
380+ return err
381+ }
382+ if err := register(lib, &xWebPIDecode, "WebPIDecode"); err != nil {
383+ return err
384+ }
385+ if err := register(lib, &xWebPEncodeRGBA, "WebPEncodeRGBA"); err != nil {
386+ return err
387+ }
388+ if err := register(lib, &xWebPEncodeRGB, "WebPEncodeRGB"); err != nil {
389+ return err
390+ }
391+ if err := register(lib, &xWebPEncodeBGR, "WebPEncodeBGR"); err != nil {
392+ return err
393+ }
394+ if err := register(lib, &xWebPEncodeBGRA, "WebPEncodeBGRA"); err != nil {
395+ return err
396+ }
397+ if err := register(lib, &xWebPEncodeLosslessRGBA, "WebPEncodeLosslessRGBA"); err != nil {
398+ return err
399+ }
400+ if err := register(lib, &xWebPEncodeLosslessRGB, "WebPEncodeLosslessRGB"); err != nil {
401+ return err
402+ }
403+ if err := register(lib, &xWebPEncodeLosslessBGR, "WebPEncodeLosslessBGR"); err != nil {
404+ return err
405+ }
406+ if err := register(lib, &xWebPEncodeLosslessBGRA, "WebPEncodeLosslessBGRA"); err != nil {
407+ return err
408+ }
409+ if err := register(lib, &xWebPConfigInitInternal, "WebPConfigInitInternal"); err != nil {
410+ return err
411+ }
412+ if err := register(lib, &xWebPConfigLosslessPreset, "WebPConfigLosslessPreset"); err != nil {
413+ return err
414+ }
415+ if err := register(lib, &xWebPValidateConfig, "WebPValidateConfig"); err != nil {
416+ return err
417+ }
418+ if err := register(lib, &xWebPMemoryWriterInit, "WebPMemoryWriterInit"); err != nil {
419+ return err
420+ }
421+ if err := register(lib, &xWebPMemoryWriterClear, "WebPMemoryWriterClear"); err != nil {
422+ return err
423+ }
424+ if err := register(lib, &xWebPMemoryWrite, "WebPMemoryWrite"); err != nil {
425+ return err
426+ }
427+ if err := register(lib, &xWebPPictureInitInternal, "WebPPictureInitInternal"); err != nil {
428+ return err
429+ }
430+ if err := register(lib, &xWebPPictureAlloc, "WebPPictureAlloc"); err != nil {
431+ return err
432+ }
433+ if err := register(lib, &xWebPPictureFree, "WebPPictureFree"); err != nil {
434+ return err
435+ }
436+ if err := register(lib, &xWebPPictureCopy, "WebPPictureCopy"); err != nil {
437+ return err
438+ }
439+ if err := register(lib, &xWebPPictureCrop, "WebPPictureCrop"); err != nil {
440+ return err
441+ }
442+ if err := register(lib, &xWebPPictureView, "WebPPictureView"); err != nil {
443+ return err
444+ }
445+ if err := register(lib, &xWebPPictureIsView, "WebPPictureIsView"); err != nil {
446+ return err
447+ }
448+ if err := register(lib, &xWebPPictureRescale, "WebPPictureRescale"); err != nil {
449+ return err
450+ }
451+ if err := register(lib, &xWebPPictureImportRGB, "WebPPictureImportRGB"); err != nil {
452+ return err
453+ }
454+ if err := register(lib, &xWebPPictureImportRGBA, "WebPPictureImportRGBA"); err != nil {
455+ return err
456+ }
457+ if err := register(lib, &xWebPPictureImportRGBX, "WebPPictureImportRGBX"); err != nil {
458+ return err
459+ }
460+ if err := register(lib, &xWebPPictureImportBGR, "WebPPictureImportBGR"); err != nil {
461+ return err
462+ }
463+ if err := register(lib, &xWebPPictureImportBGRA, "WebPPictureImportBGRA"); err != nil {
464+ return err
465+ }
466+ if err := register(lib, &xWebPPictureImportBGRX, "WebPPictureImportBGRX"); err != nil {
467+ return err
468+ }
469+ if err := register(lib, &xWebPPictureARGBToYUVA, "WebPPictureARGBToYUVA"); err != nil {
470+ return err
471+ }
472+ if err := register(lib, &xWebPPictureARGBToYUVADithered, "WebPPictureARGBToYUVADithered"); err != nil {
473+ return err
474+ }
475+ if err := register(lib, &xWebPPictureSharpARGBToYUVA, "WebPPictureSharpARGBToYUVA"); err != nil {
476+ return err
477+ }
478+ if err := register(lib, &xWebPPictureSmartARGBToYUVA, "WebPPictureSmartARGBToYUVA"); err != nil {
479+ return err
480+ }
481+ if err := register(lib, &xWebPPictureYUVAToARGB, "WebPPictureYUVAToARGB"); err != nil {
482+ return err
483+ }
484+ if err := register(lib, &xWebPCleanupTransparentArea, "WebPCleanupTransparentArea"); err != nil {
485+ return err
486+ }
487+ if err := register(lib, &xWebPPictureHasTransparency, "WebPPictureHasTransparency"); err != nil {
488+ return err
489+ }
490+ if err := register(lib, &xWebPBlendAlpha, "WebPBlendAlpha"); err != nil {
491+ return err
492+ }
493+ if err := register(lib, &xWebPPlaneDistortion, "WebPPlaneDistortion"); err != nil {
494+ return err
495+ }
496+ if err := register(lib, &xWebPPictureDistortion, "WebPPictureDistortion"); err != nil {
497+ return err
498+ }
499+ if err := register(lib, &xWebPEncode, "WebPEncode"); err != nil {
500+ return err
501+ }
502+ if err := register(lib, &xWebPFree, "WebPFree"); err != nil {
503+ return err
504+ }
505+ if err := register(lib, &xWebPGetDecoderVersion, "WebPGetDecoderVersion"); err != nil {
506+ return err
507+ }
508+ if err := register(lib, &xWebPGetEncoderVersion, "WebPGetEncoderVersion"); err != nil {
509+ return err
510+ }
511+
512+ return nil
513+}
@@ -0,0 +1,513 @@
1+// Code generated by ./cmd/gen; DO NOT EDIT.
2+
3+package libwebp
4+
5+var (
6+ xWebPGetInfo func(data *byte, dataSize uintptr, width *int32, height *int32) int32
7+ xWebPDecodeRGBA func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
8+ xWebPDecodeARGB func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
9+ xWebPDecodeBGRA func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
10+ xWebPDecodeRGB func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
11+ xWebPDecodeBGR func(data *byte, dataSize uintptr, width *int32, height *int32) *byte
12+ xWebPDecodeRGBAInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
13+ xWebPDecodeARGBInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
14+ xWebPDecodeBGRAInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
15+ xWebPDecodeRGBInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
16+ xWebPDecodeBGRInto func(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte
17+ xWebPDecodeYUV func(data *byte, dataSize uintptr, width *int32, height *int32, u **byte, v **byte, stride *int32, uvStride *int32) *byte
18+ xWebPDecodeYUVInto func(data *byte, dataSize uintptr, luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32) *byte
19+ xWebPGetFeaturesInternal func(data *byte, dataSize uintptr, features *WebPBitstreamFeatures, abiVersion int32) VP8StatusCode
20+ xWebPInitDecBufferInternal func(buffer *WebPDecBuffer, abiVersion int32) int32
21+ xWebPFreeDecBuffer func(buffer *WebPDecBuffer)
22+ xWebPInitDecoderConfigInternal func(config *WebPDecoderConfig, abiVersion int32) int32
23+ xWebPValidateDecoderConfig func(config *WebPDecoderConfig) int32
24+ xWebPDecode func(data *byte, dataSize uintptr, config *WebPDecoderConfig) VP8StatusCode
25+ xWebPINewDecoder func(outputBuffer *WebPDecBuffer) uintptr
26+ xWebPINewRGB func(csp int32, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) uintptr
27+ xWebPINewYUVA func(luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32, a *byte, aSize uintptr, aStride int32) uintptr
28+ xWebPINewYUV func(luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32) uintptr
29+ xWebPIDelete func(idec uintptr)
30+ xWebPIAppend func(idec uintptr, data *byte, dataSize uintptr) VP8StatusCode
31+ xWebPIUpdate func(idec uintptr, data *byte, dataSize uintptr) VP8StatusCode
32+ xWebPIDecGetRGB func(idec uintptr, lastY *int32, width *int32, height *int32, stride *int32) *byte
33+ xWebPIDecGetYUVA func(idec uintptr, lastY *int32, u **byte, v **byte, a **byte, width *int32, height *int32, stride *int32, uvStride *int32, aStride *int32) *byte
34+ xWebPIDecodedArea func(idec uintptr, left *int32, top *int32, width *int32, height *int32) *WebPDecBuffer
35+ xWebPIDecode func(data *byte, dataSize uintptr, config *WebPDecoderConfig) uintptr
36+ xWebPEncodeRGBA func(rgba *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr
37+ xWebPEncodeRGB func(rgb *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr
38+ xWebPEncodeBGR func(bgr *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr
39+ xWebPEncodeBGRA func(bgra *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr
40+ xWebPEncodeLosslessRGBA func(rgba *byte, width int32, height int32, stride int32, output **byte) uintptr
41+ xWebPEncodeLosslessRGB func(rgb *byte, width int32, height int32, stride int32, output **byte) uintptr
42+ xWebPEncodeLosslessBGR func(bgr *byte, width int32, height int32, stride int32, output **byte) uintptr
43+ xWebPEncodeLosslessBGRA func(bgra *byte, width int32, height int32, stride int32, output **byte) uintptr
44+ xWebPConfigInitInternal func(config *WebPConfig, preset int32, quality float32, abiVersion int32) int32
45+ xWebPConfigLosslessPreset func(config *WebPConfig, level int32) int32
46+ xWebPValidateConfig func(config *WebPConfig) int32
47+ xWebPMemoryWriterInit func(writer *WebPMemoryWriter)
48+ xWebPMemoryWriterClear func(writer *WebPMemoryWriter)
49+ xWebPMemoryWrite func(data *byte, dataSize uintptr, picture *WebPPicture) int32
50+ xWebPPictureInitInternal func(picture *WebPPicture, abiVersion int32) int32
51+ xWebPPictureAlloc func(picture *WebPPicture) int32
52+ xWebPPictureFree func(picture *WebPPicture)
53+ xWebPPictureCopy func(src *WebPPicture, dst *WebPPicture) int32
54+ xWebPPictureCrop func(picture *WebPPicture, left int32, top int32, width int32, height int32) int32
55+ xWebPPictureView func(src *WebPPicture, left int32, top int32, width int32, height int32, dst *WebPPicture) int32
56+ xWebPPictureIsView func(picture *WebPPicture) int32
57+ xWebPPictureRescale func(picture *WebPPicture, width int32, height int32) int32
58+ xWebPPictureImportRGB func(picture *WebPPicture, rgb *byte, rgbStride int32) int32
59+ xWebPPictureImportRGBA func(picture *WebPPicture, rgba *byte, rgbaStride int32) int32
60+ xWebPPictureImportRGBX func(picture *WebPPicture, rgbx *byte, rgbxStride int32) int32
61+ xWebPPictureImportBGR func(picture *WebPPicture, bgr *byte, bgrStride int32) int32
62+ xWebPPictureImportBGRA func(picture *WebPPicture, bgra *byte, bgraStride int32) int32
63+ xWebPPictureImportBGRX func(picture *WebPPicture, bgrx *byte, bgrxStride int32) int32
64+ xWebPPictureARGBToYUVA func(picture *WebPPicture, colorspace int32) int32
65+ xWebPPictureARGBToYUVADithered func(picture *WebPPicture, colorspace int32, dithering float32) int32
66+ xWebPPictureSharpARGBToYUVA func(picture *WebPPicture) int32
67+ xWebPPictureSmartARGBToYUVA func(picture *WebPPicture) int32
68+ xWebPPictureYUVAToARGB func(picture *WebPPicture) int32
69+ xWebPCleanupTransparentArea func(picture *WebPPicture)
70+ xWebPPictureHasTransparency func(picture *WebPPicture) int32
71+ xWebPBlendAlpha func(picture *WebPPicture, backgroundRGB uint32)
72+ xWebPPlaneDistortion func(src *byte, srcStride uintptr, ref *byte, refStride uintptr, width int32, height int32, xStep uintptr, distType int32, distortion *float32, result *float32) int32
73+ xWebPPictureDistortion func(src *WebPPicture, ref *WebPPicture, metricType int32, result *float32) int32
74+ xWebPEncode func(config *WebPConfig, picture *WebPPicture) int32
75+ xWebPFree func(ptr uintptr)
76+ xWebPGetDecoderVersion func() int32
77+ xWebPGetEncoderVersion func() int32
78+)
79+
80+func WebPGetInfo(data *byte, dataSize uintptr, width *int32, height *int32) int32 {
81+ return xWebPGetInfo(data, dataSize, width, height)
82+}
83+func WebPDecodeRGBA(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
84+ return xWebPDecodeRGBA(data, dataSize, width, height)
85+}
86+func WebPDecodeARGB(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
87+ return xWebPDecodeARGB(data, dataSize, width, height)
88+}
89+func WebPDecodeBGRA(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
90+ return xWebPDecodeBGRA(data, dataSize, width, height)
91+}
92+func WebPDecodeRGB(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
93+ return xWebPDecodeRGB(data, dataSize, width, height)
94+}
95+func WebPDecodeBGR(data *byte, dataSize uintptr, width *int32, height *int32) *byte {
96+ return xWebPDecodeBGR(data, dataSize, width, height)
97+}
98+func WebPDecodeRGBAInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
99+ return xWebPDecodeRGBAInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
100+}
101+func WebPDecodeARGBInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
102+ return xWebPDecodeARGBInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
103+}
104+func WebPDecodeBGRAInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
105+ return xWebPDecodeBGRAInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
106+}
107+func WebPDecodeRGBInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
108+ return xWebPDecodeRGBInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
109+}
110+func WebPDecodeBGRInto(data *byte, dataSize uintptr, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) *byte {
111+ return xWebPDecodeBGRInto(data, dataSize, outputBuffer, outputBufferSize, outputStride)
112+}
113+func WebPDecodeYUV(data *byte, dataSize uintptr, width *int32, height *int32, u **byte, v **byte, stride *int32, uvStride *int32) *byte {
114+ return xWebPDecodeYUV(data, dataSize, width, height, u, v, stride, uvStride)
115+}
116+func WebPDecodeYUVInto(data *byte, dataSize uintptr, luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32) *byte {
117+ return xWebPDecodeYUVInto(data, dataSize, luma, lumaSize, lumaStride, u, uSize, uStride, v, vSize, vStride)
118+}
119+func WebPGetFeaturesInternal(data *byte, dataSize uintptr, features *WebPBitstreamFeatures, abiVersion int32) VP8StatusCode {
120+ return xWebPGetFeaturesInternal(data, dataSize, features, abiVersion)
121+}
122+func WebPInitDecBufferInternal(buffer *WebPDecBuffer, abiVersion int32) int32 {
123+ return xWebPInitDecBufferInternal(buffer, abiVersion)
124+}
125+func WebPFreeDecBuffer(buffer *WebPDecBuffer) {
126+ xWebPFreeDecBuffer(buffer)
127+}
128+func WebPInitDecoderConfigInternal(config *WebPDecoderConfig, abiVersion int32) int32 {
129+ return xWebPInitDecoderConfigInternal(config, abiVersion)
130+}
131+func WebPValidateDecoderConfig(config *WebPDecoderConfig) int32 {
132+ return xWebPValidateDecoderConfig(config)
133+}
134+func WebPDecode(data *byte, dataSize uintptr, config *WebPDecoderConfig) VP8StatusCode {
135+ return xWebPDecode(data, dataSize, config)
136+}
137+func WebPINewDecoder(outputBuffer *WebPDecBuffer) uintptr {
138+ return xWebPINewDecoder(outputBuffer)
139+}
140+func WebPINewRGB(csp int32, outputBuffer *byte, outputBufferSize uintptr, outputStride int32) uintptr {
141+ return xWebPINewRGB(csp, outputBuffer, outputBufferSize, outputStride)
142+}
143+func WebPINewYUVA(luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32, a *byte, aSize uintptr, aStride int32) uintptr {
144+ return xWebPINewYUVA(luma, lumaSize, lumaStride, u, uSize, uStride, v, vSize, vStride, a, aSize, aStride)
145+}
146+func WebPINewYUV(luma *byte, lumaSize uintptr, lumaStride int32, u *byte, uSize uintptr, uStride int32, v *byte, vSize uintptr, vStride int32) uintptr {
147+ return xWebPINewYUV(luma, lumaSize, lumaStride, u, uSize, uStride, v, vSize, vStride)
148+}
149+func WebPIDelete(idec uintptr) {
150+ xWebPIDelete(idec)
151+}
152+func WebPIAppend(idec uintptr, data *byte, dataSize uintptr) VP8StatusCode {
153+ return xWebPIAppend(idec, data, dataSize)
154+}
155+func WebPIUpdate(idec uintptr, data *byte, dataSize uintptr) VP8StatusCode {
156+ return xWebPIUpdate(idec, data, dataSize)
157+}
158+func WebPIDecGetRGB(idec uintptr, lastY *int32, width *int32, height *int32, stride *int32) *byte {
159+ return xWebPIDecGetRGB(idec, lastY, width, height, stride)
160+}
161+func WebPIDecGetYUVA(idec uintptr, lastY *int32, u **byte, v **byte, a **byte, width *int32, height *int32, stride *int32, uvStride *int32, aStride *int32) *byte {
162+ return xWebPIDecGetYUVA(idec, lastY, u, v, a, width, height, stride, uvStride, aStride)
163+}
164+func WebPIDecodedArea(idec uintptr, left *int32, top *int32, width *int32, height *int32) *WebPDecBuffer {
165+ return xWebPIDecodedArea(idec, left, top, width, height)
166+}
167+func WebPIDecode(data *byte, dataSize uintptr, config *WebPDecoderConfig) uintptr {
168+ return xWebPIDecode(data, dataSize, config)
169+}
170+func WebPEncodeRGBA(rgba *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr {
171+ return xWebPEncodeRGBA(rgba, width, height, stride, quality, output)
172+}
173+func WebPEncodeRGB(rgb *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr {
174+ return xWebPEncodeRGB(rgb, width, height, stride, quality, output)
175+}
176+func WebPEncodeBGR(bgr *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr {
177+ return xWebPEncodeBGR(bgr, width, height, stride, quality, output)
178+}
179+func WebPEncodeBGRA(bgra *byte, width int32, height int32, stride int32, quality float32, output **byte) uintptr {
180+ return xWebPEncodeBGRA(bgra, width, height, stride, quality, output)
181+}
182+func WebPEncodeLosslessRGBA(rgba *byte, width int32, height int32, stride int32, output **byte) uintptr {
183+ return xWebPEncodeLosslessRGBA(rgba, width, height, stride, output)
184+}
185+func WebPEncodeLosslessRGB(rgb *byte, width int32, height int32, stride int32, output **byte) uintptr {
186+ return xWebPEncodeLosslessRGB(rgb, width, height, stride, output)
187+}
188+func WebPEncodeLosslessBGR(bgr *byte, width int32, height int32, stride int32, output **byte) uintptr {
189+ return xWebPEncodeLosslessBGR(bgr, width, height, stride, output)
190+}
191+func WebPEncodeLosslessBGRA(bgra *byte, width int32, height int32, stride int32, output **byte) uintptr {
192+ return xWebPEncodeLosslessBGRA(bgra, width, height, stride, output)
193+}
194+func WebPConfigInitInternal(config *WebPConfig, preset int32, quality float32, abiVersion int32) int32 {
195+ return xWebPConfigInitInternal(config, preset, quality, abiVersion)
196+}
197+func WebPConfigLosslessPreset(config *WebPConfig, level int32) int32 {
198+ return xWebPConfigLosslessPreset(config, level)
199+}
200+func WebPValidateConfig(config *WebPConfig) int32 {
201+ return xWebPValidateConfig(config)
202+}
203+func WebPMemoryWriterInit(writer *WebPMemoryWriter) {
204+ xWebPMemoryWriterInit(writer)
205+}
206+func WebPMemoryWriterClear(writer *WebPMemoryWriter) {
207+ xWebPMemoryWriterClear(writer)
208+}
209+func WebPMemoryWrite(data *byte, dataSize uintptr, picture *WebPPicture) int32 {
210+ return xWebPMemoryWrite(data, dataSize, picture)
211+}
212+func WebPPictureInitInternal(picture *WebPPicture, abiVersion int32) int32 {
213+ return xWebPPictureInitInternal(picture, abiVersion)
214+}
215+func WebPPictureAlloc(picture *WebPPicture) int32 {
216+ return xWebPPictureAlloc(picture)
217+}
218+func WebPPictureFree(picture *WebPPicture) {
219+ xWebPPictureFree(picture)
220+}
221+func WebPPictureCopy(src *WebPPicture, dst *WebPPicture) int32 {
222+ return xWebPPictureCopy(src, dst)
223+}
224+func WebPPictureCrop(picture *WebPPicture, left int32, top int32, width int32, height int32) int32 {
225+ return xWebPPictureCrop(picture, left, top, width, height)
226+}
227+func WebPPictureView(src *WebPPicture, left int32, top int32, width int32, height int32, dst *WebPPicture) int32 {
228+ return xWebPPictureView(src, left, top, width, height, dst)
229+}
230+func WebPPictureIsView(picture *WebPPicture) int32 {
231+ return xWebPPictureIsView(picture)
232+}
233+func WebPPictureRescale(picture *WebPPicture, width int32, height int32) int32 {
234+ return xWebPPictureRescale(picture, width, height)
235+}
236+func WebPPictureImportRGB(picture *WebPPicture, rgb *byte, rgbStride int32) int32 {
237+ return xWebPPictureImportRGB(picture, rgb, rgbStride)
238+}
239+func WebPPictureImportRGBA(picture *WebPPicture, rgba *byte, rgbaStride int32) int32 {
240+ return xWebPPictureImportRGBA(picture, rgba, rgbaStride)
241+}
242+func WebPPictureImportRGBX(picture *WebPPicture, rgbx *byte, rgbxStride int32) int32 {
243+ return xWebPPictureImportRGBX(picture, rgbx, rgbxStride)
244+}
245+func WebPPictureImportBGR(picture *WebPPicture, bgr *byte, bgrStride int32) int32 {
246+ return xWebPPictureImportBGR(picture, bgr, bgrStride)
247+}
248+func WebPPictureImportBGRA(picture *WebPPicture, bgra *byte, bgraStride int32) int32 {
249+ return xWebPPictureImportBGRA(picture, bgra, bgraStride)
250+}
251+func WebPPictureImportBGRX(picture *WebPPicture, bgrx *byte, bgrxStride int32) int32 {
252+ return xWebPPictureImportBGRX(picture, bgrx, bgrxStride)
253+}
254+func WebPPictureARGBToYUVA(picture *WebPPicture, colorspace int32) int32 {
255+ return xWebPPictureARGBToYUVA(picture, colorspace)
256+}
257+func WebPPictureARGBToYUVADithered(picture *WebPPicture, colorspace int32, dithering float32) int32 {
258+ return xWebPPictureARGBToYUVADithered(picture, colorspace, dithering)
259+}
260+func WebPPictureSharpARGBToYUVA(picture *WebPPicture) int32 {
261+ return xWebPPictureSharpARGBToYUVA(picture)
262+}
263+func WebPPictureSmartARGBToYUVA(picture *WebPPicture) int32 {
264+ return xWebPPictureSmartARGBToYUVA(picture)
265+}
266+func WebPPictureYUVAToARGB(picture *WebPPicture) int32 {
267+ return xWebPPictureYUVAToARGB(picture)
268+}
269+func WebPCleanupTransparentArea(picture *WebPPicture) {
270+ xWebPCleanupTransparentArea(picture)
271+}
272+func WebPPictureHasTransparency(picture *WebPPicture) int32 {
273+ return xWebPPictureHasTransparency(picture)
274+}
275+func WebPBlendAlpha(picture *WebPPicture, backgroundRGB uint32) {
276+ xWebPBlendAlpha(picture, backgroundRGB)
277+}
278+func WebPPlaneDistortion(src *byte, srcStride uintptr, ref *byte, refStride uintptr, width int32, height int32, xStep uintptr, distType int32, distortion *float32, result *float32) int32 {
279+ return xWebPPlaneDistortion(src, srcStride, ref, refStride, width, height, xStep, distType, distortion, result)
280+}
281+func WebPPictureDistortion(src *WebPPicture, ref *WebPPicture, metricType int32, result *float32) int32 {
282+ return xWebPPictureDistortion(src, ref, metricType, result)
283+}
284+func WebPEncode(config *WebPConfig, picture *WebPPicture) int32 {
285+ return xWebPEncode(config, picture)
286+}
287+func WebPFree(ptr uintptr) {
288+ xWebPFree(ptr)
289+}
290+func WebPGetDecoderVersion() int32 {
291+ return xWebPGetDecoderVersion()
292+}
293+func WebPGetEncoderVersion() int32 {
294+ return xWebPGetEncoderVersion()
295+}
296+func registerAll(lib uintptr) error {
297+ if err := register(lib, &xWebPGetInfo, "WebPGetInfo"); err != nil {
298+ return err
299+ }
300+ if err := register(lib, &xWebPDecodeRGBA, "WebPDecodeRGBA"); err != nil {
301+ return err
302+ }
303+ if err := register(lib, &xWebPDecodeARGB, "WebPDecodeARGB"); err != nil {
304+ return err
305+ }
306+ if err := register(lib, &xWebPDecodeBGRA, "WebPDecodeBGRA"); err != nil {
307+ return err
308+ }
309+ if err := register(lib, &xWebPDecodeRGB, "WebPDecodeRGB"); err != nil {
310+ return err
311+ }
312+ if err := register(lib, &xWebPDecodeBGR, "WebPDecodeBGR"); err != nil {
313+ return err
314+ }
315+ if err := register(lib, &xWebPDecodeRGBAInto, "WebPDecodeRGBAInto"); err != nil {
316+ return err
317+ }
318+ if err := register(lib, &xWebPDecodeARGBInto, "WebPDecodeARGBInto"); err != nil {
319+ return err
320+ }
321+ if err := register(lib, &xWebPDecodeBGRAInto, "WebPDecodeBGRAInto"); err != nil {
322+ return err
323+ }
324+ if err := register(lib, &xWebPDecodeRGBInto, "WebPDecodeRGBInto"); err != nil {
325+ return err
326+ }
327+ if err := register(lib, &xWebPDecodeBGRInto, "WebPDecodeBGRInto"); err != nil {
328+ return err
329+ }
330+ if err := register(lib, &xWebPDecodeYUV, "WebPDecodeYUV"); err != nil {
331+ return err
332+ }
333+ if err := register(lib, &xWebPDecodeYUVInto, "WebPDecodeYUVInto"); err != nil {
334+ return err
335+ }
336+ if err := register(lib, &xWebPGetFeaturesInternal, "WebPGetFeaturesInternal"); err != nil {
337+ return err
338+ }
339+ if err := register(lib, &xWebPInitDecBufferInternal, "WebPInitDecBufferInternal"); err != nil {
340+ return err
341+ }
342+ if err := register(lib, &xWebPFreeDecBuffer, "WebPFreeDecBuffer"); err != nil {
343+ return err
344+ }
345+ if err := register(lib, &xWebPInitDecoderConfigInternal, "WebPInitDecoderConfigInternal"); err != nil {
346+ return err
347+ }
348+ registerOptional(lib, &xWebPValidateDecoderConfig, "WebPValidateDecoderConfig")
349+ if err := register(lib, &xWebPDecode, "WebPDecode"); err != nil {
350+ return err
351+ }
352+ if err := register(lib, &xWebPINewDecoder, "WebPINewDecoder"); err != nil {
353+ return err
354+ }
355+ if err := register(lib, &xWebPINewRGB, "WebPINewRGB"); err != nil {
356+ return err
357+ }
358+ if err := register(lib, &xWebPINewYUVA, "WebPINewYUVA"); err != nil {
359+ return err
360+ }
361+ if err := register(lib, &xWebPINewYUV, "WebPINewYUV"); err != nil {
362+ return err
363+ }
364+ if err := register(lib, &xWebPIDelete, "WebPIDelete"); err != nil {
365+ return err
366+ }
367+ if err := register(lib, &xWebPIAppend, "WebPIAppend"); err != nil {
368+ return err
369+ }
370+ if err := register(lib, &xWebPIUpdate, "WebPIUpdate"); err != nil {
371+ return err
372+ }
373+ if err := register(lib, &xWebPIDecGetRGB, "WebPIDecGetRGB"); err != nil {
374+ return err
375+ }
376+ if err := register(lib, &xWebPIDecGetYUVA, "WebPIDecGetYUVA"); err != nil {
377+ return err
378+ }
379+ if err := register(lib, &xWebPIDecodedArea, "WebPIDecodedArea"); err != nil {
380+ return err
381+ }
382+ if err := register(lib, &xWebPIDecode, "WebPIDecode"); err != nil {
383+ return err
384+ }
385+ if err := register(lib, &xWebPEncodeRGBA, "WebPEncodeRGBA"); err != nil {
386+ return err
387+ }
388+ if err := register(lib, &xWebPEncodeRGB, "WebPEncodeRGB"); err != nil {
389+ return err
390+ }
391+ if err := register(lib, &xWebPEncodeBGR, "WebPEncodeBGR"); err != nil {
392+ return err
393+ }
394+ if err := register(lib, &xWebPEncodeBGRA, "WebPEncodeBGRA"); err != nil {
395+ return err
396+ }
397+ if err := register(lib, &xWebPEncodeLosslessRGBA, "WebPEncodeLosslessRGBA"); err != nil {
398+ return err
399+ }
400+ if err := register(lib, &xWebPEncodeLosslessRGB, "WebPEncodeLosslessRGB"); err != nil {
401+ return err
402+ }
403+ if err := register(lib, &xWebPEncodeLosslessBGR, "WebPEncodeLosslessBGR"); err != nil {
404+ return err
405+ }
406+ if err := register(lib, &xWebPEncodeLosslessBGRA, "WebPEncodeLosslessBGRA"); err != nil {
407+ return err
408+ }
409+ if err := register(lib, &xWebPConfigInitInternal, "WebPConfigInitInternal"); err != nil {
410+ return err
411+ }
412+ if err := register(lib, &xWebPConfigLosslessPreset, "WebPConfigLosslessPreset"); err != nil {
413+ return err
414+ }
415+ if err := register(lib, &xWebPValidateConfig, "WebPValidateConfig"); err != nil {
416+ return err
417+ }
418+ if err := register(lib, &xWebPMemoryWriterInit, "WebPMemoryWriterInit"); err != nil {
419+ return err
420+ }
421+ if err := register(lib, &xWebPMemoryWriterClear, "WebPMemoryWriterClear"); err != nil {
422+ return err
423+ }
424+ if err := register(lib, &xWebPMemoryWrite, "WebPMemoryWrite"); err != nil {
425+ return err
426+ }
427+ if err := register(lib, &xWebPPictureInitInternal, "WebPPictureInitInternal"); err != nil {
428+ return err
429+ }
430+ if err := register(lib, &xWebPPictureAlloc, "WebPPictureAlloc"); err != nil {
431+ return err
432+ }
433+ if err := register(lib, &xWebPPictureFree, "WebPPictureFree"); err != nil {
434+ return err
435+ }
436+ if err := register(lib, &xWebPPictureCopy, "WebPPictureCopy"); err != nil {
437+ return err
438+ }
439+ if err := register(lib, &xWebPPictureCrop, "WebPPictureCrop"); err != nil {
440+ return err
441+ }
442+ if err := register(lib, &xWebPPictureView, "WebPPictureView"); err != nil {
443+ return err
444+ }
445+ if err := register(lib, &xWebPPictureIsView, "WebPPictureIsView"); err != nil {
446+ return err
447+ }
448+ if err := register(lib, &xWebPPictureRescale, "WebPPictureRescale"); err != nil {
449+ return err
450+ }
451+ if err := register(lib, &xWebPPictureImportRGB, "WebPPictureImportRGB"); err != nil {
452+ return err
453+ }
454+ if err := register(lib, &xWebPPictureImportRGBA, "WebPPictureImportRGBA"); err != nil {
455+ return err
456+ }
457+ if err := register(lib, &xWebPPictureImportRGBX, "WebPPictureImportRGBX"); err != nil {
458+ return err
459+ }
460+ if err := register(lib, &xWebPPictureImportBGR, "WebPPictureImportBGR"); err != nil {
461+ return err
462+ }
463+ if err := register(lib, &xWebPPictureImportBGRA, "WebPPictureImportBGRA"); err != nil {
464+ return err
465+ }
466+ if err := register(lib, &xWebPPictureImportBGRX, "WebPPictureImportBGRX"); err != nil {
467+ return err
468+ }
469+ if err := register(lib, &xWebPPictureARGBToYUVA, "WebPPictureARGBToYUVA"); err != nil {
470+ return err
471+ }
472+ if err := register(lib, &xWebPPictureARGBToYUVADithered, "WebPPictureARGBToYUVADithered"); err != nil {
473+ return err
474+ }
475+ if err := register(lib, &xWebPPictureSharpARGBToYUVA, "WebPPictureSharpARGBToYUVA"); err != nil {
476+ return err
477+ }
478+ if err := register(lib, &xWebPPictureSmartARGBToYUVA, "WebPPictureSmartARGBToYUVA"); err != nil {
479+ return err
480+ }
481+ if err := register(lib, &xWebPPictureYUVAToARGB, "WebPPictureYUVAToARGB"); err != nil {
482+ return err
483+ }
484+ if err := register(lib, &xWebPCleanupTransparentArea, "WebPCleanupTransparentArea"); err != nil {
485+ return err
486+ }
487+ if err := register(lib, &xWebPPictureHasTransparency, "WebPPictureHasTransparency"); err != nil {
488+ return err
489+ }
490+ if err := register(lib, &xWebPBlendAlpha, "WebPBlendAlpha"); err != nil {
491+ return err
492+ }
493+ if err := register(lib, &xWebPPlaneDistortion, "WebPPlaneDistortion"); err != nil {
494+ return err
495+ }
496+ if err := register(lib, &xWebPPictureDistortion, "WebPPictureDistortion"); err != nil {
497+ return err
498+ }
499+ if err := register(lib, &xWebPEncode, "WebPEncode"); err != nil {
500+ return err
501+ }
502+ if err := register(lib, &xWebPFree, "WebPFree"); err != nil {
503+ return err
504+ }
505+ if err := register(lib, &xWebPGetDecoderVersion, "WebPGetDecoderVersion"); err != nil {
506+ return err
507+ }
508+ if err := register(lib, &xWebPGetEncoderVersion, "WebPGetEncoderVersion"); err != nil {
509+ return err
510+ }
511+
512+ return nil
513+}
A vendor/github.com/bnema/purego-webp/internal/libwebp/loader.go +86 -0 generated file: collapsed
A vendor/github.com/bnema/purego-webp/internal/libwebp/types.go +164 -0 generated file: collapsed
A vendor/github.com/bnema/purego-webp/libwebp/libwebp.go +880 -0 generated file: collapsed
M vendor/modules.txt +4 -0 generated file: collapsed

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