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
This commit is contained in:
John Cupitt 2018-03-08 13:11:54 +00:00
parent 178c2f399a
commit 29e05dabaf
2 changed files with 31 additions and 1 deletions

View File

@ -5,6 +5,7 @@
- better rounding behaviour in convolution means we hit the vector path more - better rounding behaviour in convolution means we hit the vector path more
often often
- fix a crash if a delayed load failed [gsharpsh00ter] - 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 5/1/18 started 8.6.2
- vips_sink_screen() keeps a ref to the input image ... stops a rare race - vips_sink_screen() keeps a ref to the input image ... stops a rare race

View File

@ -36,6 +36,8 @@
* - remove lcms1 support, it was untested * - remove lcms1 support, it was untested
* 10/10/17 * 10/10/17
* - more input profile sanity tests * - 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; gboolean embedded;
char *input_profile_filename; char *input_profile_filename;
/* Set if we ended up using the fallback input profile.
*/
gboolean used_fallback;
} VipsIccImport; } VipsIccImport;
typedef VipsIccClass VipsIccImportClass; typedef VipsIccClass VipsIccImportClass;
@ -615,6 +621,7 @@ static int
vips_icc_import_build( VipsObject *object ) vips_icc_import_build( VipsObject *object )
{ {
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
VipsColour *colour = (VipsColour *) object;
VipsColourCode *code = (VipsColourCode *) object; VipsColourCode *code = (VipsColourCode *) object;
VipsIcc *icc = (VipsIcc *) object; VipsIcc *icc = (VipsIcc *) object;
VipsIccImport *import = (VipsIccImport *) object; VipsIccImport *import = (VipsIccImport *) object;
@ -637,9 +644,11 @@ vips_icc_import_build( VipsObject *object )
if( !icc->in_profile && if( !icc->in_profile &&
code->in && code->in &&
import->input_profile_filename ) import->input_profile_filename ) {
icc->in_profile = vips_icc_load_profile_file( class->nickname, icc->in_profile = vips_icc_load_profile_file( class->nickname,
code->in, import->input_profile_filename ); code->in, import->input_profile_filename );
import->used_fallback = TRUE;
}
if( !icc->in_profile ) { if( !icc->in_profile ) {
vips_error( class->nickname, "%s", _( "no input 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 ) ) if( VIPS_OBJECT_CLASS( vips_icc_import_parent_class )->build( object ) )
return( -1 ); 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 ); return( 0 );
} }