From f7680292984475fd672ad6b0ef6bfbfbc26303c2 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 11 Jan 2019 06:30:06 +0000 Subject: [PATCH] make the savers use profile_load tiff, jpeg and png save all use profile_load to attach profiles --- ChangeLog | 2 +- libvips/colour/profile_load.c | 17 +++++++++++---- libvips/foreign/jpegsave.c | 7 +++---- libvips/foreign/pngsave.c | 3 +-- libvips/foreign/tiffsave.c | 3 +-- libvips/foreign/vips2jpeg.c | 39 +++++++++++++++++++---------------- libvips/foreign/vips2tiff.c | 30 +++++++++++++++------------ libvips/foreign/vipspng.c | 14 +++++++------ 8 files changed, 65 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index 54c8d71c..622b3357 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,7 @@ - dzsave has a new skip_blanks option - add vips_CMYK2XYZ() and vips_XYZ2CMYK(), plus associated routes - 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 - fix memory leak in magickload [kleisauke] diff --git a/libvips/colour/profile_load.c b/libvips/colour/profile_load.c index 80c5c193..824d8658 100644 --- a/libvips/colour/profile_load.c +++ b/libvips/colour/profile_load.c @@ -194,11 +194,20 @@ vips_profile_load_init( VipsProfileLoad *load ) * @profile: (out): loaded profile * @...: %NULL-terminated list of optional named arguments * - * Load a named profile. If the name is one of the built in ICC profiles, then - * that is returmed, otherwise a profile is loaded from the system profile - * area. + * Load a named profile. * - * 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 */ diff --git a/libvips/foreign/jpegsave.c b/libvips/foreign/jpegsave.c index d93cf5b2..91db15f9 100644 --- a/libvips/foreign/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -75,7 +75,7 @@ typedef struct _VipsForeignSaveJpeg { */ int Q; - /* Profile to embed .. "none" means don't attach a profile. + /* Profile to embed. */ 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 @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 - * they are tagged. You can use the special string "none" to mean - * "don't attach a profile". + * they are tagged. See vips_profile_load() for details on profile naming. * * If no profile is specified and the VIPS header * contains an ICC profile named #VIPS_META_ICC_NAME, the diff --git a/libvips/foreign/pngsave.c b/libvips/foreign/pngsave.c index 0033c81e..b64576a7 100644 --- a/libvips/foreign/pngsave.c +++ b/libvips/foreign/pngsave.c @@ -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. * This does not affect the pixels which are written, just the way - * they are tagged. You can use the special string "none" to mean - * "don't attach a profile". + * they are tagged. See vips_profile_load() for details on profile naming. * * If @profile is specified and the VIPS header * contains an ICC profile named VIPS_META_ICC_NAME ("icc-profile-data"), the diff --git a/libvips/foreign/tiffsave.c b/libvips/foreign/tiffsave.c index 42c6a089..576ac179 100644 --- a/libvips/foreign/tiffsave.c +++ b/libvips/foreign/tiffsave.c @@ -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. * This does not affect the pixels which are written, just the way - * they are tagged. You can use the special string "none" to mean - * "don't attach a profile". + * they are tagged. See vips_profile_load() for details on profile naming. * * If no profile is specified and the VIPS header * contains an ICC profile named #VIPS_META_ICC_NAME, the diff --git a/libvips/foreign/vips2jpeg.c b/libvips/foreign/vips2jpeg.c index 50687216..5b8ee613 100644 --- a/libvips/foreign/vips2jpeg.c +++ b/libvips/foreign/vips2jpeg.c @@ -196,8 +196,6 @@ typedef struct { struct jpeg_compress_struct cinfo; ErrorManager eman; JSAMPROW *row_pointer; - char *profile_bytes; - size_t profile_length; VipsImage *inverted; } Write; @@ -207,7 +205,6 @@ write_destroy( Write *write ) jpeg_destroy_compress( &write->cinfo ); VIPS_FREEF( fclose, write->eman.fp ); VIPS_FREE( write->row_pointer ); - VIPS_FREE( write->profile_bytes ); VIPS_UNREF( write->inverted ); g_free( write ); @@ -227,8 +224,6 @@ write_new( VipsImage *in ) write->eman.pub.error_exit = vips__new_error_exit; write->eman.pub.output_message = vips__new_output_message; write->eman.fp = NULL; - write->profile_bytes = NULL; - write->profile_length = 0; write->inverted = NULL; return( write ); @@ -358,17 +353,25 @@ write_profile_data (j_compress_ptr cinfo, static int write_profile_file( Write *write, const char *profile ) { - if( !(write->profile_bytes = - vips__file_read_name( profile, vips__icc_dir(), - &write->profile_length )) ) + VipsBlob *blob; + + if( vips_profile_load( profile, &blob, NULL ) ) 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 - printf( "write_profile_file: attached profile \"%s\"\n", profile ); + printf( "write_profile_file: " + "attached profile \"%s\"\n", profile ); #endif /*DEBUG*/ + vips_area_unref( (VipsArea *) blob ); + } + return( 0 ); } @@ -376,15 +379,16 @@ static int write_profile_meta( Write *write ) { 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 ); - write_profile_data( &write->cinfo, data, size ); + write_profile_data( &write->cinfo, data, length ); #ifdef DEBUG printf( "write_profile_meta: attached %zd byte profile from header\n", - size ); + length ); #endif /*DEBUG*/ return( 0 ); @@ -596,10 +600,9 @@ write_vips( Write *write, int qfac, const char *profile, return( -1 ); /* A profile supplied as an argument overrides an embedded - * profile. "none" means don't attach a profile. + * profile. */ - if( profile && - strcmp( profile, "none" ) != 0 && + if( profile && write_profile_file( write, profile ) ) return( -1 ); if( !profile && diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 88ae3cd5..f952aca9 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -325,24 +325,29 @@ struct _Wtiff { int image_height; }; -/* Embed an ICC profile from a file. +/* Write an ICC Profile from a file into the JPEG stream. */ static int embed_profile_file( TIFF *tif, const char *profile ) { - char *buffer; - size_t length; + VipsBlob *blob; - if( !(buffer = vips__file_read_name( profile, - vips__icc_dir(), &length )) ) + if( vips_profile_load( profile, &blob, NULL ) ) 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 - printf( "vips2tiff: attached profile \"%s\"\n", profile ); + printf( "vips2tiff: attached profile \"%s\"\n", profile ); #endif /*DEBUG*/ + vips_area_unref( (VipsArea *) blob ); + } + return( 0 ); } @@ -352,11 +357,11 @@ static int embed_profile_meta( TIFF *tif, VipsImage *im ) { 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 ); - TIFFSetField( tif, TIFFTAG_ICCPROFILE, size, data ); + TIFFSetField( tif, TIFFTAG_ICCPROFILE, length, data ); #ifdef DEBUG printf( "vips2tiff: attached profile from meta\n" ); @@ -426,8 +431,7 @@ wtiff_layer_new( Wtiff *wtiff, Layer *above, int width, int height ) static int wtiff_embed_profile( Wtiff *wtiff, TIFF *tif ) { - if( wtiff->icc_profile && - strcmp( wtiff->icc_profile, "none" ) != 0 && + if( wtiff->icc_profile && embed_profile_file( tif, wtiff->icc_profile ) ) return( -1 ); diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index a348de6d..40d594cc 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -1071,13 +1071,13 @@ write_vips( Write *write, */ if( profile && !strip ) { - if( strcmp( profile, "none" ) != 0 ) { - void *data; - size_t length; + VipsBlob *blob; - if( !(data = vips__file_read_name( profile, - vips__icc_dir(), &length )) ) - return( -1 ); + if( vips_profile_load( profile, &blob, NULL ) ) + return( -1 ); + if( blob ) { + size_t length; + const void *data = vips_blob_get( blob, &length ); #ifdef DEBUG printf( "write_vips: " @@ -1087,6 +1087,8 @@ write_vips( Write *write, png_set_iCCP( write->pPng, write->pInfo, "icc", PNG_COMPRESSION_TYPE_BASE, data, length ); + + vips_area_unref( (VipsArea *) blob ); } } else if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) &&