make fallback profiles available to icc_import etc.

almost there, not working yet
This commit is contained in:
John Cupitt 2019-01-02 10:59:16 +00:00
parent f611845698
commit 7d1ec90894
9 changed files with 124 additions and 51 deletions

View File

@ -45,8 +45,8 @@
#include <vips/vips.h> #include <vips/vips.h>
#include <vips/internal.h> #include <vips/internal.h>
#include "pcolour.h"
#include "profiles.h" #include "profiles.h"
#include "pcolour.h"
typedef struct _VipsCMYK2XYZ { typedef struct _VipsCMYK2XYZ {
VipsOperation parent_instance; 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. /* Created on first use from a base64 string in profiles.c.
*/ */
static void *vips_CMYK2XYZ_fallback_profile = NULL; typedef struct _VipsFallbackProfile {
static size_t vips_CMYK2XYZ_fallback_profile_length = 0; const char *name;
void *data;
size_t data_length;
} VipsFallbackProfile;
static GSList *vips_fallback_profile_list = NULL;
static void * static void *
vips_CMYK2XYZ_get_fallback_profile_init( void ) vips__fallback_profile_get_init( void )
{ {
size_t data_length; int i;
unsigned char *data;
if( !(data = vips__b64_decode( vips__coded_cmyk, &data_length )) ) for( i = 0; vips__coded_profiles[i].name; i++ ) {
return( NULL ); size_t data_length;
vips_CMYK2XYZ_fallback_profile = data; unsigned char *data;
vips_CMYK2XYZ_fallback_profile_length = data_length; 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 ); return( NULL );
} }
static void * /* Shared with icc_transform.c
vips__CMYK2XYZ_get_fallback_profile( size_t *length ) */
void *
vips__fallback_profile_get( const char *name, size_t *length )
{ {
GOnce once = G_ONCE_INIT; GOnce once = G_ONCE_INIT;
VIPS_ONCE( &once, GSList *p;
(GThreadFunc) vips_CMYK2XYZ_get_fallback_profile_init, NULL );
*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. /* Shared with XYZ2CMYK.c.
*/ */
int int
vips_CMYK2XYZ_set_fallback_profile( VipsImage *image ) vips__fallback_profile_set( const char *name, VipsImage *image )
{ {
size_t data_length; size_t data_length;
unsigned char *data; unsigned char *data;
@ -105,8 +131,11 @@ vips_CMYK2XYZ_set_fallback_profile( VipsImage *image )
if( vips_image_get_typeof( image, VIPS_META_ICC_NAME ) ) if( vips_image_get_typeof( image, VIPS_META_ICC_NAME ) )
return( 0 ); 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 ); return( -1 );
}
vips_image_set_blob( image, VIPS_META_ICC_NAME, vips_image_set_blob( image, VIPS_META_ICC_NAME,
NULL, data, data_length ); NULL, data, data_length );
@ -140,7 +169,7 @@ vips_CMYK2XYZ_build( VipsObject *object )
g_object_set( object, "out", out, NULL ); g_object_set( object, "out", out, NULL );
if( vips_copy( CMYK2XYZ->in, &t[0], 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", vips__colourspace_process_n( "CMYK2XYZ",
t[0], &t[1], 4, vips_CMYK2XYZ_process ) || t[0], &t[1], 4, vips_CMYK2XYZ_process ) ||
vips_image_write( t[1], out ) ) vips_image_write( t[1], out ) )

View File

@ -1,13 +1,14 @@
noinst_LTLIBRARIES = libcolour.la noinst_LTLIBRARIES = libcolour.la
if ENABLE_LCMS if ENABLE_LCMS
PROFILES = profiles.c profiles.h PROFILES = profiles.c
else else
PROFILES = PROFILES =
endif endif
libcolour_la_SOURCES = \ libcolour_la_SOURCES = \
$(PROFILES) \ $(PROFILES) \
profiles.h \
colour.c \ colour.c \
pcolour.h \ pcolour.h \
CMYK2XYZ.c \ CMYK2XYZ.c \
@ -43,7 +44,7 @@ libcolour_la_SOURCES = \
scRGB2sRGB.c scRGB2sRGB.c
profiles.c: profiles.c:
./wrap_profiles.sh profiles profiles ./wrap_profiles.sh profiles profiles.c
EXTRA_DIST = \ EXTRA_DIST = \
profiles \ profiles \

View File

@ -84,7 +84,7 @@ vips_XYZ2CMYK_build( VipsObject *object )
g_object_set( object, "out", out, NULL ); g_object_set( object, "out", out, NULL );
if( vips_copy( XYZ2CMYK->in, &t[0], 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", vips__colourspace_process_n( "XYZ2CMYK",
t[0], &t[1], 3, vips_XYZ2CMYK_process ) || t[0], &t[1], 3, vips_XYZ2CMYK_process ) ||
vips_image_write( t[1], out ) ) vips_image_write( t[1], out ) )

