lib.go (1788B)
1 package webp 2 3 import ( 4 "image" 5 "io" 6 7 "git.sr.ht/~jackmordaunt/go-libwebp/v2/lib/common" 8 "modernc.org/libc" 9 ) 10 11 func DecodeImpl(buf []byte) (image.Image, error) { 12 disableVP8GetCPUInfo() 13 tls := libc.NewTLS() 14 defer tls.Close() 15 return common.Decode(buf, makeDecodeImpl(tls), makeFreeImpl(tls)) 16 } 17 18 func EncodeImpl(w io.Writer, m *image.NRGBA, quality float32) error { 19 tls := libc.NewTLS() 20 defer tls.Close() 21 return common.Encode(w, m, quality, makeEncodeImpl(tls), makeFreeImpl(tls)) 22 } 23 24 func makeDecodeImpl(tls *libc.TLS) common.DecoderFunc { 25 return func(data uintptr, data_size uint64, width, height uintptr) uintptr { 26 return WebPDecodeRGBA(tls, data, data_size, width, height) 27 } 28 } 29 30 func makeEncodeImpl(tls *libc.TLS) common.EncodeFunc { 31 return func(in uintptr, w, h, bps int32, q float32, out uintptr) uint64 { 32 if q >= 1.0 { 33 return WebPEncodeLosslessRGBA(tls, in, w, h, bps, out) 34 } 35 return WebPEncodeRGBA(tls, in, w, h, bps, q*100, out) 36 } 37 } 38 39 func makeFreeImpl(tls *libc.TLS) common.FreeFunc { 40 return func(p uintptr) { 41 WebPFree(tls, p) 42 } 43 } 44 45 func disableVP8GetCPUInfo() { 46 // HACK: Avoid panic when decoding lossy webp data. 47 // 48 // Inline asm is used for CPU feature detection; ccgo doesn't support inline asm. 49 // 50 // libwebp uses this function pointer to check for any specialized CPU instructions. 51 // If not nil (which it is for well supported platforms, like amd64, and arm64), it will try 52 // to check CPU features using inline asm. ccgo inserts a panic for inline asm, thus using 53 // this will panic. 54 // 55 // To avoid this terrible fate, we must manually turn off the CPU feature detection by 56 // nil'ing out this function pointer. This must be done after package init since that is 57 // is when this value is set by the transpiled code. 58 VP8GetCPUInfo = 0 59 }