From 29e05dabaf0772bac57bad63b2e09ce1c9298c4b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 8 Mar 2018 13:11:54 +0000 Subject: [PATCH] icc_import attaches the input profile if used icc_import can take a fallback input profile in case the embedded one is broken or missing. If we use the fallback profile, this change attaches it to the output image. This means that icc_import will always output an image with the icc profile that was used to import it. This helps to make the behaviour of `thumbnail` more consistent. See https://github.com/jcupitt/libvips/issues/152 --- ChangeLog | 1 + libvips/colour/icc_transform.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 08aaab8c..282bd848 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ - better rounding behaviour in convolution means we hit the vector path more often - fix a crash if a delayed load failed [gsharpsh00ter] +- icc_import attaches the fallback profile if it used it 5/1/18 started 8.6.2 - vips_sink_screen() keeps a ref to the input image ... stops a rare race diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 9345c66b..7b9d0d53 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -36,6 +36,8 @@ * - remove lcms1 support, it was untested * 10/10/17 * - more input profile sanity tests + * 8/3/18 + * - attach fallback profile on import if we used it */ /* @@ -392,6 +394,10 @@ typedef struct _VipsIccImport { gboolean embedded; char *input_profile_filename; + /* Set if we ended up using the fallback input profile. + */ + gboolean used_fallback; + } VipsIccImport; typedef VipsIccClass VipsIccImportClass; @@ -615,6 +621,7 @@ static int vips_icc_import_build( VipsObject *object ) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); + VipsColour *colour = (VipsColour *) object; VipsColourCode *code = (VipsColourCode *) object; VipsIcc *icc = (VipsIcc *) object; VipsIccImport *import = (VipsIccImport *) object; @@ -637,9 +644,11 @@ vips_icc_import_build( VipsObject *object ) if( !icc->in_profile && code->in && - import->input_profile_filename ) + import->input_profile_filename ) { icc->in_profile = vips_icc_load_profile_file( class->nickname, code->in, import->input_profile_filename ); + import->used_fallback = TRUE; + } if( !icc->in_profile ) { vips_error( class->nickname, "%s", _( "no input profile" ) ); @@ -661,6 +670,26 @@ vips_icc_import_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_icc_import_parent_class )->build( object ) ) return( -1 ); + /* If we used the fallback profile, we need to attach it to the PCS + * image since the PCS image needs to know about a route back to + * device space. + * + * In the same way, we don't remove the embedded input profile on + * import. + */ + if( import->used_fallback ) { + char *data; + size_t length; + + if( !(data = vips__file_read_name( + import->input_profile_filename, + vips__icc_dir(), &length )) ) + return( -1 ); + + vips_image_set_blob( colour->out, VIPS_META_ICC_NAME, + (VipsCallbackFn) vips_free, data, length ); + } + return( 0 ); }