source.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package vips
  2. /*
  3. #cgo pkg-config: vips
  4. #cgo CFLAGS: -O3
  5. #cgo LDFLAGS: -lm
  6. #include "source.h"
  7. #include "vips.h"
  8. */
  9. import "C"
  10. import (
  11. "fmt"
  12. "io"
  13. "runtime/cgo"
  14. "unsafe"
  15. )
  16. //export closeImgproxyReader
  17. func closeImgproxyReader(handle C.uintptr_t) {
  18. h := cgo.Handle(handle)
  19. h.Delete()
  20. }
  21. // calls seek() on the async reader via it's handle from the C side
  22. //
  23. //export imgproxyReaderSeek
  24. func imgproxyReaderSeek(handle C.uintptr_t, offset C.int64_t, whence int) C.int64_t {
  25. h := cgo.Handle(handle)
  26. reader, ok := h.Value().(io.ReadSeeker)
  27. if !ok {
  28. C.vips_error_go(cachedCString("imgproxyReaderSeek"), cachedCString("failed to cast handle to io.ReadSeeker"))
  29. return -1
  30. }
  31. pos, err := reader.Seek(int64(offset), whence)
  32. if err != nil {
  33. C.vips_error_go(cachedCString("imgproxyReaderSeek"), cachedCString("failed to seek"))
  34. return -1
  35. }
  36. return C.int64_t(pos)
  37. }
  38. // calls read() on the async reader via it's handle from the C side
  39. //
  40. //export imgproxyReaderRead
  41. func imgproxyReaderRead(handle C.uintptr_t, pointer unsafe.Pointer, size C.int64_t) C.int64_t {
  42. h := cgo.Handle(handle)
  43. reader, ok := h.Value().(io.ReadSeeker)
  44. if !ok {
  45. C.vips_error_go(cachedCString("imgproxyReaderRead"), cachedCString("invalid reader handle"))
  46. return -1
  47. }
  48. buf := unsafe.Slice((*byte)(pointer), size)
  49. n, err := reader.Read(buf)
  50. if err == io.EOF {
  51. return 0
  52. } else if err != nil {
  53. msg := fmt.Sprintf("error reading from imgproxy source: %v", err)
  54. C.vips_error_go(cachedCString("imgproxyReaderRead"), cachedCString(msg))
  55. return -1
  56. }
  57. return C.int64_t(n)
  58. }
  59. // newVipsSource creates a new VipsAsyncSource from an io.ReadSeeker.
  60. func newVipsImgproxySource(r io.ReadSeeker) *C.VipsImgproxySource {
  61. handler := cgo.NewHandle(r)
  62. return C.vips_new_imgproxy_source(C.uintptr_t(handler))
  63. }