Browse Source

Optimize memory usage

DarthSim 7 years ago
parent
commit
aa4e6731dc
3 changed files with 31 additions and 15 deletions
  1. 1 1
      main.go
  2. 16 6
      process.go
  3. 14 8
      vips.h

+ 1 - 1
main.go

@@ -13,7 +13,7 @@ import (
 func main() {
 	// Force garbage collection
 	go func() {
-		for _ = range time.Tick(time.Second) {
+		for _ = range time.Tick(10 * time.Second) {
 			debug.FreeOSMemory()
 		}
 	}()

+ 16 - 6
process.go

@@ -88,7 +88,6 @@ func initVips() {
 		log.Fatalln("unable to start vips!")
 	}
 
-	C.vips_concurrency_set(1)
 	C.vips_cache_set_max_mem(100 * 1024 * 1024) // 100Mb
 	C.vips_cache_set_max(500)
 
@@ -100,6 +99,13 @@ func initVips() {
 	vipsSupportSmartcrop = C.vips_support_smartcrop() == 1
 }
 
+func randomAccessRequired(po processingOptions) int {
+	if po.gravity == SMART {
+		return 1
+	}
+	return 0
+}
+
 func vipsTypeSupportedLoad(imgtype imageType) bool {
 	switch imgtype {
 	case JPEG:
@@ -173,6 +179,10 @@ func calcCrop(width, height int, po processingOptions) (left, top int) {
 func processImage(data []byte, imgtype imageType, po processingOptions) ([]byte, error) {
 	defer keepAlive(data)
 
+	if po.gravity == SMART && !vipsSupportSmartcrop {
+		return nil, errors.New("Smart crop is not supported by used version of libvips")
+	}
+
 	err := C.int(0)
 
 	var img *C.struct__VipsImage
@@ -183,13 +193,13 @@ func processImage(data []byte, imgtype imageType, po processingOptions) ([]byte,
 	// Load the image
 	switch imgtype {
 	case JPEG:
-		err = C.vips_jpegload_buffer_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &img)
+		err = C.vips_jpegload_buffer_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &img, C.int(randomAccessRequired(po)))
 	case PNG:
-		err = C.vips_pngload_buffer_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &img)
+		err = C.vips_pngload_buffer_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &img, C.int(randomAccessRequired(po)))
 	case GIF:
-		err = C.vips_gifload_buffer_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &img)
+		err = C.vips_gifload_buffer_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &img, C.int(randomAccessRequired(po)))
 	case WEBP:
-		err = C.vips_webpload_buffer_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &img)
+		err = C.vips_webpload_buffer_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &img, C.int(randomAccessRequired(po)))
 	}
 	if err != 0 {
 		return nil, vipsError()
@@ -228,7 +238,7 @@ func processImage(data []byte, imgtype imageType, po processingOptions) ([]byte,
 			pCrop = 1
 			pWidth, pHeight = po.width, po.height
 
-			if po.gravity == SMART && vipsSupportSmartcrop {
+			if po.gravity == SMART {
 				pSmart = 1
 			} else {
 				pLeft, pTop = calcCrop(round(float64(imgWidth)*pScale), round(float64(imgHeight)*pScale), po)

+ 14 - 8
vips.h

@@ -26,6 +26,12 @@ clear_image(VipsImage **in) {
   g_clear_object(in);
 }
 
+VipsAccess
+access_mode(int random) {
+  if (random > 0) return VIPS_ACCESS_RANDOM;
+  return VIPS_ACCESS_SEQUENTIAL;
+}
+
 void
 swap_and_clear(VipsImage **in, VipsImage *out) {
   clear_image(in);
@@ -64,31 +70,31 @@ vips_type_find_save_go(int imgtype) {
 }
 
 int
-vips_jpegload_buffer_go(void *buf, size_t len, VipsImage **out)
+vips_jpegload_buffer_go(void *buf, size_t len, VipsImage **out, int random)
 {
-  return vips_jpegload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
+  return vips_jpegload_buffer(buf, len, out, "access", access_mode(random), NULL);
 }
 
 int
-vips_pngload_buffer_go(void *buf, size_t len, VipsImage **out)
+vips_pngload_buffer_go(void *buf, size_t len, VipsImage **out, int random)
 {
-  return vips_pngload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
+  return vips_pngload_buffer(buf, len, out, "access", access_mode(random), NULL);
 }
 
 int
-vips_gifload_buffer_go(void *buf, size_t len, VipsImage **out)
+vips_gifload_buffer_go(void *buf, size_t len, VipsImage **out, int random)
 {
 #if VIPS_SUPPORT_GIF
-  return vips_gifload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
+  return vips_gifload_buffer(buf, len, out, "access", access_mode(random), NULL);
 #else
   return 0;
 #endif
 }
 
 int
-vips_webpload_buffer_go(void *buf, size_t len, VipsImage **out)
+vips_webpload_buffer_go(void *buf, size_t len, VipsImage **out, int random)
 {
-  return vips_webpload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
+  return vips_webpload_buffer(buf, len, out, "access", access_mode(random), NULL);
 }
 
 int