seems to work
though the srgb fallback is not working ``` $ vips icc_import k2.jpg x.v --input-profile=srgb vips__file_open_read: unable to open file "srgb" for reading unix error: No such file or directory icc_import: no input profile ``` perhaps padding issues?
This commit is contained in:
parent
a93deb8201
commit
105760be0a
@ -151,7 +151,9 @@ typedef struct _VipsIcc {
|
||||
VipsPCS pcs;
|
||||
int depth;
|
||||
|
||||
VipsBlob *in_blob;
|
||||
cmsHPROFILE in_profile;
|
||||
VipsBlob *out_blob;
|
||||
cmsHPROFILE out_profile;
|
||||
cmsUInt32Number in_icc_format;
|
||||
cmsUInt32Number out_icc_format;
|
||||
@ -181,6 +183,16 @@ vips_icc_dispose( GObject *gobject )
|
||||
VIPS_FREEF( cmsCloseProfile, icc->in_profile );
|
||||
VIPS_FREEF( cmsCloseProfile, icc->out_profile );
|
||||
|
||||
if( icc->in_blob ) {
|
||||
vips_area_unref( (VipsArea *) icc->in_blob );
|
||||
icc->in_blob = NULL;
|
||||
}
|
||||
|
||||
if( icc->out_blob ) {
|
||||
vips_area_unref( (VipsArea *) icc->out_blob );
|
||||
icc->out_blob = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS( vips_icc_parent_class )->dispose( gobject );
|
||||
}
|
||||
|
||||
@ -581,98 +593,72 @@ vips_image_expected_sig( VipsImage *image )
|
||||
return( expected_sig );
|
||||
}
|
||||
|
||||
static cmsHPROFILE
|
||||
vips_icc_load_profile_image( VipsImage *image )
|
||||
/* Get from a filename, including loading a fallback.
|
||||
*/
|
||||
static VipsBlob *
|
||||
vips_icc_get_profile_file( const char *filename )
|
||||
{
|
||||
void *data;
|
||||
size_t data_length;
|
||||
cmsHPROFILE profile;
|
||||
size_t size;
|
||||
|
||||
if( (data = vips__fallback_profile_get( filename, &size )) )
|
||||
/* We have a fallback profile of this name.
|
||||
*/
|
||||
return( vips_blob_new( NULL, data, size ) );
|
||||
else if( (data = vips__file_read_name( filename,
|
||||
vips__icc_dir(), &size )) )
|
||||
/* Load from the named file.
|
||||
*/
|
||||
return( vips_blob_new(
|
||||
(VipsCallbackFn) vips_free, data, size ) );
|
||||
else
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Get from an image.
|
||||
*/
|
||||
static VipsBlob *
|
||||
vips_icc_get_profile_image( VipsImage *image )
|
||||
{
|
||||
void *data;
|
||||
size_t size;
|
||||
|
||||
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 ) ||
|
||||
!(profile = cmsOpenProfileFromMem( data, data_length )) ) {
|
||||
g_warning( "%s", _( "corrupt embedded profile" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if( vips_image_expected_bands( image ) !=
|
||||
vips_icc_profile_needs_bands( profile ) ) {
|
||||
VIPS_FREEF( cmsCloseProfile, profile );
|
||||
g_warning( "%s",
|
||||
_( "embedded profile incompatible with image" ) );
|
||||
return( NULL );
|
||||
}
|
||||
if( vips_image_expected_sig( image ) != cmsGetColorSpace( profile ) ) {
|
||||
VIPS_FREEF( cmsCloseProfile, profile );
|
||||
g_warning( "%s",
|
||||
_( "embedded profile colourspace differs from image" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
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 ) )
|
||||
if( vips_image_get_blob( image, VIPS_META_ICC_NAME, &data, &size ) )
|
||||
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 );
|
||||
return( vips_blob_new( NULL, data, size ) );
|
||||
}
|
||||
|
||||
/* Load a profile from a blob and check compatibility.
|
||||
*/
|
||||
static cmsHPROFILE
|
||||
vips_icc_load_profile( const char *domain,
|
||||
VipsImage *image, void *data, size_t *data_length )
|
||||
vips_icc_load_profile_blob( VipsBlob *blob, VipsImage *image )
|
||||
{
|
||||
const void *data;
|
||||
size_t size;
|
||||
cmsHPROFILE profile;
|
||||
|
||||
if( !(profile = cmsOpenProfileFromMem( data, data_length )) ) {
|
||||
data = vips_blob_get( blob, &size );
|
||||
if( !(profile = cmsOpenProfileFromMem( data, size )) ) {
|
||||
g_warning( "%s", _( "corrupt profile" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if( vips_image_expected_bands( image ) !=
|
||||
vips_icc_profile_needs_bands( profile ) ) {
|
||||
if( image &&
|
||||
vips_image_expected_bands( image ) !=
|
||||
vips_icc_profile_needs_bands( profile ) ) {
|
||||
VIPS_FREEF( cmsCloseProfile, profile );
|
||||
g_warning( _( "profile \"%s\" incompatible with image" ),
|
||||
filename );
|
||||
g_warning( "%s", _( "profile incompatible with image" ) );
|
||||
return( NULL );
|
||||
}
|
||||
if( vips_image_expected_sig( image ) != cmsGetColorSpace( profile ) ) {
|
||||
if( image &&
|
||||
vips_image_expected_sig( image ) !=
|
||||
cmsGetColorSpace( profile ) ) {
|
||||
VIPS_FREEF( cmsCloseProfile, profile );
|
||||
g_warning( _( "profile \"%s\" colourspace "
|
||||
"differs from image" ), filename );
|
||||
g_warning( "%s",
|
||||
_( "profile colourspace differs from image" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
@ -695,23 +681,25 @@ vips_icc_import_build( VipsObject *object )
|
||||
* 1 0 image
|
||||
* 0 1 file
|
||||
* 1 1 image, then fall back to file
|
||||
*
|
||||
* see also import_build.
|
||||
*/
|
||||
|
||||
if( code->in &&
|
||||
(import->embedded ||
|
||||
!import->input_profile_filename) )
|
||||
icc->in_profile = vips_icc_load_profile_image( code->in );
|
||||
icc->in_blob = vips_icc_get_profile_image( code->in );
|
||||
|
||||
if( !icc->in_profile &&
|
||||
code->in &&
|
||||
if( !icc->in_blob &&
|
||||
import->input_profile_filename ) {
|
||||
icc->in_profile = vips_icc_load_profile_file( class->nickname,
|
||||
code->in, import->input_profile_filename );
|
||||
icc->in_blob = vips_icc_get_profile_file(
|
||||
import->input_profile_filename );
|
||||
import->used_fallback = TRUE;
|
||||
}
|
||||
|
||||
if( icc->in_blob &&
|
||||
code->in )
|
||||
icc->in_profile =
|
||||
vips_icc_load_profile_blob( icc->in_blob, code->in );
|
||||
|
||||
if( !icc->in_profile ) {
|
||||
vips_error( class->nickname, "%s", _( "no input profile" ) );
|
||||
return( -1 );
|
||||
@ -733,23 +721,19 @@ vips_icc_import_build( VipsObject *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.
|
||||
* image, since the PCS image needs 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 );
|
||||
if( import->used_fallback &&
|
||||
icc->in_blob ) {
|
||||
void *data;
|
||||
size_t size;
|
||||
|
||||
data = vips_blob_get( icc->in_blob, &size );
|
||||
vips_image_set_blob( colour->out, VIPS_META_ICC_NAME,
|
||||
(VipsCallbackFn) vips_free, data, length );
|
||||
NULL, data, size );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
@ -897,32 +881,18 @@ vips_icc_export_build( VipsObject *object )
|
||||
icc->in_profile = cmsCreateXYZProfile();
|
||||
|
||||
if( code->in &&
|
||||
!export->output_profile_filename &&
|
||||
vips_image_get_typeof( code->in, VIPS_META_ICC_NAME ) ) {
|
||||
void *data;
|
||||
size_t data_length;
|
||||
|
||||
if( vips_image_get_blob( code->in, VIPS_META_ICC_NAME,
|
||||
&data, &data_length ) ||
|
||||
!(icc->out_profile = cmsOpenProfileFromMem(
|
||||
data, data_length )) ) {
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "unable to load embedded profile" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
else if( export->output_profile_filename ) {
|
||||
if( !(icc->out_profile = cmsOpenProfileFromFile(
|
||||
export->output_profile_filename, "r" )) ) {
|
||||
vips_error( class->nickname,
|
||||
_( "unable to open profile \"%s\"" ),
|
||||
export->output_profile_filename );
|
||||
return( -1 );
|
||||
}
|
||||
!export->output_profile_filename )
|
||||
icc->out_blob = vips_icc_get_profile_image( code->in );
|
||||
|
||||
if( !icc->out_blob &&
|
||||
export->output_profile_filename ) {
|
||||
icc->out_blob = vips_icc_get_profile_file(
|
||||
export->output_profile_filename );
|
||||
colour->profile_filename = export->output_profile_filename;
|
||||
}
|
||||
else {
|
||||
|
||||
if( !(icc->out_profile =
|
||||
vips_icc_load_profile_blob( icc->out_blob, NULL )) ) {
|
||||
vips_error( class->nickname, "%s", _( "no output profile" ) );
|
||||
return( -1 );
|
||||
}
|
||||
@ -1115,13 +1085,17 @@ vips_icc_transform_build( VipsObject *object )
|
||||
if( code->in &&
|
||||
(transform->embedded ||
|
||||
!transform->input_profile_filename) )
|
||||
icc->in_profile = vips_icc_load_profile_image( code->in );
|
||||
icc->in_blob = vips_icc_get_profile_image( code->in );
|
||||
|
||||
if( !icc->in_profile &&
|
||||
code->in &&
|
||||
if( !icc->in_blob &&
|
||||
transform->input_profile_filename )
|
||||
icc->in_profile = vips_icc_load_profile_file( class->nickname,
|
||||
code->in, transform->input_profile_filename );
|
||||
icc->in_blob = vips_icc_get_profile_file(
|
||||
transform->input_profile_filename );
|
||||
|
||||
if( icc->in_blob &&
|
||||
code->in )
|
||||
icc->in_profile =
|
||||
vips_icc_load_profile_blob( icc->in_blob, code->in );
|
||||
|
||||
if( !icc->in_profile ) {
|
||||
vips_error( class->nickname, "%s", _( "no input profile" ) );
|
||||
@ -1129,17 +1103,20 @@ vips_icc_transform_build( VipsObject *object )
|
||||
}
|
||||
|
||||
if( transform->output_profile_filename ) {
|
||||
if( !(icc->out_profile = cmsOpenProfileFromFile(
|
||||
transform->output_profile_filename, "r" )) ) {
|
||||
vips_error( class->nickname,
|
||||
_( "unable to open profile \"%s\"" ),
|
||||
transform->output_profile_filename );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
icc->out_blob = vips_icc_get_profile_file(
|
||||
transform->output_profile_filename );
|
||||
colour->profile_filename = transform->output_profile_filename;
|
||||
}
|
||||
|
||||
if( icc->out_blob )
|
||||
icc->out_profile =
|
||||
vips_icc_load_profile_blob( icc->out_blob, NULL );
|
||||
|
||||
if( !icc->out_profile ) {
|
||||
vips_error( class->nickname, "%s", _( "no output profile" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
vips_check_intent( class->nickname,
|
||||
icc->in_profile, icc->intent, LCMS_USED_AS_INPUT );
|
||||
vips_check_intent( class->nickname,
|
||||
|
Loading…
Reference in New Issue
Block a user