make the savers use profile_load
tiff, jpeg and png save all use profile_load to attach profiles
This commit is contained in:
parent
28999aa5b6
commit
f768029298
@ -15,7 +15,7 @@
|
|||||||
- dzsave has a new skip_blanks option
|
- dzsave has a new skip_blanks option
|
||||||
- add vips_CMYK2XYZ() and vips_XYZ2CMYK(), plus associated routes
|
- add vips_CMYK2XYZ() and vips_XYZ2CMYK(), plus associated routes
|
||||||
- include cmyk and srgb fallback profiles
|
- include cmyk and srgb fallback profiles
|
||||||
- add vips_profile_load()
|
- add vips_profile_load() and use it everywhere
|
||||||
|
|
||||||
4/1/19 started 8.7.4
|
4/1/19 started 8.7.4
|
||||||
- fix memory leak in magickload [kleisauke]
|
- fix memory leak in magickload [kleisauke]
|
||||||
|
@ -194,11 +194,20 @@ vips_profile_load_init( VipsProfileLoad *load )
|
|||||||
* @profile: (out): loaded profile
|
* @profile: (out): loaded profile
|
||||||
* @...: %NULL-terminated list of optional named arguments
|
* @...: %NULL-terminated list of optional named arguments
|
||||||
*
|
*
|
||||||
* Load a named profile. If the name is one of the built in ICC profiles, then
|
* Load a named profile.
|
||||||
* that is returmed, otherwise a profile is loaded from the system profile
|
|
||||||
* area.
|
|
||||||
*
|
*
|
||||||
* The special name "none" will make this operation return NULL for @profile.
|
* Profiles are loaded from four sources:
|
||||||
|
*
|
||||||
|
* - The special name `"none"` means no profile. @profile will be %NULL in this
|
||||||
|
* case.
|
||||||
|
*
|
||||||
|
* - @name can be the name of one of the ICC profiles embedded in libvips.
|
||||||
|
* These names can be at least `"cmyk"` and `"srgb"`.
|
||||||
|
*
|
||||||
|
* - @name can be the full path to a file.
|
||||||
|
*
|
||||||
|
* - @name can be the name of an ICC profile in the system profile directory
|
||||||
|
* for your platform.
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error
|
* Returns: 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
|
@ -75,7 +75,7 @@ typedef struct _VipsForeignSaveJpeg {
|
|||||||
*/
|
*/
|
||||||
int Q;
|
int Q;
|
||||||
|
|
||||||
/* Profile to embed .. "none" means don't attach a profile.
|
/* Profile to embed.
|
||||||
*/
|
*/
|
||||||
char *profile;
|
char *profile;
|
||||||
|
|
||||||
@ -434,10 +434,9 @@ vips_foreign_save_jpeg_mime_init( VipsForeignSaveJpegMime *mime )
|
|||||||
*
|
*
|
||||||
* Use @Q to set the JPEG compression factor. Default 75.
|
* Use @Q to set the JPEG compression factor. Default 75.
|
||||||
*
|
*
|
||||||
* Use @profile to give the filename of a profile to be embedded in the JPEG.
|
* Use @profile to give the name of a profile to be embedded in the JPEG.
|
||||||
* This does not affect the pixels which are written, just the way
|
* This does not affect the pixels which are written, just the way
|
||||||
* they are tagged. You can use the special string "none" to mean
|
* they are tagged. See vips_profile_load() for details on profile naming.
|
||||||
* "don't attach a profile".
|
|
||||||
*
|
*
|
||||||
* If no profile is specified and the VIPS header
|
* If no profile is specified and the VIPS header
|
||||||
* contains an ICC profile named #VIPS_META_ICC_NAME, the
|
* contains an ICC profile named #VIPS_META_ICC_NAME, the
|
||||||
|
@ -332,8 +332,7 @@ vips_foreign_save_png_buffer_init( VipsForeignSavePngBuffer *buffer )
|
|||||||
*
|
*
|
||||||
* Use @profile to give the filename of a profile to be embedded in the PNG.
|
* Use @profile to give the filename of a profile to be embedded in the PNG.
|
||||||
* This does not affect the pixels which are written, just the way
|
* This does not affect the pixels which are written, just the way
|
||||||
* they are tagged. You can use the special string "none" to mean
|
* they are tagged. See vips_profile_load() for details on profile naming.
|
||||||
* "don't attach a profile".
|
|
||||||
*
|
*
|
||||||
* If @profile is specified and the VIPS header
|
* If @profile is specified and the VIPS header
|
||||||
* contains an ICC profile named VIPS_META_ICC_NAME ("icc-profile-data"), the
|
* contains an ICC profile named VIPS_META_ICC_NAME ("icc-profile-data"), the
|
||||||
|
@ -509,8 +509,7 @@ vips_foreign_save_tiff_buffer_init( VipsForeignSaveTiffBuffer *buffer )
|
|||||||
*
|
*
|
||||||
* Use @profile to give the filename of a profile to be embedded in the TIFF.
|
* Use @profile to give the filename of a profile to be embedded in the TIFF.
|
||||||
* This does not affect the pixels which are written, just the way
|
* This does not affect the pixels which are written, just the way
|
||||||
* they are tagged. You can use the special string "none" to mean
|
* they are tagged. See vips_profile_load() for details on profile naming.
|
||||||
* "don't attach a profile".
|
|
||||||
*
|
*
|
||||||
* If no profile is specified and the VIPS header
|
* If no profile is specified and the VIPS header
|
||||||
* contains an ICC profile named #VIPS_META_ICC_NAME, the
|
* contains an ICC profile named #VIPS_META_ICC_NAME, the
|
||||||
|
@ -196,8 +196,6 @@ typedef struct {
|
|||||||
struct jpeg_compress_struct cinfo;
|
struct jpeg_compress_struct cinfo;
|
||||||
ErrorManager eman;
|
ErrorManager eman;
|
||||||
JSAMPROW *row_pointer;
|
JSAMPROW *row_pointer;
|
||||||
char *profile_bytes;
|
|
||||||
size_t profile_length;
|
|
||||||
VipsImage *inverted;
|
VipsImage *inverted;
|
||||||
} Write;
|
} Write;
|
||||||
|
|
||||||
@ -207,7 +205,6 @@ write_destroy( Write *write )
|
|||||||
jpeg_destroy_compress( &write->cinfo );
|
jpeg_destroy_compress( &write->cinfo );
|
||||||
VIPS_FREEF( fclose, write->eman.fp );
|
VIPS_FREEF( fclose, write->eman.fp );
|
||||||
VIPS_FREE( write->row_pointer );
|
VIPS_FREE( write->row_pointer );
|
||||||
VIPS_FREE( write->profile_bytes );
|
|
||||||
VIPS_UNREF( write->inverted );
|
VIPS_UNREF( write->inverted );
|
||||||
|
|
||||||
g_free( write );
|
g_free( write );
|
||||||
@ -227,8 +224,6 @@ write_new( VipsImage *in )
|
|||||||
write->eman.pub.error_exit = vips__new_error_exit;
|
write->eman.pub.error_exit = vips__new_error_exit;
|
||||||
write->eman.pub.output_message = vips__new_output_message;
|
write->eman.pub.output_message = vips__new_output_message;
|
||||||
write->eman.fp = NULL;
|
write->eman.fp = NULL;
|
||||||
write->profile_bytes = NULL;
|
|
||||||
write->profile_length = 0;
|
|
||||||
write->inverted = NULL;
|
write->inverted = NULL;
|
||||||
|
|
||||||
return( write );
|
return( write );
|
||||||
@ -358,17 +353,25 @@ write_profile_data (j_compress_ptr cinfo,
|
|||||||
static int
|
static int
|
||||||
write_profile_file( Write *write, const char *profile )
|
write_profile_file( Write *write, const char *profile )
|
||||||
{
|
{
|
||||||
if( !(write->profile_bytes =
|
VipsBlob *blob;
|
||||||
vips__file_read_name( profile, vips__icc_dir(),
|
|
||||||
&write->profile_length )) )
|
if( vips_profile_load( profile, &blob, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
write_profile_data( &write->cinfo,
|
|
||||||
(JOCTET *) write->profile_bytes, write->profile_length );
|
if( blob ) {
|
||||||
|
size_t length;
|
||||||
|
const void *data = vips_blob_get( blob, &length );
|
||||||
|
|
||||||
|
write_profile_data( &write->cinfo, (JOCTET *) data, length );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "write_profile_file: attached profile \"%s\"\n", profile );
|
printf( "write_profile_file: "
|
||||||
|
"attached profile \"%s\"\n", profile );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
|
vips_area_unref( (VipsArea *) blob );
|
||||||
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,15 +379,16 @@ static int
|
|||||||
write_profile_meta( Write *write )
|
write_profile_meta( Write *write )
|
||||||
{
|
{
|
||||||
const void *data;
|
const void *data;
|
||||||
size_t size;
|
size_t length;
|
||||||
|
|
||||||
if( vips_image_get_blob( write->in, VIPS_META_ICC_NAME, &data, &size ) )
|
if( vips_image_get_blob( write->in,
|
||||||
|
VIPS_META_ICC_NAME, &data, &length ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
write_profile_data( &write->cinfo, data, size );
|
write_profile_data( &write->cinfo, data, length );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "write_profile_meta: attached %zd byte profile from header\n",
|
printf( "write_profile_meta: attached %zd byte profile from header\n",
|
||||||
size );
|
length );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -596,10 +600,9 @@ write_vips( Write *write, int qfac, const char *profile,
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* A profile supplied as an argument overrides an embedded
|
/* A profile supplied as an argument overrides an embedded
|
||||||
* profile. "none" means don't attach a profile.
|
* profile.
|
||||||
*/
|
*/
|
||||||
if( profile &&
|
if( profile &&
|
||||||
strcmp( profile, "none" ) != 0 &&
|
|
||||||
write_profile_file( write, profile ) )
|
write_profile_file( write, profile ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( !profile &&
|
if( !profile &&
|
||||||
|
@ -325,24 +325,29 @@ struct _Wtiff {
|
|||||||
int image_height;
|
int image_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Embed an ICC profile from a file.
|
/* Write an ICC Profile from a file into the JPEG stream.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
embed_profile_file( TIFF *tif, const char *profile )
|
embed_profile_file( TIFF *tif, const char *profile )
|
||||||
{
|
{
|
||||||
char *buffer;
|
VipsBlob *blob;
|
||||||
size_t length;
|
|
||||||
|
|
||||||
if( !(buffer = vips__file_read_name( profile,
|
if( vips_profile_load( profile, &blob, NULL ) )
|
||||||
vips__icc_dir(), &length )) )
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
TIFFSetField( tif, TIFFTAG_ICCPROFILE, length, buffer );
|
|
||||||
vips_free( buffer );
|
if( blob ) {
|
||||||
|
size_t length;
|
||||||
|
const void *data = vips_blob_get( blob, &length );
|
||||||
|
|
||||||
|
TIFFSetField( tif, TIFFTAG_ICCPROFILE, length, data );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips2tiff: attached profile \"%s\"\n", profile );
|
printf( "vips2tiff: attached profile \"%s\"\n", profile );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
|
vips_area_unref( (VipsArea *) blob );
|
||||||
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,11 +357,11 @@ static int
|
|||||||
embed_profile_meta( TIFF *tif, VipsImage *im )
|
embed_profile_meta( TIFF *tif, VipsImage *im )
|
||||||
{
|
{
|
||||||
const void *data;
|
const void *data;
|
||||||
size_t size;
|
size_t length;
|
||||||
|
|
||||||
if( vips_image_get_blob( im, VIPS_META_ICC_NAME, &data, &size ) )
|
if( vips_image_get_blob( im, VIPS_META_ICC_NAME, &data, &length ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
TIFFSetField( tif, TIFFTAG_ICCPROFILE, size, data );
|
TIFFSetField( tif, TIFFTAG_ICCPROFILE, length, data );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips2tiff: attached profile from meta\n" );
|
printf( "vips2tiff: attached profile from meta\n" );
|
||||||
@ -426,8 +431,7 @@ wtiff_layer_new( Wtiff *wtiff, Layer *above, int width, int height )
|
|||||||
static int
|
static int
|
||||||
wtiff_embed_profile( Wtiff *wtiff, TIFF *tif )
|
wtiff_embed_profile( Wtiff *wtiff, TIFF *tif )
|
||||||
{
|
{
|
||||||
if( wtiff->icc_profile &&
|
if( wtiff->icc_profile &&
|
||||||
strcmp( wtiff->icc_profile, "none" ) != 0 &&
|
|
||||||
embed_profile_file( tif, wtiff->icc_profile ) )
|
embed_profile_file( tif, wtiff->icc_profile ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
@ -1071,13 +1071,13 @@ write_vips( Write *write,
|
|||||||
*/
|
*/
|
||||||
if( profile &&
|
if( profile &&
|
||||||
!strip ) {
|
!strip ) {
|
||||||
if( strcmp( profile, "none" ) != 0 ) {
|
VipsBlob *blob;
|
||||||
void *data;
|
|
||||||
size_t length;
|
|
||||||
|
|
||||||
if( !(data = vips__file_read_name( profile,
|
if( vips_profile_load( profile, &blob, NULL ) )
|
||||||
vips__icc_dir(), &length )) )
|
return( -1 );
|
||||||
return( -1 );
|
if( blob ) {
|
||||||
|
size_t length;
|
||||||
|
const void *data = vips_blob_get( blob, &length );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "write_vips: "
|
printf( "write_vips: "
|
||||||
@ -1087,6 +1087,8 @@ write_vips( Write *write,
|
|||||||
|
|
||||||
png_set_iCCP( write->pPng, write->pInfo, "icc",
|
png_set_iCCP( write->pPng, write->pInfo, "icc",
|
||||||
PNG_COMPRESSION_TYPE_BASE, data, length );
|
PNG_COMPRESSION_TYPE_BASE, data, length );
|
||||||
|
|
||||||
|
vips_area_unref( (VipsArea *) blob );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) &&
|
else if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) &&
|
||||||
|
Loading…
Reference in New Issue
Block a user