View File

@ -615,16 +615,51 @@ vips_icc_load_profile_image( VipsImage *image )
return( profile ); 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 static cmsHPROFILE
vips_icc_load_profile_file( const char *domain, vips_icc_load_profile( const char *domain,
VipsImage *image, const char *filename ) VipsImage *image, void *data, size_t *data_length )
{ {
cmsHPROFILE profile; cmsHPROFILE profile;
if( !(profile = cmsOpenProfileFromFile( filename, "r" )) ) { if( !(profile = cmsOpenProfileFromMem( data, data_length )) ) {
vips_error( domain, g_warning( "%s", _( "corrupt profile" ) );
_( "unable to open profile \"%s\"" ), filename ); return( NULL );
return( NULL );
} }
if( vips_image_expected_bands( image ) != if( vips_image_expected_bands( image ) !=

View File

@ -216,7 +216,8 @@ extern float vips_v2Y_16[65536];
void vips_col_make_tables_RGB_8( void ); void vips_col_make_tables_RGB_8( void );
void vips_col_make_tables_RGB_16( 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. /* A colour-transforming function.
*/ */

View File

@ -1,6 +1,9 @@
/* coded files, generated automatically */ /* coded files, generated automatically */
char *vips__coded_cmyk = #include "profiles.h"
VipsCodedProfile vips__coded_profiles[] = {
{ "cmyk",
"AA6sbGFyZ2wCIAAAcHJ0ckNNWUtMYWIgB94ACAAZAAwAKAA1YWNzcE1TRlQAAAAAAAAAAAAAAAAA" "AA6sbGFyZ2wCIAAAcHJ0ckNNWUtMYWIgB94ACAAZAAwAKAA1YWNzcE1TRlQAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAEAAPbWAAEAAAAA0y1hcmdsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" "AAAAAAAAAAAAAAEAAPbWAAEAAAAA0y1hcmdsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAPZGVzYwAAATgAAABpY3BydAAAAaQAAABnd3RwdAAAAgwAAAAUYmtw" "AAAAAAAAAAAAAAAAAAAAAAAPZGVzYwAAATgAAABpY3BydAAAAaQAAABnd3RwdAAAAgwAAAAUYmtw"
@ -16872,4 +16875,6 @@ char *vips__coded_cmyk =
"LjI5IDMuOTIgMy41NyAzLjIzIDMuMDUgMy40IDQuMjUgNC43NCAzLjc1IDIuNDggMS45NCAxLjcz" "LjI5IDMuOTIgMy41NyAzLjIzIDMuMDUgMy40IDQuMjUgNC43NCAzLjc1IDIuNDggMS45NCAxLjcz"
"IDEuNDYgMS40IDEuODMgMi41OCAyLjk0IDIuOTUgMi45NCAyLjk1IDIuOTggMy4zMiAzLjk5IDQu" "IDEuNDYgMS40IDEuODMgMi41OCAyLjk0IDIuOTUgMi45NCAyLjk1IDIuOTggMy4zMiAzLjk5IDQu"
"NDIgNC4yOCAzLjk0IDMuNDcgMy4xMyAzLjM1IDQuMjENCkVORF9EQVRBDQoNCg0KDQoNCgAA" "NDIgNC4yOCAzLjk0IDMuNDcgMy4xMyAzLjM1IDQuMjENCkVORF9EQVRBDQoNCg0KDQoNCgAA"
; },
{ 0, 0 }
};

View File

@ -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 ;

Binary file not shown.

View File

@ -1,27 +1,22 @@
#!/bin/bash #!/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 in=$1
out_c=$2.c out=$2
out_h=$2.h
echo "/* coded files, generated automatically */" > $out_c echo "/* coded files, generated automatically */" > $out
echo "" >> $out_c echo "" >> $out
echo "#include \"profiles.h\"" >> $out
echo "" >> $out
echo "VipsCodedProfile vips__coded_profiles[] = {" >> $out
for file in $in/*; do for file in $in/*; do
root=${file%.icm} root=${file%.icm}
base=${root##*/} base=${root##*/}
echo char \*vips__coded_$base = >> $out_c echo " { \"$base\"," >> $out
base64 $file | sed 's/\(.*\)/"\1"/g' >> $out_c base64 $file | sed 's/\(.*\)/"\1"/g' >> $out
echo ';' >> $out_c echo " }," >> $out
done done
echo " { 0, 0 }" >> $out
echo "/* header for coded files, generated automatically */" > $out_h echo "};" >> $out
echo "" >> $out_h
for file in $in/*; do
root=${file%.icm}
base=${root##*/}
echo extern char \*vips__coded_$base ';' >> $out_h
done