From 7d1ec908947b46ee7fa4d41e5156c570272cb572 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 2 Jan 2019 10:59:16 +0000 Subject: [PATCH] make fallback profiles available to icc_import etc. almost there, not working yet --- libvips/colour/CMYK2XYZ.c | 67 ++++++++++++++++++++++--------- libvips/colour/Makefile.am | 5 ++- libvips/colour/XYZ2CMYK.c | 2 +- libvips/colour/icc_transform.c | 47 +++++++++++++++++++--- libvips/colour/pcolour.h | 3 +- libvips/colour/profiles.c | 9 ++++- libvips/colour/profiles.h | 11 ++++- libvips/colour/profiles/sRGB.icm | Bin 0 -> 6922 bytes libvips/colour/wrap-profiles.sh | 31 ++++++-------- 9 files changed, 124 insertions(+), 51 deletions(-) create mode 100644 libvips/colour/profiles/sRGB.icm diff --git a/libvips/colour/CMYK2XYZ.c b/libvips/colour/CMYK2XYZ.c index 83e2603c..0abc074b 100644 --- a/libvips/colour/CMYK2XYZ.c +++ b/libvips/colour/CMYK2XYZ.c @@ -45,8 +45,8 @@ #include #include -#include "pcolour.h" #include "profiles.h" +#include "pcolour.h" typedef struct _VipsCMYK2XYZ { VipsOperation parent_instance; @@ -61,40 +61,66 @@ G_DEFINE_TYPE( VipsCMYK2XYZ, vips_CMYK2XYZ, VIPS_TYPE_OPERATION ); /* Created on first use from a base64 string in profiles.c. */ -static void *vips_CMYK2XYZ_fallback_profile = NULL; -static size_t vips_CMYK2XYZ_fallback_profile_length = 0; +typedef struct _VipsFallbackProfile { + const char *name; + void *data; + size_t data_length; +} VipsFallbackProfile; + +static GSList *vips_fallback_profile_list = NULL; static void * -vips_CMYK2XYZ_get_fallback_profile_init( void ) +vips__fallback_profile_get_init( void ) { - size_t data_length; - unsigned char *data; + int i; - if( !(data = vips__b64_decode( vips__coded_cmyk, &data_length )) ) - return( NULL ); - vips_CMYK2XYZ_fallback_profile = data; - vips_CMYK2XYZ_fallback_profile_length = data_length; + for( i = 0; vips__coded_profiles[i].name; i++ ) { + size_t data_length; + unsigned char *data; + VipsFallbackProfile *fallback; + + if( !(data = vips__b64_decode( + vips__coded_profiles[i].data, &data_length )) ) + return( NULL ); + fallback = g_new( VipsFallbackProfile,1 ); + fallback->name = vips__coded_profiles[i].name; + fallback->data = data; + fallback->data_length = data_length; + vips_fallback_profile_list = g_slist_append( + vips_fallback_profile_list, fallback ); + } return( NULL ); } -static void * -vips__CMYK2XYZ_get_fallback_profile( size_t *length ) +/* Shared with icc_transform.c + */ +void * +vips__fallback_profile_get( const char *name, size_t *length ) { GOnce once = G_ONCE_INIT; - VIPS_ONCE( &once, - (GThreadFunc) vips_CMYK2XYZ_get_fallback_profile_init, NULL ); + GSList *p; - *length = vips_CMYK2XYZ_fallback_profile_length; + VIPS_ONCE( &once, (GThreadFunc) vips__fallback_profile_get_init, NULL ); - return( vips_CMYK2XYZ_fallback_profile ); + for( p = vips_fallback_profile_list; p; p = p->next ) { + VipsFallbackProfile *fallback = (VipsFallbackProfile *) p->data; + + if( strcasecmp( fallback->name, name ) == 0 ) { + *length = fallback->data_length; + + return( fallback->data ); + } + } + + return( NULL ); } /* Shared with XYZ2CMYK.c. */ int -vips_CMYK2XYZ_set_fallback_profile( VipsImage *image ) +vips__fallback_profile_set( const char *name, VipsImage *image ) { size_t data_length; unsigned char *data; @@ -105,8 +131,11 @@ vips_CMYK2XYZ_set_fallback_profile( VipsImage *image ) if( vips_image_get_typeof( image, VIPS_META_ICC_NAME ) ) return( 0 ); - if( !(data = vips__CMYK2XYZ_get_fallback_profile( &data_length )) ) + if( !(data = vips__fallback_profile_get( name, &data_length )) ) { + vips_error( "fallback", + _( "unknown fallback profile \"%s\"" ), name ); return( -1 ); + } vips_image_set_blob( image, VIPS_META_ICC_NAME, NULL, data, data_length ); @@ -140,7 +169,7 @@ vips_CMYK2XYZ_build( VipsObject *object ) g_object_set( object, "out", out, NULL ); if( vips_copy( CMYK2XYZ->in, &t[0], NULL ) || - vips_CMYK2XYZ_set_fallback_profile( t[0] ) || + vips__fallback_profile_set( "cmyk", t[0] ) || vips__colourspace_process_n( "CMYK2XYZ", t[0], &t[1], 4, vips_CMYK2XYZ_process ) || vips_image_write( t[1], out ) ) diff --git a/libvips/colour/Makefile.am b/libvips/colour/Makefile.am index 09d8b55e..4aeb5499 100644 --- a/libvips/colour/Makefile.am +++ b/libvips/colour/Makefile.am @@ -1,13 +1,14 @@ noinst_LTLIBRARIES = libcolour.la if ENABLE_LCMS -PROFILES = profiles.c profiles.h +PROFILES = profiles.c else PROFILES = endif libcolour_la_SOURCES = \ $(PROFILES) \ + profiles.h \ colour.c \ pcolour.h \ CMYK2XYZ.c \ @@ -43,7 +44,7 @@ libcolour_la_SOURCES = \ scRGB2sRGB.c profiles.c: - ./wrap_profiles.sh profiles profiles + ./wrap_profiles.sh profiles profiles.c EXTRA_DIST = \ profiles \ diff --git a/libvips/colour/XYZ2CMYK.c b/libvips/colour/XYZ2CMYK.c index bf5cd2b3..d7737399 100644 --- a/libvips/colour/XYZ2CMYK.c +++ b/libvips/colour/XYZ2CMYK.c @@ -84,7 +84,7 @@ vips_XYZ2CMYK_build( VipsObject *object ) g_object_set( object, "out", out, NULL ); if( vips_copy( XYZ2CMYK->in, &t[0], NULL ) || - vips_CMYK2XYZ_set_fallback_profile( t[0] ) || + vips__fallback_profile_set( "cmyk", t[0] ) || vips__colourspace_process_n( "XYZ2CMYK", t[0], &t[1], 3, vips_XYZ2CMYK_process ) || vips_image_write( t[1], out ) ) diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 49b40caf..fec7d89b 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -615,16 +615,51 @@ vips_icc_load_profile_image( VipsImage *image ) return( profile ); } +static void * +vips_icc_get_profile_file( const char *filename, size_t *data_length ) +{ + void *data; + + /* See if we have a fallback profile of this name. + */ + if( (data = vips__fallback_profile_get( filename, data_length )) ) + return( data ); + + /* Try to load as a filename. + */ + if( (data = vips__file_read_name( filename, + vips__icc_dir(), data_length )) ) + return( data ); + + return( NULL ); +} + +static void * +vips_icc_get_profile_image( VipsImage *image, size_t *data_length ) +{ + void *data; + + if( !vips_image_get_typeof( image, VIPS_META_ICC_NAME ) ) + return( NULL ); + + if( vips_image_get_blob( image, VIPS_META_ICC_NAME, + &data, data_length ) _) { + g_warning( "%s", _( "corrupt embedded profile" ) ); + return( NULL ); + } + + return( data ); +} + static cmsHPROFILE -vips_icc_load_profile_file( const char *domain, - VipsImage *image, const char *filename ) +vips_icc_load_profile( const char *domain, + VipsImage *image, void *data, size_t *data_length ) { cmsHPROFILE profile; - if( !(profile = cmsOpenProfileFromFile( filename, "r" )) ) { - vips_error( domain, - _( "unable to open profile \"%s\"" ), filename ); - return( NULL ); + if( !(profile = cmsOpenProfileFromMem( data, data_length )) ) { + g_warning( "%s", _( "corrupt profile" ) ); + return( NULL ); } if( vips_image_expected_bands( image ) != diff --git a/libvips/colour/pcolour.h b/libvips/colour/pcolour.h index da93c9c6..475c3bb4 100644 --- a/libvips/colour/pcolour.h +++ b/libvips/colour/pcolour.h @@ -216,7 +216,8 @@ extern float vips_v2Y_16[65536]; void vips_col_make_tables_RGB_8( void ); void vips_col_make_tables_RGB_16( void ); -int vips_CMYK2XYZ_set_fallback_profile( VipsImage *image ); +void *vips__fallback_profile_get( const char *name, size_t *length ); +int vips__fallback_profile_set( const char *name, VipsImage *image ); /* A colour-transforming function. */ diff --git a/libvips/colour/profiles.c b/libvips/colour/profiles.c index 0550c9e7..e064fa74 100644 --- a/libvips/colour/profiles.c +++ b/libvips/colour/profiles.c @@ -1,6 +1,9 @@ /* coded files, generated automatically */ -char *vips__coded_cmyk = +#include "profiles.h" + +VipsCodedProfile vips__coded_profiles[] = { + { "cmyk", "AA6sbGFyZ2wCIAAAcHJ0ckNNWUtMYWIgB94ACAAZAAwAKAA1YWNzcE1TRlQAAAAAAAAAAAAAAAAA" "AAAAAAAAAAAAAAEAAPbWAAEAAAAA0y1hcmdsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" "AAAAAAAAAAAAAAAAAAAAAAAPZGVzYwAAATgAAABpY3BydAAAAaQAAABnd3RwdAAAAgwAAAAUYmtw" @@ -16872,4 +16875,6 @@ char *vips__coded_cmyk = "LjI5IDMuOTIgMy41NyAzLjIzIDMuMDUgMy40IDQuMjUgNC43NCAzLjc1IDIuNDggMS45NCAxLjcz" "IDEuNDYgMS40IDEuODMgMi41OCAyLjk0IDIuOTUgMi45NCAyLjk1IDIuOTggMy4zMiAzLjk5IDQu" "NDIgNC4yOCAzLjk0IDMuNDcgMy4xMyAzLjM1IDQuMjENCkVORF9EQVRBDQoNCg0KDQoNCgAA" -; + }, + { 0, 0 } +}; diff --git a/libvips/colour/profiles.h b/libvips/colour/profiles.h index 25db4062..e958e6b4 100644 --- a/libvips/colour/profiles.h +++ b/libvips/colour/profiles.h @@ -1,3 +1,10 @@ -/* header for coded files, generated automatically */ +/* The fallback profiles, coded as a set of base64 strings, see + * wrap-profiles.sh + */ +typedef struct _VipsCodedProfile { + const char *name; + const char *data; +} VipsCodedProfile; + +extern VipsCodedProfile vips__coded_profiles[]; -extern char *vips__coded_cmyk ; diff --git a/libvips/colour/profiles/sRGB.icm b/libvips/colour/profiles/sRGB.icm new file mode 100644 index 0000000000000000000000000000000000000000..1d8f7419c3bf2c6a3dd78f2c679fdefbda1776a3 GIT binary patch literal 6922 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 VE+#f@4I@33!-(c_IEmSS@NW)(3LO9d literal 0 HcmV?d00001 diff --git a/libvips/colour/wrap-profiles.sh b/libvips/colour/wrap-profiles.sh index fcfd422f..cfd801b9 100755 --- a/libvips/colour/wrap-profiles.sh +++ b/libvips/colour/wrap-profiles.sh @@ -1,27 +1,22 @@ #!/bin/bash -# code up the binary files in $1 as a set of base64-encoded strings in $2 +# code up the binary files in $1 as a set of name / base64-encoded strings +# in $2 in=$1 -out_c=$2.c -out_h=$2.h +out=$2 -echo "/* coded files, generated automatically */" > $out_c -echo "" >> $out_c +echo "/* coded files, generated automatically */" > $out +echo "" >> $out +echo "#include \"profiles.h\"" >> $out +echo "" >> $out +echo "VipsCodedProfile vips__coded_profiles[] = {" >> $out for file in $in/*; do root=${file%.icm} base=${root##*/} - echo char \*vips__coded_$base = >> $out_c - base64 $file | sed 's/\(.*\)/"\1"/g' >> $out_c - echo ';' >> $out_c + echo " { \"$base\"," >> $out + base64 $file | sed 's/\(.*\)/"\1"/g' >> $out + echo " }," >> $out done - -echo "/* header for coded files, generated automatically */" > $out_h -echo "" >> $out_h -for file in $in/*; do - root=${file%.icm} - base=${root##*/} - echo extern char \*vips__coded_$base ';' >> $out_h -done - - +echo " { 0, 0 }" >> $out +echo "};" >> $out