diff --git a/ChangeLog b/ChangeLog index 2a9c1ed2..af06e281 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,7 +5,8 @@ im_LabS2LabQ(), im_LabQ2disp(), im_XYZ2disp(), im_disp2XYZ(), im_icc_import*(), im_icc_export*(), im_icc_transform*(), im_dE_fromLab(), im_dECMC_fromLab(), im_dE00_from_Lab(), im_icc_ac2rc() as classes -- added vips_colourspace(), replaces all derived conversions +- added vips_colourspace(), vips_colourspace_issupported(), replaces all + derived conversions - faster and more accurate sRGB <-> XYZ conversion - rename UCS colourspace as CMC - dzsave can write zoomify and google maps layout as well diff --git a/libvips/colour/colourspace.c b/libvips/colour/colourspace.c index c892df4b..c403ae9a 100644 --- a/libvips/colour/colourspace.c +++ b/libvips/colour/colourspace.c @@ -148,6 +148,34 @@ static VipsColourRoute vips_colour_routes[] = { { YXY, sRGB, { vips_Yxy2XYZ, vips_XYZ2sRGB, NULL } }, }; +/* Is an image in a supported colourspace. + */ + +/** + * vips_colourspace_issupported: + * @in: input image + * + * Test if @image is in a colourspace that vips_colourspace() can process. For + * example, #VIPS_INTERPRETATION_RGB images are not in a well-defined + * colourspace, but #VIPS_INTERPRETATION_sRGB ones are. + * + * Returns: %TRUE if @image is in a supported colourspace. + */ +gboolean +vips_colourspace_issupported( const VipsImage *image ) +{ + VipsInterpretation interpretation = + vips_image_guess_interpretation( image ); + int i; + + for( i = 0; i < VIPS_NUMBER( vips_colour_routes ); i++ ) + if( vips_colour_routes[i].from == interpretation ) + return( TRUE ); + + return( FALSE ); +} + + typedef struct _VipsColourspace { VipsOperation parent_instance; @@ -262,12 +290,17 @@ vips_colourspace_init( VipsColourspace *colourspace ) * @out: output image * @space: convert to this colour space * - * This convenience function looks at the interpretation field of @in and runs + * This operation looks at the interpretation field of @in and runs * a set of colourspace conversion functions to move it to @space. * * For example, given an image tagged as #VIPS_INTERPRETATION_YXY, running * vips_colourspace() with @space set to #VIPS_INTERPRETATION_LAB will * convert with vips_Yxy2XYZ() and vips_XYZ2Lab(). + * + * See also: vips_colourspace_issupported(), + * vips_image_guess_interpretation(). + * + * Returns: 0 on success, -1 on error. */ int vips_colourspace( VipsImage *in, VipsImage **out, diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 53baccfa..8ccae8c3 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1238,7 +1238,8 @@ vips_foreign_convert_saveable( VipsForeignSave *save ) /* Interpret the Type field for colorimetric images. */ - if( in->Bands == 3 ) { + if( in->Bands == 3 && + vips_colourspace_issupported( in ) ) { VipsImage *out; if( vips_colourspace( in, &out, diff --git a/libvips/include/vips/colour.h b/libvips/include/vips/colour.h index 0ede6c05..53868678 100644 --- a/libvips/include/vips/colour.h +++ b/libvips/include/vips/colour.h @@ -110,6 +110,7 @@ typedef enum { VIPS_INTENT_ABSOLUTE } VipsIntent; +gboolean vips_colourspace_issupported( const VipsImage *image ); int vips_colourspace( VipsImage *in, VipsImage **out, VipsInterpretation space, ... ) __attribute__((sentinel));