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/internal.h>
#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 ) )

View File

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

View File

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

View File

@ -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 ) !=

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_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.
*/

View File

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

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
# 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