|
@@ -8,12 +8,14 @@ package vips
|
|
*/
|
|
*/
|
|
import "C"
|
|
import "C"
|
|
import (
|
|
import (
|
|
|
|
+ "bytes"
|
|
"context"
|
|
"context"
|
|
"math"
|
|
"math"
|
|
"net/http"
|
|
"net/http"
|
|
"os"
|
|
"os"
|
|
"regexp"
|
|
"regexp"
|
|
"runtime"
|
|
"runtime"
|
|
|
|
+ "runtime/cgo"
|
|
"strings"
|
|
"strings"
|
|
"sync"
|
|
"sync"
|
|
"time"
|
|
"time"
|
|
@@ -329,6 +331,49 @@ func (img *Image) Pages() int {
|
|
return p
|
|
return p
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+//export closeAsyncReader
|
|
|
|
+func closeAsyncReader(handle C.uintptr_t) {
|
|
|
|
+ h := cgo.Handle(handle)
|
|
|
|
+ h.Delete()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// calls seek() on the async reader via it's handle from the C side
|
|
|
|
+//
|
|
|
|
+//export asyncReaderSeek
|
|
|
|
+func asyncReaderSeek(handle C.uintptr_t, offset C.int64_t, whence int) C.int64_t {
|
|
|
|
+ h := cgo.Handle(handle)
|
|
|
|
+ reader, ok := h.Value().(*bytes.Reader)
|
|
|
|
+ if !ok {
|
|
|
|
+ return -1
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pos, err := reader.Seek(int64(offset), whence)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return -1
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return C.int64_t(pos)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// calls read() on the async reader via it's handle from the C side
|
|
|
|
+//
|
|
|
|
+//export asyncReaderRead
|
|
|
|
+func asyncReaderRead(handle C.uintptr_t, pointer unsafe.Pointer, size C.int64_t) C.int64_t {
|
|
|
|
+ h := cgo.Handle(handle)
|
|
|
|
+ reader, ok := h.Value().(*bytes.Reader)
|
|
|
|
+ if !ok {
|
|
|
|
+ return -1
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ buf := unsafe.Slice((*byte)(pointer), size)
|
|
|
|
+ n, err := reader.Read(buf)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return -1
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return C.int64_t(n)
|
|
|
|
+}
|
|
|
|
+
|
|
func (img *Image) Load(imgdata *imagedata.ImageData, shrink int, scale float64, pages int) error {
|
|
func (img *Image) Load(imgdata *imagedata.ImageData, shrink int, scale float64, pages int) error {
|
|
if imgdata.Type == imagetype.ICO {
|
|
if imgdata.Type == imagetype.ICO {
|
|
return img.loadIco(imgdata.Data, shrink, scale, pages)
|
|
return img.loadIco(imgdata.Data, shrink, scale, pages)
|
|
@@ -344,9 +389,13 @@ func (img *Image) Load(imgdata *imagedata.ImageData, shrink int, scale float64,
|
|
dataSize := C.size_t(len(imgdata.Data))
|
|
dataSize := C.size_t(len(imgdata.Data))
|
|
err := C.int(0)
|
|
err := C.int(0)
|
|
|
|
|
|
|
|
+ reader := bytes.NewReader(imgdata.Data)
|
|
|
|
+ handler := cgo.NewHandle(reader)
|
|
|
|
+ source := C.vips_new_async_source(C.uintptr_t(handler))
|
|
|
|
+
|
|
switch imgdata.Type {
|
|
switch imgdata.Type {
|
|
case imagetype.JPEG:
|
|
case imagetype.JPEG:
|
|
- err = C.vips_jpegload_go(data, dataSize, C.int(shrink), &tmp)
|
|
|
|
|
|
+ err = C.vips_jpegloadsource_go(source, C.int(shrink), &tmp)
|
|
case imagetype.JXL:
|
|
case imagetype.JXL:
|
|
err = C.vips_jxlload_go(data, dataSize, C.int(pages), &tmp)
|
|
err = C.vips_jxlload_go(data, dataSize, C.int(pages), &tmp)
|
|
case imagetype.PNG:
|
|
case imagetype.PNG:
|
|
@@ -362,12 +411,15 @@ func (img *Image) Load(imgdata *imagedata.ImageData, shrink int, scale float64,
|
|
case imagetype.TIFF:
|
|
case imagetype.TIFF:
|
|
err = C.vips_tiffload_go(data, dataSize, &tmp)
|
|
err = C.vips_tiffload_go(data, dataSize, &tmp)
|
|
default:
|
|
default:
|
|
|
|
+ C.close_source(nil, source)
|
|
return newVipsError("Usupported image type to load")
|
|
return newVipsError("Usupported image type to load")
|
|
}
|
|
}
|
|
if err != 0 {
|
|
if err != 0 {
|
|
|
|
+ C.close_source(nil, source)
|
|
return Error()
|
|
return Error()
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ C.vips_attach_image_close_signals(&tmp, C.uintptr_t(handler), source)
|
|
C.swap_and_clear(&img.VipsImage, tmp)
|
|
C.swap_and_clear(&img.VipsImage, tmp)
|
|
|
|
|
|
if imgdata.Type == imagetype.TIFF {
|
|
if imgdata.Type == imagetype.TIFF {
|