1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-04-22 07:07:51 +02:00

Improved ICC profiles handling

This commit is contained in:
DarthSim 2020-11-18 12:22:23 +06:00
parent cc1665a4fe
commit 1260d27b0b
6 changed files with 40 additions and 20100 deletions

View File

@ -7,6 +7,7 @@
### Changed
- Disable scale-on-load for animated images since it causes many problems. Currently, only animated WebP is affected.
- Improved ICC profiles handling.
### Fix
- Fix `dpr` option.

File diff suppressed because it is too large Load Diff

View File

@ -371,7 +371,7 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
convertToLinear := conf.UseLinearColorspace && scale != 1
if convertToLinear || !img.IsSRGB() {
if err = img.ImportColourProfile(true); err != nil {
if err = img.ImportColourProfile(); err != nil {
return err
}
iccImported = true
@ -436,15 +436,15 @@ func transformImage(ctx context.Context, img *vipsImage, data []byte, po *proces
}
}
if !iccImported {
if err = img.ImportColourProfile(false); err != nil {
return err
}
}
if iccImported {
if err = img.RgbColourspace(); err != nil {
return err
}
} else {
if err = img.TransformColourProfile(); err != nil {
return err
}
}
transparentBg := po.Format.SupportsAlpha() && !po.Flatten

16
vips.c
View File

@ -34,9 +34,6 @@
#define VIPS_SUPPORT_AVIF \
(VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 9))
#define VIPS_SUPPORT_BUILTIN_ICC \
(VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 8))
#define VIPS_SUPPORT_COMPOSITE \
(VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 6))
@ -347,13 +344,18 @@ vips_has_embedded_icc(VipsImage *in) {
}
int
vips_support_builtin_icc() {
return VIPS_SUPPORT_BUILTIN_ICC;
vips_icc_import_go(VipsImage *in, VipsImage **out) {
if (vips_icc_import(in, out, "embedded", TRUE, "pcs", VIPS_PCS_XYZ, NULL))
return 1;
vips_image_remove(*out, VIPS_META_ICC_NAME);
return 0;
}
int
vips_icc_import_go(VipsImage *in, VipsImage **out, char *profile) {
if (vips_icc_import(in, out, "input_profile", profile, "embedded", TRUE, "pcs", VIPS_PCS_XYZ, NULL))
vips_icc_transform_go(VipsImage *in, VipsImage **out) {
if (vips_icc_transform(in, out, "sRGB", "embedded", TRUE, "pcs", VIPS_PCS_XYZ, NULL))
return 1;
vips_image_remove(*out, VIPS_META_ICC_NAME);

40
vips.go
View File

@ -503,7 +503,7 @@ func (img *vipsImage) Sharpen(sigma float32) error {
return nil
}
func (img *vipsImage) ImportColourProfile(evenSRGB bool) error {
func (img *vipsImage) ImportColourProfile() error {
var tmp *C.VipsImage
if img.VipsImage.Coding != C.VIPS_CODING_NONE {
@ -514,31 +514,16 @@ func (img *vipsImage) ImportColourProfile(evenSRGB bool) error {
return nil
}
profile := (*C.char)(nil)
if C.vips_has_embedded_icc(img.VipsImage) == 0 {
// No embedded profile
// If vips doesn't have built-in profile, use profile built-in to imgproxy for CMYK
// TODO: Remove this. Supporting built-in profiles is pain, vips does it better
if img.VipsImage.Type == C.VIPS_INTERPRETATION_CMYK && C.vips_support_builtin_icc() == 0 {
p, err := cmykProfilePath()
if err != nil {
return err
}
profile = cachedCString(p)
} else {
// imgproxy doesn't have built-in profile for other interpretations,
if img.VipsImage.Type != C.VIPS_INTERPRETATION_CMYK {
// vips doesn't have built-in profile for other interpretations,
// so we can't do anything here
return nil
}
}
// Don't import sRGB IEC61966 2.1 unless evenSRGB
if img.VipsImage.Type == C.VIPS_INTERPRETATION_sRGB && !evenSRGB && C.vips_icc_is_srgb_iec61966(img.VipsImage) != 0 {
return nil
}
if C.vips_icc_import_go(img.VipsImage, &tmp, profile) == 0 {
if C.vips_icc_import_go(img.VipsImage, &tmp) == 0 {
C.swap_and_clear(&img.VipsImage, tmp)
} else {
logWarning("Can't import ICC profile: %s", vipsError())
@ -547,6 +532,23 @@ func (img *vipsImage) ImportColourProfile(evenSRGB bool) error {
return nil
}
func (img *vipsImage) TransformColourProfile() error {
var tmp *C.VipsImage
// Don't transform is there's no embedded profile or embedded profile is sRGB
if C.vips_has_embedded_icc(img.VipsImage) == 0 || C.vips_icc_is_srgb_iec61966(img.VipsImage) == 1 {
return nil
}
if C.vips_icc_transform_go(img.VipsImage, &tmp) == 0 {
C.swap_and_clear(&img.VipsImage, tmp)
} else {
logWarning("Can't transform ICC profile: %s", vipsError())
}
return nil
}
func (img *vipsImage) IsSRGB() bool {
return img.VipsImage.Type == C.VIPS_INTERPRETATION_sRGB
}

4
vips.h
View File

@ -60,8 +60,8 @@ int vips_resize_with_premultiply(VipsImage *in, VipsImage **out, double scale);
int vips_icc_is_srgb_iec61966(VipsImage *in);
int vips_has_embedded_icc(VipsImage *in);
int vips_support_builtin_icc();
int vips_icc_import_go(VipsImage *in, VipsImage **out, char *profile);
int vips_icc_import_go(VipsImage *in, VipsImage **out);
int vips_icc_transform_go(VipsImage *in, VipsImage **out);
int vips_colourspace_go(VipsImage *in, VipsImage **out, VipsInterpretation cs);
int vips_rot_go(VipsImage *in, VipsImage **out, VipsAngle angle);