mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-09-27 12:07:59 +02:00
AsyncSource -> ImgproxySource
This commit is contained in:
146
vips/source.c
146
vips/source.c
@@ -1,166 +1,86 @@
|
||||
#include "source.h"
|
||||
|
||||
// --- async source ----------------------------------------------------------------------
|
||||
|
||||
// define glib subtype for vips async source
|
||||
#define VIPS_TYPE_ASYNC_SOURCE (vips_async_source_get_type())
|
||||
G_DEFINE_FINAL_TYPE(VipsAsyncSource, vips_async_source, VIPS_TYPE_SOURCE)
|
||||
#define VIPS_TYPE_IMGPROXY_SOURCE (vips_imgproxy_source_get_type())
|
||||
G_DEFINE_FINAL_TYPE(VipsImgproxySource, vips_imgproxy_source, VIPS_TYPE_SOURCE)
|
||||
|
||||
extern void closeAsyncReader(uintptr_t handle);
|
||||
extern gint64 asyncReaderSeek(uintptr_t handle, gint64 offset, int whence);
|
||||
extern gint64 asyncReaderRead(uintptr_t handle, gpointer buffer, gint64 size);
|
||||
|
||||
// loads jpeg from a source
|
||||
int
|
||||
vips_jpegload_source_go(VipsAsyncSource *source, int shrink, VipsImage **out)
|
||||
{
|
||||
if (shrink > 1)
|
||||
return vips_jpegload_source(VIPS_SOURCE(source), out, "shrink", shrink,
|
||||
NULL);
|
||||
|
||||
return vips_jpegload_source(VIPS_SOURCE(source), out, NULL);
|
||||
}
|
||||
|
||||
// loads xjl from source
|
||||
int
|
||||
vips_jxlload_source_go(VipsAsyncSource *source, int pages, VipsImage **out)
|
||||
{
|
||||
return vips_jxlload_source(VIPS_SOURCE(source), out, "n", pages, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_pngload_source_go(VipsAsyncSource *source, VipsImage **out, int unlimited)
|
||||
{
|
||||
return vips_pngload_source(
|
||||
VIPS_SOURCE(source), out,
|
||||
"unlimited", unlimited,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_webpload_source_go(VipsAsyncSource *source, double scale, int pages, VipsImage **out)
|
||||
{
|
||||
return vips_webpload_source(
|
||||
VIPS_SOURCE(source), out,
|
||||
"scale", scale,
|
||||
"n", pages,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_gifload_source_go(VipsAsyncSource *source, int pages, VipsImage **out)
|
||||
{
|
||||
return vips_gifload_source(VIPS_SOURCE(source), out, "access", VIPS_ACCESS_SEQUENTIAL, "n", pages, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_svgload_source_go(VipsAsyncSource *source, double scale, VipsImage **out, int unlimited)
|
||||
{
|
||||
// libvips limits the minimal scale to 0.001, so we have to scale down dpi
|
||||
// for lower scale values
|
||||
double dpi = 72.0;
|
||||
if (scale < 0.001) {
|
||||
dpi *= VIPS_MAX(scale / 0.001, 0.001);
|
||||
scale = 0.001;
|
||||
}
|
||||
|
||||
return vips_svgload_source(
|
||||
VIPS_SOURCE(source), out,
|
||||
"scale", scale,
|
||||
"dpi", dpi,
|
||||
"unlimited", unlimited,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_heifload_source_go(VipsAsyncSource *source, VipsImage **out, int thumbnail)
|
||||
{
|
||||
return vips_heifload_source(
|
||||
VIPS_SOURCE(source), out,
|
||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||
"thumbnail", thumbnail,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_tiffload_source_go(VipsAsyncSource *source, VipsImage **out)
|
||||
{
|
||||
return vips_tiffload_source(VIPS_SOURCE(source), out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
|
||||
}
|
||||
extern void closeImgproxyReader(uintptr_t handle);
|
||||
extern gint64 imgproxyReaderSeek(uintptr_t handle, gint64 offset, int whence);
|
||||
extern gint64 imgproxyReaderRead(uintptr_t handle, gpointer buffer, gint64 size);
|
||||
|
||||
// dereferences source
|
||||
void
|
||||
unref_source(VipsAsyncSource *source)
|
||||
unref_imgproxy_source(VipsImgproxySource *source)
|
||||
{
|
||||
VIPS_UNREF(source);
|
||||
}
|
||||
|
||||
// read function for vips async source
|
||||
// read function for vips imgproxy source
|
||||
static gint64
|
||||
vips_async_source_read(VipsSource *source, void *buffer, size_t length)
|
||||
vips_imgproxy_source_read(VipsSource *source, void *buffer, size_t length)
|
||||
{
|
||||
VipsAsyncSource *self = (VipsAsyncSource *) source;
|
||||
VipsImgproxySource *self = (VipsImgproxySource *) source;
|
||||
|
||||
gint64 read_length = asyncReaderRead(self->readerHandle, buffer, length);
|
||||
gint64 read_length = imgproxyReaderRead(self->readerHandle, buffer, length);
|
||||
if (read_length < 0) {
|
||||
vips_error("vips_async_source_read", "failed to read from async source");
|
||||
vips_error("vips_imgproxy_source_read", "failed to read from imgproxy source");
|
||||
}
|
||||
return read_length;
|
||||
}
|
||||
|
||||
// seek function for vips async source. whence can be SEEK_SET (0), SEEK_CUR (1), or SEEK_END (2).
|
||||
// seek function for vips imgproxy source. whence can be SEEK_SET (0), SEEK_CUR (1), or SEEK_END (2).
|
||||
static gint64
|
||||
vips_async_source_seek(VipsSource *source, gint64 offset, int whence)
|
||||
vips_imgproxy_source_seek(VipsSource *source, gint64 offset, int whence)
|
||||
{
|
||||
VipsAsyncSource *self = (VipsAsyncSource *) source;
|
||||
VipsImgproxySource *self = (VipsImgproxySource *) source;
|
||||
|
||||
gint64 actual_offset = asyncReaderSeek(self->readerHandle, offset, whence);
|
||||
gint64 actual_offset = imgproxyReaderSeek(self->readerHandle, offset, whence);
|
||||
|
||||
if (actual_offset < 0) {
|
||||
vips_error("vips_async_source_seek", "failed to seek in async source");
|
||||
vips_error("vips_imgproxy_source_seek", "failed to seek in imgproxy source");
|
||||
}
|
||||
|
||||
return actual_offset;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_async_source_dispose(GObject *gobject)
|
||||
vips_imgproxy_source_dispose(GObject *gobject)
|
||||
{
|
||||
VipsAsyncSource *source = (VipsAsyncSource *) gobject;
|
||||
VipsImgproxySource *source = (VipsImgproxySource *) gobject;
|
||||
|
||||
closeAsyncReader(source->readerHandle);
|
||||
closeImgproxyReader(source->readerHandle);
|
||||
|
||||
G_OBJECT_CLASS(vips_async_source_parent_class)->dispose(gobject);
|
||||
G_OBJECT_CLASS(vips_imgproxy_source_parent_class)->dispose(gobject);
|
||||
}
|
||||
|
||||
// attaches seek/read handlers to the async source class
|
||||
// attaches seek/read handlers to the imgproxy source class
|
||||
static void
|
||||
vips_async_source_class_init(VipsAsyncSourceClass *klass)
|
||||
vips_imgproxy_source_class_init(VipsImgproxySourceClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
|
||||
VipsObjectClass *object_class = VIPS_OBJECT_CLASS(klass);
|
||||
VipsSourceClass *source_class = VIPS_SOURCE_CLASS(klass);
|
||||
|
||||
object_class->nickname = "async_source";
|
||||
object_class->description = "async input source";
|
||||
object_class->nickname = "imgproxy_source";
|
||||
object_class->description = "imgproxy input source";
|
||||
|
||||
gobject_class->dispose = vips_async_source_dispose;
|
||||
gobject_class->dispose = vips_imgproxy_source_dispose;
|
||||
|
||||
source_class->read = vips_async_source_read;
|
||||
source_class->seek = vips_async_source_seek;
|
||||
source_class->read = vips_imgproxy_source_read;
|
||||
source_class->seek = vips_imgproxy_source_seek;
|
||||
}
|
||||
|
||||
// initializes the async source (nothing to do here yet)
|
||||
// initializes the imgproxy source (nothing to do here yet)
|
||||
static void
|
||||
vips_async_source_init(VipsAsyncSource *source)
|
||||
vips_imgproxy_source_init(VipsImgproxySource *source)
|
||||
{
|
||||
}
|
||||
|
||||
// creates a new async source with the given reader handle
|
||||
VipsAsyncSource *
|
||||
vips_new_async_source(uintptr_t readerHandle)
|
||||
// creates a new imgproxy source with the given reader handle
|
||||
VipsImgproxySource *
|
||||
vips_new_imgproxy_source(uintptr_t readerHandle)
|
||||
{
|
||||
VipsAsyncSource *source = g_object_new(VIPS_TYPE_ASYNC_SOURCE, NULL);
|
||||
VipsImgproxySource *source = g_object_new(VIPS_TYPE_IMGPROXY_SOURCE, NULL);
|
||||
source->readerHandle = readerHandle;
|
||||
return source;
|
||||
}
|
||||
|
@@ -13,16 +13,16 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//export closeAsyncReader
|
||||
func closeAsyncReader(handle C.uintptr_t) {
|
||||
//export closeImgproxyReader
|
||||
func closeImgproxyReader(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 {
|
||||
//export imgproxyReaderSeek
|
||||
func imgproxyReaderSeek(handle C.uintptr_t, offset C.int64_t, whence int) C.int64_t {
|
||||
h := cgo.Handle(handle)
|
||||
reader, ok := h.Value().(io.ReadSeeker)
|
||||
if !ok {
|
||||
@@ -39,8 +39,8 @@ func asyncReaderSeek(handle C.uintptr_t, offset C.int64_t, whence int) C.int64_t
|
||||
|
||||
// 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 {
|
||||
//export imgproxyReaderRead
|
||||
func imgproxyReaderRead(handle C.uintptr_t, pointer unsafe.Pointer, size C.int64_t) C.int64_t {
|
||||
h := cgo.Handle(handle)
|
||||
reader, ok := h.Value().(io.ReadSeeker)
|
||||
if !ok {
|
||||
@@ -59,7 +59,7 @@ func asyncReaderRead(handle C.uintptr_t, pointer unsafe.Pointer, size C.int64_t)
|
||||
}
|
||||
|
||||
// newVipsSource creates a new VipsAsyncSource from an io.ReadSeeker.
|
||||
func newVipsAsyncSource(r io.ReadSeeker) *C.VipsAsyncSource {
|
||||
func newVipsImgproxySource(r io.ReadSeeker) *C.VipsImgproxySource {
|
||||
handler := cgo.NewHandle(r)
|
||||
return C.vips_new_async_source(C.uintptr_t(handler))
|
||||
return C.vips_new_imgproxy_source(C.uintptr_t(handler))
|
||||
}
|
||||
|
@@ -4,29 +4,24 @@
|
||||
#include <vips/vips.h>
|
||||
#include <vips/connection.h>
|
||||
|
||||
#ifndef VIPS_IMGPROXY_SOURCE_H
|
||||
#define VIPS_IMGPROXY_SOURCE_H
|
||||
|
||||
// vips async source
|
||||
typedef struct _VipsAsyncSource {
|
||||
typedef struct _VipsImgproxySource {
|
||||
VipsSource source; // class designator
|
||||
uintptr_t readerHandle; // async reader handler
|
||||
} VipsAsyncSource;
|
||||
} VipsImgproxySource;
|
||||
|
||||
// glib class for vips async source
|
||||
typedef struct _VipsAsyncSourceClass {
|
||||
typedef struct _VipsImgproxySourceClass {
|
||||
VipsSourceClass parent_class;
|
||||
} VipsAsyncSourceClass;
|
||||
|
||||
// vips async source read functions
|
||||
int vips_jpegload_source_go(VipsAsyncSource *source, int shrink, VipsImage **out);
|
||||
int vips_jxlload_source_go(VipsAsyncSource *source, int pages, VipsImage **out);
|
||||
int vips_pngload_source_go(VipsAsyncSource *source, VipsImage **out, int unlimited);
|
||||
int vips_webpload_source_go(VipsAsyncSource *source, double scale, int pages, VipsImage **out);
|
||||
int vips_gifload_source_go(VipsAsyncSource *source, int pages, VipsImage **out);
|
||||
int vips_svgload_source_go(VipsAsyncSource *source, double scale, VipsImage **out, int unlimited);
|
||||
int vips_heifload_source_go(VipsAsyncSource *source, VipsImage **out, int thumbnail);
|
||||
int vips_tiffload_source_go(VipsAsyncSource *source, VipsImage **out);
|
||||
} VipsImgproxySourceClass;
|
||||
|
||||
// creates new vips async source from a reader handle
|
||||
VipsAsyncSource *vips_new_async_source(uintptr_t readerHandle);
|
||||
VipsImgproxySource *vips_new_imgproxy_source(uintptr_t readerHandle);
|
||||
|
||||
#endif
|
||||
|
||||
// unreferences the source, which leads to reader close
|
||||
void unref_source(VipsAsyncSource *source);
|
||||
void unref_imgproxy_source(VipsImgproxySource *source);
|
||||
|
52
vips/vips.c
52
vips/vips.c
@@ -55,37 +55,39 @@ vips_health()
|
||||
return res;
|
||||
}
|
||||
|
||||
// loads jpeg from a source
|
||||
int
|
||||
vips_jpegload_go(void *buf, size_t len, int shrink, VipsImage **out)
|
||||
vips_jpegload_source_go(VipsImgproxySource *source, int shrink, VipsImage **out)
|
||||
{
|
||||
if (shrink > 1)
|
||||
return vips_jpegload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, "shrink", shrink,
|
||||
return vips_jpegload_source(VIPS_SOURCE(source), out, "access", VIPS_ACCESS_SEQUENTIAL, "shrink", shrink,
|
||||
NULL);
|
||||
|
||||
return vips_jpegload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
|
||||
return vips_jpegload_source(VIPS_SOURCE(source), out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
|
||||
}
|
||||
|
||||
// loads xjl from source
|
||||
int
|
||||
vips_jxlload_source_go(VipsImgproxySource *source, int pages, VipsImage **out)
|
||||
{
|
||||
return vips_jxlload_source(VIPS_SOURCE(source), out, "access", VIPS_ACCESS_SEQUENTIAL, "n", pages, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_jxlload_go(void *buf, size_t len, int pages, VipsImage **out)
|
||||
vips_pngload_source_go(VipsImgproxySource *source, VipsImage **out, int unlimited)
|
||||
{
|
||||
return vips_jxlload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, "n", pages, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_pngload_go(void *buf, size_t len, VipsImage **out, int unlimited)
|
||||
{
|
||||
return vips_pngload_buffer(
|
||||
buf, len, out,
|
||||
return vips_pngload_source(
|
||||
VIPS_SOURCE(source), out,
|
||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||
"unlimited", unlimited,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_webpload_go(void *buf, size_t len, double scale, int pages, VipsImage **out)
|
||||
vips_webpload_source_go(VipsImgproxySource *source, double scale, int pages, VipsImage **out)
|
||||
{
|
||||
return vips_webpload_buffer(
|
||||
buf, len, out,
|
||||
return vips_webpload_source(
|
||||
VIPS_SOURCE(source), out,
|
||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||
"scale", scale,
|
||||
"n", pages,
|
||||
@@ -93,13 +95,13 @@ vips_webpload_go(void *buf, size_t len, double scale, int pages, VipsImage **out
|
||||
}
|
||||
|
||||
int
|
||||
vips_gifload_go(void *buf, size_t len, int pages, VipsImage **out)
|
||||
vips_gifload_source_go(VipsImgproxySource *source, int pages, VipsImage **out)
|
||||
{
|
||||
return vips_gifload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, "n", pages, NULL);
|
||||
return vips_gifload_source(VIPS_SOURCE(source), out, "access", VIPS_ACCESS_SEQUENTIAL, "n", pages, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out, int unlimited)
|
||||
vips_svgload_source_go(VipsImgproxySource *source, double scale, VipsImage **out, int unlimited)
|
||||
{
|
||||
// libvips limits the minimal scale to 0.001, so we have to scale down dpi
|
||||
// for lower scale values
|
||||
@@ -109,8 +111,8 @@ vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out, int unlimi
|
||||
scale = 0.001;
|
||||
}
|
||||
|
||||
return vips_svgload_buffer(
|
||||
buf, len, out,
|
||||
return vips_svgload_source(
|
||||
VIPS_SOURCE(source), out,
|
||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||
"scale", scale,
|
||||
"dpi", dpi,
|
||||
@@ -119,19 +121,19 @@ vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out, int unlimi
|
||||
}
|
||||
|
||||
int
|
||||
vips_heifload_go(void *buf, size_t len, VipsImage **out, int thumbnail)
|
||||
vips_heifload_source_go(VipsImgproxySource *source, VipsImage **out, int thumbnail)
|
||||
{
|
||||
return vips_heifload_buffer(
|
||||
buf, len, out,
|
||||
return vips_heifload_source(
|
||||
VIPS_SOURCE(source), out,
|
||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||
"thumbnail", thumbnail,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vips_tiffload_go(void *buf, size_t len, VipsImage **out)
|
||||
vips_tiffload_source_go(VipsImgproxySource *source, VipsImage **out)
|
||||
{
|
||||
return vips_tiffload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
|
||||
return vips_tiffload_source(VIPS_SOURCE(source), out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
|
12
vips/vips.go
12
vips/vips.go
@@ -345,7 +345,8 @@ func (img *Image) Load(imgdata *imagedata.ImageData, shrink int, scale float64,
|
||||
err := C.int(0)
|
||||
|
||||
reader := bytes.NewReader(imgdata.Data)
|
||||
source := newVipsAsyncSource(reader)
|
||||
source := newVipsImgproxySource(reader)
|
||||
defer C.unref_imgproxy_source(source)
|
||||
|
||||
switch imgdata.Type {
|
||||
case imagetype.JPEG:
|
||||
@@ -365,11 +366,9 @@ func (img *Image) Load(imgdata *imagedata.ImageData, shrink int, scale float64,
|
||||
case imagetype.TIFF:
|
||||
err = C.vips_tiffload_source_go(source, &tmp)
|
||||
default:
|
||||
C.unref_source(source)
|
||||
return newVipsError("Usupported image type to load")
|
||||
}
|
||||
if err != 0 {
|
||||
C.unref_source(source)
|
||||
return Error()
|
||||
}
|
||||
|
||||
@@ -393,10 +392,11 @@ func (img *Image) LoadThumbnail(imgdata *imagedata.ImageData) error {
|
||||
|
||||
var tmp *C.VipsImage
|
||||
|
||||
data := unsafe.Pointer(&imgdata.Data[0])
|
||||
dataSize := C.size_t(len(imgdata.Data))
|
||||
reader := bytes.NewReader(imgdata.Data)
|
||||
source := newVipsImgproxySource(reader)
|
||||
defer C.unref_imgproxy_source(source)
|
||||
|
||||
if err := C.vips_heifload_go(data, dataSize, &tmp, C.int(1)); err != 0 {
|
||||
if err := C.vips_heifload_source_go(source, &tmp, C.int(1)); err != 0 {
|
||||
return Error()
|
||||
}
|
||||
|
||||
|
17
vips/vips.h
17
vips/vips.h
@@ -4,6 +4,7 @@
|
||||
#include <vips/vips.h>
|
||||
#include <vips/vips7compat.h>
|
||||
#include <vips/vector.h>
|
||||
#include "source.h"
|
||||
|
||||
typedef struct _RGB {
|
||||
double r;
|
||||
@@ -22,14 +23,14 @@ int gif_resolution_limit();
|
||||
|
||||
int vips_health();
|
||||
|
||||
int vips_jpegload_go(void *buf, size_t len, int shrink, VipsImage **out);
|
||||
int vips_jxlload_go(void *buf, size_t len, int pages, VipsImage **out);
|
||||
int vips_pngload_go(void *buf, size_t len, VipsImage **out, int unlimited);
|
||||
int vips_webpload_go(void *buf, size_t len, double scale, int pages, VipsImage **out);
|
||||
int vips_gifload_go(void *buf, size_t len, int pages, VipsImage **out);
|
||||
int vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out, int unlimited);
|
||||
int vips_heifload_go(void *buf, size_t len, VipsImage **out, int thumbnail);
|
||||
int vips_tiffload_go(void *buf, size_t len, VipsImage **out);
|
||||
int vips_jpegload_source_go(VipsImgproxySource *source, int shrink, VipsImage **out);
|
||||
int vips_jxlload_source_go(VipsImgproxySource *source, int pages, VipsImage **out);
|
||||
int vips_pngload_source_go(VipsImgproxySource *source, VipsImage **out, int unlimited);
|
||||
int vips_webpload_source_go(VipsImgproxySource *source, double scale, int pages, VipsImage **out);
|
||||
int vips_gifload_source_go(VipsImgproxySource *source, int pages, VipsImage **out);
|
||||
int vips_svgload_source_go(VipsImgproxySource *source, double scale, VipsImage **out, int unlimited);
|
||||
int vips_heifload_source_go(VipsImgproxySource *source, VipsImage **out, int thumbnail);
|
||||
int vips_tiffload_source_go(VipsImgproxySource *source, VipsImage **out);
|
||||
|
||||
int vips_black_go(VipsImage **out, int width, int height, int bands);
|
||||
|
||||
|
Reference in New Issue
Block a user