Explorar o código

Fix color management

DarthSim %!s(int64=6) %!d(string=hai) anos
pai
achega
79af765015
Modificáronse 3 ficheiros con 87 adicións e 21 borrados
  1. 41 11
      process.go
  2. 42 8
      vips.c
  3. 4 2
      vips.h

+ 41 - 11
process.go

@@ -154,6 +154,7 @@ func extractMeta(img *C.VipsImage) (int, int, int, bool) {
 	flip := false
 
 	orientation := C.vips_get_exif_orientation(img)
+
 	if orientation >= 5 && orientation <= 8 {
 		width, height = height, width
 	}
@@ -281,7 +282,9 @@ func transformImage(ctx context.Context, img **C.VipsImage, data []byte, po *pro
 
 	hasAlpha := vipsImageHasAlpha(*img)
 
-	if scale := calcScale(imgWidth, imgHeight, po, imgtype); scale != 1 {
+	scale := calcScale(imgWidth, imgHeight, po, imgtype)
+
+	if scale != 1 {
 		if imgtype == imageTypeSVG && data != nil {
 			// Load SVG with desired scale
 			if tmp, err := vipsLoadImage(data, imgtype, 1, scale, false); err == nil {
@@ -289,33 +292,45 @@ func transformImage(ctx context.Context, img **C.VipsImage, data []byte, po *pro
 			} else {
 				return err
 			}
+
+			scale = 1
 		} else {
 			// Do some shrink-on-load
 			if scale < 1.0 && data != nil {
 				if shrink := calcShink(scale, imgtype); shrink != 1 {
-					scale = scale * float64(shrink)
-
 					if tmp, err := vipsLoadImage(data, imgtype, shrink, 1.0, false); err == nil {
 						C.swap_and_clear(img, tmp)
 					} else {
 						return err
 					}
-				}
-			}
 
-			if err = vipsResize(img, scale, hasAlpha); err != nil {
-				return err
+					scale = scale * float64(shrink)
+				}
 			}
 		}
+	}
 
-		// Update actual image size after resize
-		imgWidth, imgHeight, _, _ = extractMeta(*img)
+	if err = vipsRad2Float(img); err != nil {
+		return err
 	}
 
 	if err = vipsImportColourProfile(img); err != nil {
 		return err
 	}
 
+	if err = vipsFixColourspace(img); err != nil {
+		return err
+	}
+
+	if scale != 1 {
+		if err = vipsResize(img, scale, hasAlpha); err != nil {
+			return err
+		}
+	}
+
+	// Update actual image size after resize
+	imgWidth, imgHeight, _, _ = extractMeta(*img)
+
 	checkTimeout(ctx)
 
 	if angle != C.VIPS_ANGLE_D0 || flip {
@@ -558,6 +573,8 @@ func processImage(ctx context.Context) ([]byte, context.CancelFunc, error) {
 		checkTimeout(ctx)
 	}
 
+	C.vips_strip_meta(img)
+
 	return vipsSaveImage(img, po.Format, po.Quality)
 }
 
@@ -642,7 +659,7 @@ func vipsSaveImage(img *C.VipsImage, imgtype imageType, quality int) ([]byte, co
 
 	switch imgtype {
 	case imageTypeJPEG:
-		err = C.vips_jpegsave_go(img, &ptr, &imgsize, 1, C.int(quality), cConf.JpegProgressive)
+		err = C.vips_jpegsave_go(img, &ptr, &imgsize, C.int(quality), cConf.JpegProgressive)
 	case imageTypePNG:
 		if err = C.vips_pngsave_go(img, &ptr, &imgsize, cConf.PngInterlaced, 1); err != 0 {
 			C.g_free_go(&ptr)
@@ -650,7 +667,7 @@ func vipsSaveImage(img *C.VipsImage, imgtype imageType, quality int) ([]byte, co
 			err = C.vips_pngsave_go(img, &ptr, &imgsize, cConf.PngInterlaced, 0)
 		}
 	case imageTypeWEBP:
-		err = C.vips_webpsave_go(img, &ptr, &imgsize, 1, C.int(quality))
+		err = C.vips_webpsave_go(img, &ptr, &imgsize, C.int(quality))
 	case imageTypeGIF:
 		err = C.vips_gifsave_go(img, &ptr, &imgsize)
 	case imageTypeICO:
@@ -713,6 +730,19 @@ func vipsCastUchar(img **C.VipsImage) error {
 	return nil
 }
 
+func vipsRad2Float(img **C.VipsImage) error {
+	var tmp *C.VipsImage
+
+	if C.vips_image_get_coding(*img) == C.VIPS_CODING_RAD {
+		if C.vips_rad2float_go(*img, &tmp) != 0 {
+			return vipsError()
+		}
+		C.swap_and_clear(img, tmp)
+	}
+
+	return nil
+}
+
 func vipsResize(img **C.VipsImage, scale float64, hasAlpa bool) error {
 	var tmp *C.VipsImage
 

+ 42 - 8
vips.c

@@ -116,17 +116,43 @@ vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out) {
   #endif
 }
 
+#ifdef VIPS_META_ORIENTATION
 int
 vips_get_exif_orientation(VipsImage *image) {
-	const char *orientation;
+  int orientation;
 
 	if (
-		vips_image_get_typeof(image, EXIF_ORIENTATION) != G_TYPE_INVALID &&
+		vips_image_get_typeof(image, VIPS_META_ORIENTATION) == G_TYPE_INT &&
+		vips_image_get_int(image, VIPS_META_ORIENTATION, &orientation) == 0
+	) return orientation;
+
+	return 1;
+}
+#else
+int
+vips_get_exif_orientation(VipsImage *image) {
+  const char *orientation;
+
+	if (
+		vips_image_get_typeof(image, EXIF_ORIENTATION) == VIPS_TYPE_REF_STRING &&
 		vips_image_get_string(image, EXIF_ORIENTATION, &orientation) == 0
-	) return atoi(&orientation[0]);
+	) return atoi(orientation);
 
 	return 1;
 }
+#endif // VIPS_META_ORIENTATION
+
+void
+vips_strip_meta(VipsImage *image) {
+  #ifdef VIPS_META_ORIENTATION
+	vips_image_remove(image, VIPS_META_ORIENTATION);
+  #endif
+
+	vips_image_remove(image, VIPS_META_EXIF_NAME);
+	vips_image_remove(image, VIPS_META_PHOTOSHOP_NAME);
+
+  vips_image_remove(image, EXIF_ORIENTATION);
+}
 
 int
 vips_support_smartcrop() {
@@ -170,6 +196,11 @@ vips_cast_go(VipsImage *in, VipsImage **out, VipsBandFormat format) {
   return vips_cast(in, out, format, NULL);
 }
 
+int
+vips_rad2float_go(VipsImage *in, VipsImage **out) {
+	return vips_rad2float(in, out, NULL);
+}
+
 int
 vips_resize_go(VipsImage *in, VipsImage **out, double scale) {
   return vips_resize(in, out, scale, NULL);
@@ -209,7 +240,10 @@ vips_resize_with_premultiply(VipsImage *in, VipsImage **out, double scale) {
 
 int
 vips_need_icc_import(VipsImage *in) {
-  return in->Type == VIPS_INTERPRETATION_CMYK;
+  return in->Type == VIPS_INTERPRETATION_CMYK &&
+		in->Coding == VIPS_CODING_NONE &&
+		(in->BandFmt == VIPS_FORMAT_UCHAR ||
+		 in->BandFmt == VIPS_FORMAT_USHORT);
 }
 
 int
@@ -442,8 +476,8 @@ vips_arrayjoin_go(VipsImage **in, VipsImage **out, int n) {
 }
 
 int
-vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int strip, int quality, int interlace) {
-  return vips_jpegsave_buffer(in, buf, len, "strip", strip, "Q", quality, "optimize_coding", TRUE, "interlace", interlace, NULL);
+vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int quality, int interlace) {
+  return vips_jpegsave_buffer(in, buf, len, "Q", quality, "optimize_coding", TRUE, "interlace", interlace, NULL);
 }
 
 int
@@ -455,8 +489,8 @@ vips_pngsave_go(VipsImage *in, void **buf, size_t *len, int interlace, int embed
 }
 
 int
-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);
+vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality) {
+  return vips_webpsave_buffer(in, buf, len, "Q", quality, NULL);
 }
 
 int

+ 4 - 2
vips.h

@@ -30,6 +30,7 @@ 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 vips_get_exif_orientation(VipsImage *image);
+void vips_strip_meta(VipsImage *image);
 
 int vips_support_smartcrop();
 
@@ -41,6 +42,7 @@ gboolean vips_image_hasalpha_go(VipsImage * in);
 int vips_copy_go(VipsImage *in, VipsImage **out);
 
 int vips_cast_go(VipsImage *in, VipsImage **out, VipsBandFormat format);
+int vips_rad2float_go(VipsImage *in, VipsImage **out);
 
 int vips_resize_go(VipsImage *in, VipsImage **out, double scale);
 int vips_resize_with_premultiply(VipsImage *in, VipsImage **out, double scale);
@@ -70,9 +72,9 @@ int vips_apply_watermark(VipsImage *in, VipsImage *watermark, VipsImage **out, d
 
 int vips_arrayjoin_go(VipsImage **in, VipsImage **out, int n);
 
-int vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int strip, int quality, int interlace);
+int vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int quality, int interlace);
 int vips_pngsave_go(VipsImage *in, void **buf, size_t *len, int interlace, int embed_profile);
-int vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int strip, int quality);
+int vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality);
 int vips_gifsave_go(VipsImage *in, void **buf, size_t *len);
 int vips_icosave_go(VipsImage *in, void **buf, size_t *len);