mirror of
https://github.com/talgo-cloud/talgo-libwebp.git
synced 2026-03-09 07:28:20 -07:00
Merge pull request #3 from saturday06/fix/go1.6
Support rules for passing pointers between Go with C for Go 1.6.
This commit is contained in:
commit
10d006dab5
3 changed files with 85 additions and 14 deletions
|
|
@ -1,17 +1,21 @@
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.3
|
|
||||||
- 1.4
|
- 1.4
|
||||||
|
- 1.5
|
||||||
|
- 1.6
|
||||||
|
- tip
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- LIBWEBP_VERSION="0.4.1"
|
- LIBWEBP_VERSION="0.4.1"
|
||||||
- LIBWEBP_VERSION="0.4.2"
|
- LIBWEBP_VERSION="0.4.2"
|
||||||
|
- LIBWEBP_VERSION="0.4.3"
|
||||||
|
- LIBWEBP_VERSION="0.5.0"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -qq libjpeg-dev libpng-dev libtiff-dev libgif-dev
|
- sudo apt-get install -qq libjpeg-dev libpng-dev libtiff-dev libgif-dev
|
||||||
- >
|
- >
|
||||||
cd /tmp
|
cd /tmp
|
||||||
&& wget http://downloads.webmproject.org/releases/webp/libwebp-${LIBWEBP_VERSION}.tar.gz
|
&& wget http://downloads.webmproject.org/releases/webp/libwebp-${LIBWEBP_VERSION}.tar.gz
|
||||||
&& tar xf libwebp-${LIBWEBP_VERSION}.tar.gz
|
&& tar xf libwebp-${LIBWEBP_VERSION}.tar.gz
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,14 @@ package webp
|
||||||
|
|
||||||
int writeWebP(uint8_t*, size_t, struct WebPPicture*);
|
int writeWebP(uint8_t*, size_t, struct WebPPicture*);
|
||||||
|
|
||||||
|
static WebPPicture *malloc_WebPPicture(void) {
|
||||||
|
return malloc(sizeof(WebPPicture));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_WebPPicture(WebPPicture* webpPicture) {
|
||||||
|
free(webpPicture);
|
||||||
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
|
@ -15,6 +23,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"io"
|
"io"
|
||||||
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -38,9 +47,39 @@ type destinationManager struct {
|
||||||
writer io.Writer
|
writer io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var destinationManagerMapMutex sync.RWMutex
|
||||||
|
var destinationManagerMap = make(map[uintptr]*destinationManager)
|
||||||
|
|
||||||
|
// GetDestinationManagerMapLen returns the number of globally working sourceManagers for debug
|
||||||
|
func GetDestinationManagerMapLen() int {
|
||||||
|
destinationManagerMapMutex.RLock()
|
||||||
|
defer destinationManagerMapMutex.RUnlock()
|
||||||
|
return len(destinationManagerMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeDestinationManager(w io.Writer, pic *C.WebPPicture) (mgr *destinationManager) {
|
||||||
|
mgr = &destinationManager{writer: w}
|
||||||
|
destinationManagerMapMutex.Lock()
|
||||||
|
defer destinationManagerMapMutex.Unlock()
|
||||||
|
destinationManagerMap[uintptr(unsafe.Pointer(pic))] = mgr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseDestinationManager(pic *C.WebPPicture) {
|
||||||
|
destinationManagerMapMutex.Lock()
|
||||||
|
defer destinationManagerMapMutex.Unlock()
|
||||||
|
delete(destinationManagerMap, uintptr(unsafe.Pointer(pic)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDestinationManager(pic *C.WebPPicture) *destinationManager {
|
||||||
|
destinationManagerMapMutex.RLock()
|
||||||
|
defer destinationManagerMapMutex.RUnlock()
|
||||||
|
return destinationManagerMap[uintptr(unsafe.Pointer(pic))]
|
||||||
|
}
|
||||||
|
|
||||||
//export writeWebP
|
//export writeWebP
|
||||||
func writeWebP(data *C.uint8_t, size C.size_t, pic *C.WebPPicture) C.int {
|
func writeWebP(data *C.uint8_t, size C.size_t, pic *C.WebPPicture) C.int {
|
||||||
mgr := (*destinationManager)(unsafe.Pointer(pic.custom_ptr))
|
mgr := getDestinationManager(pic)
|
||||||
bytes := C.GoBytes(unsafe.Pointer(data), C.int(size))
|
bytes := C.GoBytes(unsafe.Pointer(data), C.int(size))
|
||||||
_, err := mgr.writer.Write(bytes)
|
_, err := mgr.writer.Write(bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -57,30 +96,37 @@ func EncodeRGBA(w io.Writer, img image.Image, c Config) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var pic C.WebPPicture
|
pic := C.malloc_WebPPicture()
|
||||||
if C.WebPPictureInit(&pic) == 0 {
|
if pic == nil {
|
||||||
|
return errors.New("Could not allocate webp picture")
|
||||||
|
}
|
||||||
|
defer C.free_WebPPicture(pic)
|
||||||
|
|
||||||
|
makeDestinationManager(w, pic)
|
||||||
|
defer releaseDestinationManager(pic)
|
||||||
|
|
||||||
|
if C.WebPPictureInit(pic) == 0 {
|
||||||
return errors.New("Could not initialize webp picture")
|
return errors.New("Could not initialize webp picture")
|
||||||
}
|
}
|
||||||
|
defer C.WebPPictureFree(pic)
|
||||||
|
|
||||||
pic.use_argb = 1
|
pic.use_argb = 1
|
||||||
|
|
||||||
pic.width = C.int(img.Bounds().Dx())
|
pic.width = C.int(img.Bounds().Dx())
|
||||||
pic.height = C.int(img.Bounds().Dy())
|
pic.height = C.int(img.Bounds().Dy())
|
||||||
|
|
||||||
pic.writer = C.WebPWriterFunction(C.writeWebP)
|
pic.writer = C.WebPWriterFunction(C.writeWebP)
|
||||||
pic.custom_ptr = unsafe.Pointer(&destinationManager{writer: w})
|
|
||||||
|
|
||||||
switch p := img.(type) {
|
switch p := img.(type) {
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
C.WebPPictureImportRGBA(&pic, (*C.uint8_t)(&p.Pix[0]), C.int(p.Stride))
|
C.WebPPictureImportRGBA(pic, (*C.uint8_t)(&p.Pix[0]), C.int(p.Stride))
|
||||||
case *image.NRGBA:
|
case *image.NRGBA:
|
||||||
C.WebPPictureImportRGBA(&pic, (*C.uint8_t)(&p.Pix[0]), C.int(p.Stride))
|
C.WebPPictureImportRGBA(pic, (*C.uint8_t)(&p.Pix[0]), C.int(p.Stride))
|
||||||
default:
|
default:
|
||||||
return errors.New("unsupported image type")
|
return errors.New("unsupported image type")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer C.WebPPictureFree(&pic)
|
if C.WebPEncode(webpConfig, pic) == 0 {
|
||||||
|
|
||||||
if C.WebPEncode(webpConfig, &pic) == 0 {
|
|
||||||
return fmt.Errorf("Encoding error: %d", pic.error_code)
|
return fmt.Errorf("Encoding error: %d", pic.error_code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,10 +140,20 @@ func EncodeYUVA(w io.Writer, img *YUVAImage, c Config) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var pic C.WebPPicture
|
pic := C.malloc_WebPPicture()
|
||||||
if C.WebPPictureInit(&pic) == 0 {
|
if pic == nil {
|
||||||
|
return errors.New("Could not allocate webp picture")
|
||||||
|
}
|
||||||
|
defer C.free_WebPPicture(pic)
|
||||||
|
|
||||||
|
makeDestinationManager(w, pic)
|
||||||
|
defer releaseDestinationManager(pic)
|
||||||
|
|
||||||
|
if C.WebPPictureInit(pic) == 0 {
|
||||||
return errors.New("Could not initialize webp picture")
|
return errors.New("Could not initialize webp picture")
|
||||||
}
|
}
|
||||||
|
defer C.WebPPictureFree(pic)
|
||||||
|
|
||||||
pic.use_argb = 0
|
pic.use_argb = 0
|
||||||
pic.colorspace = C.WebPEncCSP(img.ColorSpace)
|
pic.colorspace = C.WebPEncCSP(img.ColorSpace)
|
||||||
pic.width = C.int(img.Rect.Dx())
|
pic.width = C.int(img.Rect.Dx())
|
||||||
|
|
@ -116,7 +172,7 @@ func EncodeYUVA(w io.Writer, img *YUVAImage, c Config) (err error) {
|
||||||
pic.writer = C.WebPWriterFunction(C.writeWebP)
|
pic.writer = C.WebPWriterFunction(C.writeWebP)
|
||||||
pic.custom_ptr = unsafe.Pointer(&destinationManager{writer: w})
|
pic.custom_ptr = unsafe.Pointer(&destinationManager{writer: w})
|
||||||
|
|
||||||
if C.WebPEncode(webpConfig, &pic) == 0 {
|
if C.WebPEncode(webpConfig, pic) == 0 {
|
||||||
return fmt.Errorf("Encoding error: %d", pic.error_code)
|
return fmt.Errorf("Encoding error: %d", pic.error_code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,24 @@ package webp_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/harukasan/go-libwebp/test/util"
|
"github.com/harukasan/go-libwebp/test/util"
|
||||||
"github.com/harukasan/go-libwebp/webp"
|
"github.com/harukasan/go-libwebp/webp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
result := m.Run()
|
||||||
|
if webp.GetDestinationManagerMapLen() > 0 {
|
||||||
|
fmt.Println("destinationManager leaked")
|
||||||
|
result = 2
|
||||||
|
}
|
||||||
|
os.Exit(result)
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Decode
|
// Decode
|
||||||
//
|
//
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue