diff --git a/ChangeLog b/ChangeLog index 538abcbd..0dd67b77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +30/1/12 started 7.28.0 + 30/1/12 started 7.28.0 - version bump - added vips_foreign_find_save_options()/vips_foreign_find_load_options() diff --git a/TODO b/TODO index ac8bf3a7..79013bd3 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,8 @@ resample foreign ======= +- magick2vips should spot ICC profiles and attach them as meta + - interlaced jpg needs massive memory, we should have two jpg read modes, like png @@ -64,10 +66,6 @@ foreign consider openexr write -- magick2vips should spot ICC profiles and attach them as meta - -- also png2vips? - - magick should set some header field for n_frames and frame_height? see also analyze diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 81090289..059d2bd5 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -389,7 +389,7 @@ embed_profile_file( TIFF *tif, const char *profile ) char *buffer; unsigned int length; - if( !(buffer = vips__file_read_name( profile, VIPS_ICC_DIR, &length )) ) + if( !(buffer = vips__file_read_name( profile, VIPS_ICC_DIR, &length )) ) return( -1 ); TIFFSetField( tif, TIFFTAG_ICCPROFILE, length, buffer ); vips_free( buffer ); diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index c94b7f8a..73568c1e 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -38,6 +38,8 @@ * - add support for sequential reads * 23/2/12 * - add a longjmp() to our error handler to stop the default one running + * 13/3/12 + * - add ICC profile read/write */ /* @@ -67,8 +69,8 @@ */ /* -#define DEBUG */ +#define DEBUG #ifdef HAVE_CONFIG_H #include @@ -185,6 +187,11 @@ png2vips_header( Read *read, VipsImage *out ) png_uint_32 res_x, res_y; int unit_type; + png_charp name; + int compression_type; + png_bytep profile; + png_uint_32 proflen; + int bands; VipsInterpretation interpretation; double Xres, Yres; @@ -296,6 +303,29 @@ png2vips_header( Read *read, VipsImage *out ) vips_demand_hint( out, VIPS_DEMAND_STYLE_FATSTRIP, NULL ); + /* Fetch the ICC profile. @name is useless, something like "icc" or + * "ICC Profile" etc. Ignore it. + * + * @profile was png_charpp in libpngs < 1.5, png_bytepp is the + * modern one. Ignore the warning, if any. + */ + if( png_get_iCCP( read->pPng, read->pInfo, + &name, &compression_type, &profile, &proflen ) ) { + void *profile_copy; + +#ifdef DEBUG + printf( "png2vips_header: attaching %zd bytes of ICC profile\n", + proflen ); + printf( "png2vips_header: name = \"%s\"\n", name ); +#endif /*DEBUG*/ + + if( !(profile_copy = vips_malloc( NULL, proflen )) ) + return( -1 ); + memcpy( profile_copy, profile, proflen ); + vips_image_set_blob( out, VIPS_META_ICC_NAME, + (VipsCallbackFn) vips_free, profile_copy, proflen ); + } + return( 0 ); } @@ -550,6 +580,8 @@ write_vips( Write *write, int compress, int interlace ) int color_type; int interlace_type; int i, nb_passes; + void *profile; + size_t profile_length; g_assert( in->BandFmt == VIPS_FORMAT_UCHAR || in->BandFmt == VIPS_FORMAT_USHORT ); @@ -599,6 +631,19 @@ write_vips( Write *write, int compress, int interlace ) VIPS_RINT( in->Xres * 1000 ), VIPS_RINT( in->Yres * 1000 ), PNG_RESOLUTION_METER ); + /* Set ICC Profile. + */ + if( !vips_image_get_blob( in, VIPS_META_ICC_NAME, + &profile, &profile_length ) ) { +#ifdef DEBUG + printf( "write_vips: attaching %zd bytes of ICC profile\n", + profile_length ); +#endif /*DEBUG*/ + + png_set_iCCP( write->pPng, write->pInfo, "icc", + PNG_COMPRESSION_TYPE_BASE, profile, profile_length ); + } + png_write_info( write->pPng, write->pInfo ); /* If we're an intel byte order CPU and this is a 16bit image, we need