commit 61bcd809df050051345098e0c46884ccc52c8c97
parent 55f31ea7f7298c3aeb2a7b051784a7ff313f0d35
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date: Wed, 3 Jan 2024 16:30:32 +0800
lib/transpiled: add decode and fix asm panic
Signed-off-by: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Diffstat:
1 file changed, 44 insertions(+), 36 deletions(-)
diff --git a/lib/transpiled/webp/lib.go b/lib/transpiled/webp/lib.go
@@ -1,51 +1,59 @@
package webp
import (
- "unsafe"
+ "image"
+ "io"
+ "git.sr.ht/~jackmordaunt/go-libwebp/lib/common"
"modernc.org/libc"
)
-var tls *libc.TLS
-
-func EncodeImpl(
- in unsafe.Pointer,
- w int32,
- h int32,
- bps int32,
- q float32,
- out unsafe.Pointer,
-) (size uint64) {
- tls = libc.NewTLS()
+func DecodeImpl(buf []byte) (image.Image, error) {
+ disableVP8GetCPUInfo()
+ tls := libc.NewTLS()
defer tls.Close()
+ return common.Decode(buf, makeDecodeImpl(tls), makeFreeImpl(tls))
+}
+
+func EncodeImpl(w io.Writer, m *image.RGBA, quality float32) error {
+ tls := libc.NewTLS()
+ defer tls.Close()
+ return common.Encode(w, m, quality, makeEncodeImpl(tls), makeFreeImpl(tls))
+}
- if q >= 1.0 {
- size = WebPEncodeLosslessRGBA(
- tls,
- uintptr(in),
- w,
- h,
- bps,
- uintptr(out),
- )
- } else {
- size = WebPEncodeRGBA(
- tls,
- uintptr(in),
- w,
- h,
- bps,
- q,
- uintptr(out),
- )
+func makeDecodeImpl(tls *libc.TLS) common.DecoderFunc {
+ return func(data uintptr, data_size uint64, width, height uintptr) uintptr {
+ return WebPDecodeRGBA(tls, data, data_size, width, height)
}
+}
- return size
+func makeEncodeImpl(tls *libc.TLS) common.EncodeFunc {
+ return func(in uintptr, w, h, bps int32, q float32, out uintptr) uint64 {
+ if q >= 1.0 {
+ return WebPEncodeLosslessRGBA(tls, in, w, h, bps, out)
+ }
+ return WebPEncodeRGBA(tls, in, w, h, bps, q, out)
+ }
}
-func FreeImpl(ptr unsafe.Pointer) {
- if tls == nil {
- panic("tls is nil, invalid use of transpile api")
+func makeFreeImpl(tls *libc.TLS) common.FreeFunc {
+ return func(p uintptr) {
+ WebPFree(tls, p)
}
- WebPFree(tls, uintptr(ptr))
+}
+
+func disableVP8GetCPUInfo() {
+ // HACK: Avoid panic when decoding lossy webp data.
+ //
+ // Inline asm is used for CPU feature detection; ccgo doesn't support inline asm.
+ //
+ // libwebp uses this function pointer to check for any specialized CPU instructions.
+ // If not nil (which it is for well supported platforms, like amd64, and arm64), it will try
+ // to check CPU features using inline asm. ccgo inserts a panic for inline asm, thus using
+ // this will panic.
+ //
+ // To avoid this terrible fate, we must manually turn off the CPU feature detection by
+ // nil'ing out this function pointer. This must be done after package init since that is
+ // is when this value is set by the transpiled code.
+ VP8GetCPUInfo = 0
}