Browse Source

Tune up processing

DarthSim 7 years ago
parent
commit
7e1b9408a4
2 changed files with 79 additions and 50 deletions
  1. 28 36
      process.go
  2. 51 14
      vips.h

+ 28 - 36
process.go

@@ -76,6 +76,8 @@ type processingOptions struct {
 	format  imageType
 	format  imageType
 }
 }
 
 
+var vipsSupportSmartcrop bool
+
 func initVips() {
 func initVips() {
 	runtime.LockOSThread()
 	runtime.LockOSThread()
 	defer runtime.UnlockOSThread()
 	defer runtime.UnlockOSThread()
@@ -88,6 +90,8 @@ func initVips() {
 	C.vips_concurrency_set(1)
 	C.vips_concurrency_set(1)
 	C.vips_cache_set_max_mem(100 * 1024 * 1024) // 100Mb
 	C.vips_cache_set_max_mem(100 * 1024 * 1024) // 100Mb
 	C.vips_cache_set_max(500)
 	C.vips_cache_set_max(500)
+
+	vipsSupportSmartcrop = C.vips_support_smartcrop() == 1
 }
 }
 
 
 func vipsTypeSupportedLoad(imgtype imageType) bool {
 func vipsTypeSupportedLoad(imgtype imageType) bool {
@@ -165,13 +169,9 @@ func processImage(data []byte, imgtype imageType, po processingOptions) ([]byte,
 
 
 	err := C.int(0)
 	err := C.int(0)
 
 
-	var img, tmpImg *C.struct__VipsImage
+	var img *C.struct__VipsImage
 
 
-	// Cleanup after all
-	defer func() {
-		C.vips_thread_shutdown()
-		C.vips_error_clear()
-	}()
+	defer C.vips_cleanup()
 
 
 	// Load the image
 	// Load the image
 	switch imgtype {
 	switch imgtype {
@@ -203,43 +203,35 @@ func processImage(data []byte, imgtype imageType, po processingOptions) ([]byte,
 	}
 	}
 
 
 	if po.width != imgWidth || po.height != imgHeight {
 	if po.width != imgWidth || po.height != imgHeight {
-		// Resize image for "fill" and "fit"
+		var (
+			pResize, pCrop               int
+			pScale                       float64
+			pSmart                       int
+			pLeft, pTop, pWidth, pHeight int
+		)
+
 		if po.resize == FILL || po.resize == FIT {
 		if po.resize == FILL || po.resize == FIT {
-			scale := calcScale(imgWidth, imgHeight, po)
-			err = C.vips_resize_go(img, &tmpImg, C.double(scale))
-			C.g_object_unref(C.gpointer(img))
-			img = tmpImg
-			if err != 0 {
-				return nil, vipsError()
-			}
+			pResize = 1
+			pScale = calcScale(imgWidth, imgHeight, po)
+		} else {
+			pScale = 1.0
 		}
 		}
-		// Crop image for "fill" and "crop"
+
 		if po.resize == FILL || po.resize == CROP {
 		if po.resize == FILL || po.resize == CROP {
-			if po.gravity == SMART && C.vips_support_smartcrop() == 1 {
-				err = C.vips_smartcrop_go(img, &tmpImg, C.int(po.width), C.int(po.height))
-				C.g_object_unref(C.gpointer(img))
-				img = tmpImg
-				if err != 0 {
-					return nil, vipsError()
-				}
+			pCrop = 1
+			pWidth, pHeight = po.width, po.height
+
+			if po.gravity == SMART && vipsSupportSmartcrop {
+				pSmart = 1
 			} else {
 			} else {
-				left, top := calcCrop(int(img.Xsize), int(img.Ysize), po)
-				err = C.vips_extract_area_go(img, &tmpImg, C.int(left), C.int(top), C.int(po.width), C.int(po.height))
-				C.g_object_unref(C.gpointer(img))
-				img = tmpImg
-				if err != 0 {
-					return nil, vipsError()
-				}
+				pLeft, pTop = calcCrop(round(float64(imgWidth)*pScale), round(float64(imgHeight)*pScale), po)
 			}
 			}
 		}
 		}
-	}
 
 
-	// Convert to sRGB colour space
-	err = C.vips_colourspace_go(img, &tmpImg, C.VIPS_INTERPRETATION_sRGB)
-	C.g_object_unref(C.gpointer(img))
-	img = tmpImg
-	if err != 0 {
-		return nil, vipsError()
+		err = C.vips_process_image(&img, C.int(pResize), C.double(pScale), C.int(pCrop), C.int(pSmart), C.int(pLeft), C.int(pTop), C.int(pWidth), C.int(pHeight))
+		if err != 0 {
+			return nil, vipsError()
+		}
 	}
 	}
 
 
 	// Finally, save
 	// Finally, save

+ 51 - 14
vips.h

@@ -5,9 +5,6 @@
 #define VIPS_SUPPORT_SMARTCROP \
 #define VIPS_SUPPORT_SMARTCROP \
   (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 5))
   (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 5))
 
 
-#define VIPS_SUPPORT_RESIZE_KERNEL \
-  (VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION > 3) || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 3 && VIPS_MICRO_VERSION >= 1))
-
 enum types {
 enum types {
 	JPEG = 0,
 	JPEG = 0,
   PNG,
   PNG,
@@ -21,6 +18,12 @@ vips_initialize()
   return vips_init("imgproxy");
   return vips_init("imgproxy");
 }
 }
 
 
+void
+swap_and_clear(VipsImage **in, VipsImage *out) {
+  g_object_unref((gpointer) *in);
+  *in = out;
+}
+
 int
 int
 vips_type_find_load_go(int imgtype) {
 vips_type_find_load_go(int imgtype) {
   if (imgtype == JPEG) {
   if (imgtype == JPEG) {
@@ -56,35 +59,31 @@ int
 vips_jpegload_buffer_go(void *buf, size_t len, VipsImage **out)
 vips_jpegload_buffer_go(void *buf, size_t len, VipsImage **out)
 {
 {
   return vips_jpegload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
   return vips_jpegload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
-};
+}
 
 
 int
 int
 vips_pngload_buffer_go(void *buf, size_t len, VipsImage **out)
 vips_pngload_buffer_go(void *buf, size_t len, VipsImage **out)
 {
 {
   return vips_pngload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
   return vips_pngload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
-};
+}
 
 
 int
 int
 vips_gifload_buffer_go(void *buf, size_t len, VipsImage **out)
 vips_gifload_buffer_go(void *buf, size_t len, VipsImage **out)
 {
 {
   return vips_gifload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
   return vips_gifload_buffer(buf, len, out, "access", VIPS_ACCESS_RANDOM, NULL);
-};
+}
 
 
 int
 int
 vips_webpload_buffer_go(void *buf, size_t len, VipsImage **out)
 vips_webpload_buffer_go(void *buf, size_t len, VipsImage **out)
 {
 {
   return vips_webpload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
   return vips_webpload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
-};
+}
 
 
 int
 int
 vips_resize_go(VipsImage *in, VipsImage **out, double scale)
 vips_resize_go(VipsImage *in, VipsImage **out, double scale)
 {
 {
-#if VIPS_SUPPORT_RESIZE_KERNEL
-  return vips_resize(in, out, scale, "kernel", VIPS_KERNEL_LANCZOS3, NULL);
-#else
   return vips_resize(in, out, scale, NULL);
   return vips_resize(in, out, scale, NULL);
-#endif
-};
+}
 
 
 int
 int
 vips_support_smartcrop() {
 vips_support_smartcrop() {
@@ -108,7 +107,7 @@ int
 vips_colourspace_go(VipsImage *in, VipsImage **out, VipsInterpretation space)
 vips_colourspace_go(VipsImage *in, VipsImage **out, VipsInterpretation space)
 {
 {
   return vips_colourspace(in, out, space, NULL);
   return vips_colourspace(in, out, space, NULL);
-};
+}
 
 
 int
 int
 vips_extract_area_go(VipsImage *in, VipsImage **out, int left, int top, int width, int height)
 vips_extract_area_go(VipsImage *in, VipsImage **out, int left, int top, int width, int height)
@@ -116,6 +115,36 @@ vips_extract_area_go(VipsImage *in, VipsImage **out, int left, int top, int widt
   return vips_extract_area(in, out, left, top, width, height, NULL);
   return vips_extract_area(in, out, left, top, width, height, NULL);
 }
 }
 
 
+int
+vips_process_image(VipsImage **img, int resize, double scale, int crop, int smart, int left, int top, int width, int height)
+{
+  VipsImage *tmp;
+  int err;
+
+  if (resize > 0) {
+    err = vips_resize_go(*img, &tmp, scale);
+    swap_and_clear(img, tmp);
+    if (err> 0) { return 1; }
+  }
+
+  if (crop > 0) {
+    if (smart > 0) {
+      err = vips_smartcrop_go(*img, &tmp, width, height);
+      swap_and_clear(img, tmp);
+      if (err> 0) { return 1; }
+    } else {
+      vips_extract_area_go(*img, &tmp, left, top, width, height);
+      swap_and_clear(img, tmp);
+      if (err> 0) { return 1; }
+    }
+  }
+
+  err = vips_colourspace_go(*img, &tmp, VIPS_INTERPRETATION_sRGB);
+  swap_and_clear(img, tmp);
+
+  return err;
+}
+
 int
 int
 vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int strip, int quality, int interlace)
 vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int strip, int quality, int interlace)
 {
 {
@@ -129,6 +158,14 @@ vips_pngsave_go(VipsImage *in, void **buf, size_t *len)
 }
 }
 
 
 int
 int
-vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int strip, int quality) {
+vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int strip, int quality)
+{
 	return vips_webpsave_buffer(in, buf, len, "strip", strip, "Q", quality, NULL);
 	return vips_webpsave_buffer(in, buf, len, "strip", strip, "Q", quality, NULL);
 }
 }
+
+void
+vips_cleanup()
+{
+  vips_thread_shutdown();
+  vips_error_clear();
+}