Browse Source

Rotate after resize; Use most vips functions directly

DarthSim 7 years ago
parent
commit
50e68556d0
2 changed files with 79 additions and 112 deletions
  1. 37 20
      process.go
  2. 42 92
      vips.h

+ 37 - 20
process.go

@@ -19,11 +19,11 @@ import (
 type imageType int
 type imageType int
 
 
 const (
 const (
-	UNKNOWN imageType = iota
-	JPEG
-	PNG
-	WEBP
-	GIF
+	UNKNOWN = C.UNKNOWN
+	JPEG    = C.JPEG
+	PNG     = C.PNG
+	WEBP    = C.WEBP
+	GIF     = C.GIF
 )
 )
 
 
 var imageTypes = map[string]imageType{
 var imageTypes = map[string]imageType{
@@ -138,6 +138,33 @@ func round(f float64) int {
 	return int(f + .5)
 	return int(f + .5)
 }
 }
 
 
+func extractMeta(img *C.VipsImage) (int, int, int, int) {
+	width := int(img.Xsize)
+	height := int(img.Ysize)
+
+	angle := C.VIPS_ANGLE_D0
+	flip := C.FALSE
+
+	orientation := C.vips_get_exif_orientation(img)
+	if orientation >= 5 && orientation <= 8 {
+		width, height = height, width
+	}
+	if orientation == 3 || orientation == 4 {
+		angle = C.VIPS_ANGLE_D180
+	}
+	if orientation == 5 || orientation == 6 {
+		angle = C.VIPS_ANGLE_D90
+	}
+	if orientation == 7 || orientation == 8 {
+		angle = C.VIPS_ANGLE_D270
+	}
+	if orientation == 2 || orientation == 4 || orientation == 5 || orientation == 7 {
+		flip = C.TRUE
+	}
+
+	return width, height, angle, flip
+}
+
 func calcScale(width, height int, po processingOptions) float64 {
 func calcScale(width, height int, po processingOptions) float64 {
 	if (po.width == width && po.height == height) || (po.resize != FILL && po.resize != FIT) {
 	if (po.width == width && po.height == height) || (po.resize != FILL && po.resize != FIT) {
 		return 1
 		return 1
@@ -193,24 +220,14 @@ func processImage(data []byte, imgtype imageType, po processingOptions, t *timer
 	defer C.vips_cleanup()
 	defer C.vips_cleanup()
 
 
 	// Load the image
 	// Load the image
-	switch imgtype {
-	case JPEG:
-		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, C.int(randomAccessRequired(po)))
-	case GIF:
-		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, C.int(randomAccessRequired(po)))
-	}
+	err = C.vips_load_buffer(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.int(imgtype), &img)
 	if err != 0 {
 	if err != 0 {
 		return nil, vipsError()
 		return nil, vipsError()
 	}
 	}
 
 
 	t.Check()
 	t.Check()
 
 
-	imgWidth := int(img.Xsize)
-	imgHeight := int(img.Ysize)
+	imgWidth, imgHeight, angle, flip := extractMeta(img)
 
 
 	// Ensure we won't crop out of bounds
 	// Ensure we won't crop out of bounds
 	if !po.enlarge || po.resize == CROP {
 	if !po.enlarge || po.resize == CROP {
@@ -224,10 +241,10 @@ func processImage(data []byte, imgtype imageType, po processingOptions, t *timer
 	}
 	}
 
 
 	if po.width != imgWidth || po.height != imgHeight {
 	if po.width != imgWidth || po.height != imgHeight {
+		pResize, pCrop, pSmart := C.FALSE, C.FALSE, C.FALSE
+
 		var (
 		var (
-			pResize, pCrop               int
 			pScale                       float64
 			pScale                       float64
-			pSmart                       int
 			pLeft, pTop, pWidth, pHeight int
 			pLeft, pTop, pWidth, pHeight int
 		)
 		)
 
 
@@ -249,7 +266,7 @@ func processImage(data []byte, imgtype imageType, po processingOptions, t *timer
 			}
 			}
 		}
 		}
 
 
-		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))
+		err = C.vips_process_image(&img, C.gboolean(pResize), C.double(pScale), C.gboolean(pCrop), C.gboolean(pSmart), C.int(pLeft), C.int(pTop), C.int(pWidth), C.int(pHeight), C.VipsAngle(angle), C.gboolean(flip))
 		if err != 0 {
 		if err != 0 {
 			return nil, vipsError()
 			return nil, vipsError()
 		}
 		}

+ 42 - 92
vips.h

@@ -11,7 +11,8 @@
 #define EXIF_ORIENTATION "exif-ifd0-Orientation"
 #define EXIF_ORIENTATION "exif-ifd0-Orientation"
 
 
 enum types {
 enum types {
-  JPEG = 0,
+  UNKNOWN = 0,
+  JPEG,
   PNG,
   PNG,
   WEBP,
   WEBP,
   GIF
   GIF
@@ -32,12 +33,6 @@ g_free_go(void **buf) {
   g_free(*buf);
   g_free(*buf);
 }
 }
 
 
-VipsAccess
-access_mode(int random) {
-  if (random > 0) return VIPS_ACCESS_RANDOM;
-  return VIPS_ACCESS_SEQUENTIAL;
-}
-
 void
 void
 swap_and_clear(VipsImage **in, VipsImage *out) {
 swap_and_clear(VipsImage **in, VipsImage *out) {
   clear_image(in);
   clear_image(in);
@@ -76,27 +71,20 @@ vips_type_find_save_go(int imgtype) {
 }
 }
 
 
 int
 int
-vips_jpegload_buffer_go(void *buf, size_t len, VipsImage **out, int random) {
-  return vips_jpegload_buffer(buf, len, out, "access", access_mode(random), NULL);
-}
-
-int
-vips_pngload_buffer_go(void *buf, size_t len, VipsImage **out, int random) {
-  return vips_pngload_buffer(buf, len, out, "access", access_mode(random), NULL);
-}
-
-int
-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", access_mode(random), NULL);
-#else
-  return 0;
-#endif
-}
-
-int
-vips_webpload_buffer_go(void *buf, size_t len, VipsImage **out, int random) {
-  return vips_webpload_buffer(buf, len, out, "access", access_mode(random), NULL);
+vips_load_buffer(void *buf, size_t len, int imgtype, VipsImage **out) {
+  switch (imgtype) {
+    case JPEG:
+      return vips_jpegload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
+    case PNG:
+      return vips_pngload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
+    case WEBP:
+      return vips_webpload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
+    #if VIPS_SUPPORT_GIF
+    case GIF:
+      return vips_gifload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, NULL);
+    #endif
+  }
+  return 1;
 }
 }
 
 
 int
 int
@@ -111,39 +99,6 @@ vips_get_exif_orientation(VipsImage *image) {
 	return 1;
 	return 1;
 }
 }
 
 
-int
-vips_exif_rotate(VipsImage **img, int orientation) {
-  int err;
-  int angle = VIPS_ANGLE_D0;
-  gboolean flip = FALSE;
-
-  VipsImage *tmp;
-
-  if (orientation == 3 || orientation == 4) angle = VIPS_ANGLE_D180;
-  if (orientation == 5 || orientation == 6) angle = VIPS_ANGLE_D90;
-  if (orientation == 7 || orientation == 8) angle = VIPS_ANGLE_D270;
-  if (orientation == 2 || orientation == 4 || orientation == 5 || orientation == 7) {
-    flip = TRUE;
-  }
-
-  err = vips_rot(*img, &tmp, angle, NULL);
-  swap_and_clear(img, tmp);
-  if (err > 0) { return err; }
-
-  if (flip) {
-    err = vips_flip(*img, &tmp, VIPS_DIRECTION_HORIZONTAL, NULL);
-    swap_and_clear(img, tmp);
-    if (err > 0) { return err; }
-  }
-
-  return 0;
-}
-
-int
-vips_resize_go(VipsImage *in, VipsImage **out, double scale) {
-  return vips_resize(in, out, scale, NULL);
-}
-
 int
 int
 vips_support_smartcrop() {
 vips_support_smartcrop() {
 #if VIPS_SUPPORT_SMARTCROP
 #if VIPS_SUPPORT_SMARTCROP
@@ -154,55 +109,50 @@ vips_support_smartcrop() {
 }
 }
 
 
 int
 int
-vips_smartcrop_go(VipsImage *in, VipsImage **out, int width, int height) {
-#if VIPS_SUPPORT_SMARTCROP
-  return vips_smartcrop(in, out, width, height, NULL);
-#else
-  return 0;
-#endif
-}
-
-int
-vips_colourspace_go(VipsImage *in, VipsImage **out, VipsInterpretation space) {
-  return vips_colourspace(in, out, space, NULL);
-}
-
-int
-vips_extract_area_go(VipsImage *in, VipsImage **out, int left, int top, int width, int height) {
-  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) {
+vips_process_image(VipsImage **img, gboolean resize, double scale, gboolean crop, gboolean smart, int left, int top, int width, int height, VipsAngle angle, gboolean flip) {
   VipsImage *tmp;
   VipsImage *tmp;
   int err;
   int err;
 
 
-  int exif_orientation = vips_get_exif_orientation(*img);
-  if (exif_orientation > 1) {
-    vips_exif_rotate(img, exif_orientation);
+  if (resize && scale != 1.0) {
+    err = vips_resize(*img, &tmp, scale, NULL);
+    swap_and_clear(img, tmp);
     if (err > 0) { return 1; }
     if (err > 0) { return 1; }
   }
   }
 
 
-  if (resize > 0) {
-    err = vips_resize_go(*img, &tmp, scale);
+  if (angle != VIPS_ANGLE_D0 || flip) {
+    tmp = vips_image_copy_memory(*img);
     swap_and_clear(img, tmp);
     swap_and_clear(img, tmp);
-    if (err > 0) { return 1; }
+    if (tmp == NULL) { return 1; }
+
+    if (angle != VIPS_ANGLE_D0) {
+      err = vips_rot(*img, &tmp, angle, NULL);
+      swap_and_clear(img, tmp);
+      if (err > 0) { return err; }
+    }
+
+    if (flip) {
+      err = vips_flip(*img, &tmp, VIPS_DIRECTION_HORIZONTAL, NULL);
+      swap_and_clear(img, tmp);
+      if (err > 0) { return err; }
+    }
   }
   }
 
 
-  if (crop > 0) {
-    if (smart > 0) {
-      err = vips_smartcrop_go(*img, &tmp, width, height);
+  if (crop) {
+    if (smart) {
+      #if VIPS_SUPPORT_SMARTCROP
+      err = vips_smartcrop(*img, &tmp, width, height, NULL);
       swap_and_clear(img, tmp);
       swap_and_clear(img, tmp);
       if (err > 0) { return 1; }
       if (err > 0) { return 1; }
+      #endif
     } else {
     } else {
-      vips_extract_area_go(*img, &tmp, left, top, width, height);
+      vips_extract_area(*img, &tmp, left, top, width, height, NULL);
       swap_and_clear(img, tmp);
       swap_and_clear(img, tmp);
       if (err > 0) { return 1; }
       if (err > 0) { return 1; }
     }
     }
   }
   }
 
 
   if (vips_image_guess_interpretation(*img) != VIPS_INTERPRETATION_sRGB) {
   if (vips_image_guess_interpretation(*img) != VIPS_INTERPRETATION_sRGB) {
-    err = vips_colourspace_go(*img, &tmp, VIPS_INTERPRETATION_sRGB);
+    err = vips_colourspace(*img, &tmp, VIPS_INTERPRETATION_sRGB, NULL);
     swap_and_clear(img, tmp);
     swap_and_clear(img, tmp);
   }
   }