diff --git a/README.md b/README.md index 065cb83..609fbf7 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Here you can see some performance test comparisons for multiple scenarios: #### Benchmarks -Tested using Go 1.4 and libvips-7.42.3 in OSX i7 2.7Ghz +Tested using Go 1.4.2 and libvips-7.42.3 in OSX i7 2.7Ghz ``` BenchmarkResizeLargeJpeg 50 43400480 ns/op BenchmarkResizePng 20 57592174 ns/op @@ -237,6 +237,11 @@ Run the process passing the `DEBUG` environment variable DEBUG=* ./app ``` +Enable libvips traces (note that a lot of data will be written in stdout): +``` +VIPS_TRACE=1 ./app +``` + #### func DetermineImageTypeName ```go diff --git a/vips.go b/vips.go index 5d7a966..d92c1ba 100644 --- a/vips.go +++ b/vips.go @@ -9,6 +9,7 @@ import "C" import ( "errors" + "os" "runtime" "strings" "sync" @@ -68,9 +69,19 @@ func Initialize() { panic("unable to start vips!") } - C.vips_concurrency_set(0) // default - C.vips_cache_set_max_mem(100 * 1024 * 1024) // 100 MB - C.vips_cache_set_max(500) // 500 operations + C.vips_cache_set_max_mem(100 * 1024 * 1024) + C.vips_cache_set_max(500) + + // Explicit concurrency limit to avoid thread-unsafe issues. + // See: https://github.com/jcupitt/libvips/issues/261#issuecomment-92850414 + if os.Getenv("VIPS_CONCURRENCY") == "" { + C.vips_concurrency_set(1) + } + + if os.Getenv("VIPS_TRACE") != "" { + C.vips_enable_cache_set_trace() + } + initialized = true } @@ -113,7 +124,9 @@ func vipsHasProfile(image *C.struct__VipsImage) bool { } func vipsWindowSize(name string) float64 { - return float64(C.interpolator_window_size(C.CString(name))) + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + return float64(C.interpolator_window_size(cname)) } func vipsSpace(image *C.struct__VipsImage) string { @@ -175,7 +188,7 @@ func vipsWatermark(image *C.struct__VipsImage, w Watermark) (*C.struct__VipsImag defer C.free(unsafe.Pointer(text)) defer C.free(unsafe.Pointer(font)) - err := C.vips_watermark(image, &out, (*C.watermarkTextOptions)(unsafe.Pointer(&textOpts)), (*C.watermarkOptions)(unsafe.Pointer(&opts))) + err := C.vips_watermark(image, &out, (*C.WatermarkTextOptions)(unsafe.Pointer(&textOpts)), (*C.WatermarkOptions)(unsafe.Pointer(&opts))) if err != 0 { return nil, catchVipsError() } diff --git a/vips.h b/vips.h index d0de8e9..445a755 100644 --- a/vips.h +++ b/vips.h @@ -14,7 +14,7 @@ enum types { typedef struct { const char *Text; const char *Font; -} watermarkTextOptions; +} WatermarkTextOptions; typedef struct { int Width; @@ -23,7 +23,7 @@ typedef struct { int NoReplicate; float Opacity; double Background[3]; -} watermarkOptions; +} WatermarkOptions; int vips_affine_interpolator(VipsImage *in, VipsImage **out, double a, double b, double c, double d, VipsInterpolate *interpolator) @@ -187,7 +187,7 @@ vips_watermark_replicate(VipsImage *orig, VipsImage *in, VipsImage **out) }; int -vips_watermark(VipsImage *in, VipsImage **out, watermarkTextOptions *to, watermarkOptions *o) +vips_watermark(VipsImage *in, VipsImage **out, WatermarkTextOptions *to, WatermarkOptions *o) { double ones[3] = { 1, 1, 1 }; @@ -244,3 +244,8 @@ vips_watermark(VipsImage *in, VipsImage **out, watermarkTextOptions *to, waterma return 0; }; +void +vips_enable_cache_set_trace() +{ + vips_cache_set_trace(TRUE); +};