mirror of
https://github.com/lovell/sharp.git
synced 2025-12-19 07:15:08 +01:00
Ensure embedded profile, if any, is always used
Perform sRGB conversion at end of pipe only withMetadata exports profile, should not convert Convert one fixture to sRGB to help test Discovered while investigating #125
This commit is contained in:
@@ -117,6 +117,13 @@ namespace sharp {
|
||||
return image;
|
||||
}
|
||||
|
||||
/*
|
||||
Does this image have an embedded profile?
|
||||
*/
|
||||
bool HasProfile(VipsImage *image) {
|
||||
return (vips_image_get_typeof(image, VIPS_META_ICC_NAME) > 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
Does this image have an alpha channel?
|
||||
Uses colour space interpretation with number of channels to guess this.
|
||||
|
||||
@@ -44,6 +44,11 @@ namespace sharp {
|
||||
*/
|
||||
VipsImage* InitImage(ImageType imageType, char const *file, VipsAccess const access);
|
||||
|
||||
/*
|
||||
Does this image have an embedded profile?
|
||||
*/
|
||||
bool HasProfile(VipsImage *image);
|
||||
|
||||
/*
|
||||
Does this image have an alpha channel?
|
||||
Uses colour space interpretation with number of channels to guess this.
|
||||
|
||||
@@ -74,7 +74,7 @@ class MetadataWorker : public NanAsyncWorker {
|
||||
baton->height = image->Ysize;
|
||||
baton->space = vips_enum_nick(VIPS_TYPE_INTERPRETATION, image->Type);
|
||||
baton->channels = image->Bands;
|
||||
baton->hasProfile = (vips_image_get_typeof(image, VIPS_META_ICC_NAME) > 0) ? TRUE : FALSE;
|
||||
baton->hasProfile = HasProfile(image);
|
||||
// Derived attributes
|
||||
baton->hasAlpha = HasAlpha(image);
|
||||
baton->orientation = ExifOrientation(image);
|
||||
|
||||
@@ -269,33 +269,23 @@ class ResizeWorker : public NanAsyncWorker {
|
||||
image = shrunkOnLoad;
|
||||
}
|
||||
|
||||
// Handle colour profile, if any, for non sRGB images
|
||||
if (image->Type != VIPS_INTERPRETATION_sRGB) {
|
||||
// Get the input colour profile
|
||||
if (vips_image_get_typeof(image, VIPS_META_ICC_NAME)) {
|
||||
VipsImage *profile;
|
||||
// Use embedded profile
|
||||
if (vips_icc_import(image, &profile, "pcs", VIPS_PCS_XYZ, "embedded", TRUE, NULL)) {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
vips_object_local(hook, profile);
|
||||
image = profile;
|
||||
} else if (image->Type == VIPS_INTERPRETATION_CMYK) {
|
||||
VipsImage *profile;
|
||||
// CMYK with no embedded profile
|
||||
if (vips_icc_import(image, &profile, "pcs", VIPS_PCS_XYZ, "input_profile", (baton->iccProfileCmyk).c_str(), NULL)) {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
vips_object_local(hook, profile);
|
||||
image = profile;
|
||||
}
|
||||
// Attempt to convert to sRGB colour space
|
||||
VipsImage *colourspaced;
|
||||
if (vips_colourspace(image, &colourspaced, VIPS_INTERPRETATION_sRGB, NULL)) {
|
||||
// Ensure we're using a device-independent colour space
|
||||
if (HasProfile(image)) {
|
||||
// Convert to CIELAB using embedded profile
|
||||
VipsImage *profile;
|
||||
if (vips_icc_import(image, &profile, "pcs", VIPS_PCS_XYZ, "embedded", TRUE, NULL)) {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
vips_object_local(hook, colourspaced);
|
||||
image = colourspaced;
|
||||
vips_object_local(hook, profile);
|
||||
image = profile;
|
||||
} else if (image->Type == VIPS_INTERPRETATION_CMYK) {
|
||||
// Convert to CIELAB using default "USWebCoatedSWOP" CMYK profile
|
||||
VipsImage *profile;
|
||||
if (vips_icc_import(image, &profile, "pcs", VIPS_PCS_XYZ, "input_profile", (baton->iccProfileCmyk).c_str(), NULL)) {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
vips_object_local(hook, profile);
|
||||
image = profile;
|
||||
}
|
||||
|
||||
// Flatten image to remove alpha channel
|
||||
@@ -578,14 +568,22 @@ class ResizeWorker : public NanAsyncWorker {
|
||||
image = gammaDecoded;
|
||||
}
|
||||
|
||||
// Convert to sRGB colour space, if not already
|
||||
// Convert colour space to either sRGB or RGB-with-profile, if not already
|
||||
if (image->Type != VIPS_INTERPRETATION_sRGB) {
|
||||
VipsImage *colourspaced;
|
||||
if (vips_colourspace(image, &colourspaced, VIPS_INTERPRETATION_sRGB, NULL)) {
|
||||
return Error(baton, hook);
|
||||
VipsImage *rgb;
|
||||
if (baton->withMetadata && HasProfile(image)) {
|
||||
// Convert to device-dependent RGB using embedded profile of input
|
||||
if (vips_icc_export(image, &rgb, NULL)) {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
} else {
|
||||
// Convert to device-independent sRGB
|
||||
if (vips_colourspace(image, &rgb, VIPS_INTERPRETATION_sRGB, NULL)) {
|
||||
return Error(baton, hook);
|
||||
}
|
||||
}
|
||||
vips_object_local(hook, colourspaced);
|
||||
image = colourspaced;
|
||||
vips_object_local(hook, rgb);
|
||||
image = rgb;
|
||||
}
|
||||
|
||||
#if !(VIPS_MAJOR_VERSION >= 7 && VIPS_MINOR_VERSION >= 40 && VIPS_MINOR_VERSION >= 5)
|
||||
|
||||
Reference in New Issue
Block a user