diff --git a/ChangeLog b/ChangeLog index a6db28c2..908571db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ - don't stop composite on first non-transparent image [felixbuenemann, GDmac] - add vips_rect_overlapsrect() - composite is much faster at positioning subimages +- add CMYK as a supported colourspace 21/11/18 started 8.7.3 - fix infinite loop for autofit with non-scaleable font diff --git a/libvips/colour/CMYK2XYZ.c b/libvips/colour/CMYK2XYZ.c index fa2230c1..d85dfe12 100644 --- a/libvips/colour/CMYK2XYZ.c +++ b/libvips/colour/CMYK2XYZ.c @@ -2,7 +2,7 @@ * vips_icc_import. * * 21/12/18 - * - from CMYK2XYZ + * - from scRGB2XYZ.c */ /* @@ -43,38 +43,135 @@ #include #include +#include #include "pcolour.h" +#include "profiles.h" -typedef VipsColourTransform VipsCMYK2XYZ; -typedef VipsColourTransformClass VipsCMYK2XYZClass; +typedef struct _VipsCMYK2XYZ { + VipsOperation parent_instance; -G_DEFINE_TYPE( VipsCMYK2XYZ, vips_CMYK2XYZ, VIPS_TYPE_COLOUR_TRANSFORM ); + VipsImage *in; + VipsImage *out; +} VipsCMYK2XYZ; -void -vips_CMYK2XYZ_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) +typedef VipsColourCodeClass VipsCMYK2XYZClass; + +G_DEFINE_TYPE( VipsCMYK2XYZ, vips_CMYK2XYZ, VIPS_TYPE_OPERATION ); + +/* Created on first use from a base64 string in profiles.c. + */ +static void *vips_CMYK2XYZ_fallback_profile = NULL; +static size_t vips_CMYK2XYZ_fallback_profile_length = 0; + +static void * +vips_CMYK2XYZ_get_fallback_profile_init( void ) { - /* Or maybe subclass icc_import? */ + size_t data_length; + unsigned char *data; + + if( !(data = vips__b64_decode( vips__coded_cmyk, &data_length )) ) + return( NULL ); + vips_CMYK2XYZ_fallback_profile = data; + vips_CMYK2XYZ_fallback_profile_length = data_length; + + return( NULL ); +} + +static void * +vips__CMYK2XYZ_get_fallback_profile( size_t *length ) +{ + GOnce once = G_ONCE_INIT; + + VIPS_ONCE( &once, + (GThreadFunc) vips_CMYK2XYZ_get_fallback_profile_init, NULL ); + + *length = vips_CMYK2XYZ_fallback_profile_length; + + return( vips_CMYK2XYZ_fallback_profile ); +} + +/* Shared with XYZ2CMYK.c. + * + * FIXME ... should this remove and replace a non-CMYK profile? + */ +int +vips_CMYK2XYZ_set_fallback_profile( VipsImage *image ) +{ + size_t data_length; + unsigned char *data; + + if( vips_image_get_typeof( image, VIPS_META_ICC_NAME ) ) + return( -1 ); + + if( !(data = vips__CMYK2XYZ_get_fallback_profile( &data_length )) ) + return( -1 ); + + vips_image_set_blob( image, VIPS_META_ICC_NAME, + NULL, data, data_length ); + + return( 0 ); +} + +static int +vips_CMYK2XYZ_build( VipsObject *object ) +{ + VipsCMYK2XYZ *CMYK2XYZ = (VipsCMYK2XYZ *) object; + VipsImage **t = (VipsImage **) vips_object_local_array( object, 7 ); + + VipsImage *out; + + if( VIPS_OBJECT_CLASS( vips_CMYK2XYZ_parent_class )->build( object ) ) + return( -1 ); + + out = vips_image_new(); + g_object_set( object, "out", out, NULL ); + + if( vips_copy( CMYK2XYZ->in, &t[0], NULL ) || + vips_CMYK2XYZ_set_fallback_profile( t[0] ) || + vips_icc_import( t[0], &t[1], + "embedded", TRUE, + "pcs", VIPS_PCS_XYZ, + NULL ) || + vips_image_write( t[1], out ) ) + return( -1 ); + + return( 0 ); } static void vips_CMYK2XYZ_class_init( VipsCMYK2XYZClass *class ) { + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsColourClass *colour_class = VIPS_COLOUR_CLASS( class ); + VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class ); + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; object_class->nickname = "CMYK2XYZ"; object_class->description = _( "transform CMYK to XYZ" ); + object_class->build = vips_CMYK2XYZ_build; + + operation_class->flags = VIPS_OPERATION_SEQUENTIAL; + + VIPS_ARG_IMAGE( class, "in", 1, + _( "Input" ), + _( "Input image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsCMYK2XYZ, in ) ); + + VIPS_ARG_IMAGE( class, "out", 100, + _( "Output" ), + _( "Output image" ), + VIPS_ARGUMENT_REQUIRED_OUTPUT, + G_STRUCT_OFFSET( VipsCMYK2XYZ, out ) ); - colour_class->process_line = vips_CMYK2XYZ_line; } static void vips_CMYK2XYZ_init( VipsCMYK2XYZ *CMYK2XYZ ) { - VipsColour *colour = VIPS_COLOUR( CMYK2XYZ ); - - colour->interpretation = VIPS_INTERPRETATION_XYZ; } #endif /*HAVE_LCMS2*/ @@ -85,7 +182,12 @@ vips_CMYK2XYZ_init( VipsCMYK2XYZ *CMYK2XYZ ) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Turn XYZ to CMYK. + * Turn CMYK to XYZ. If the image has an embedded ICC profile this will be + * used for the conversion. If there is no embedded profile, a generic + * fallback profile will be used. + * + * Conversion is to D65 XYZ with relative intent. If you need more control + * over the process, use vips_icc_import() instead. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/colour/Makefile.am b/libvips/colour/Makefile.am index 11ea3f8c..09d8b55e 100644 --- a/libvips/colour/Makefile.am +++ b/libvips/colour/Makefile.am @@ -10,6 +10,8 @@ libcolour_la_SOURCES = \ $(PROFILES) \ colour.c \ pcolour.h \ + CMYK2XYZ.c \ + XYZ2CMYK.c \ colourspace.c \ dE76.c \ dE00.c \ diff --git a/libvips/colour/XYZ2CMYK.c b/libvips/colour/XYZ2CMYK.c new file mode 100644 index 00000000..66d356f1 --- /dev/null +++ b/libvips/colour/XYZ2CMYK.c @@ -0,0 +1,150 @@ +/* Use lcms to move from XYZ to CMYK, if we can. This needs a working + * vips_icc_export. + * + * 21/12/18 + * - from CMYK2XYZ.c + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#ifdef HAVE_LCMS2 + +#include +#include + +#include +#include + +#include "pcolour.h" +#include "profiles.h" + +typedef struct _VipsXYZ2CMYK { + VipsOperation parent_instance; + + VipsImage *in; + VipsImage *out; +} VipsXYZ2CMYK; + +typedef VipsColourCodeClass VipsXYZ2CMYKClass; + +G_DEFINE_TYPE( VipsXYZ2CMYK, vips_XYZ2CMYK, VIPS_TYPE_OPERATION ); + +static int +vips_XYZ2CMYK_build( VipsObject *object ) +{ + VipsXYZ2CMYK *XYZ2CMYK = (VipsXYZ2CMYK *) object; + VipsImage **t = (VipsImage **) vips_object_local_array( object, 7 ); + + VipsImage *out; + + if( VIPS_OBJECT_CLASS( vips_XYZ2CMYK_parent_class )->build( object ) ) + return( -1 ); + + out = vips_image_new(); + g_object_set( object, "out", out, NULL ); + + if( vips_copy( XYZ2CMYK->in, &t[0], NULL ) || + vips_CMYK2XYZ_set_fallback_profile( t[0] ) || + vips_icc_export( t[0], &t[1], + "pcs", VIPS_PCS_XYZ, + NULL ) || + vips_image_write( t[1], out ) ) + return( -1 ); + + return( 0 ); +} + +static void +vips_XYZ2CMYK_class_init( VipsXYZ2CMYKClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *object_class = (VipsObjectClass *) class; + VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class ); + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + object_class->nickname = "XYZ2CMYK"; + object_class->description = _( "transform XYZ to CMYK" ); + object_class->build = vips_XYZ2CMYK_build; + + operation_class->flags = VIPS_OPERATION_SEQUENTIAL; + + VIPS_ARG_IMAGE( class, "in", 1, + _( "Input" ), + _( "Input image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsXYZ2CMYK, in ) ); + + VIPS_ARG_IMAGE( class, "out", 100, + _( "Output" ), + _( "Output image" ), + VIPS_ARGUMENT_REQUIRED_OUTPUT, + G_STRUCT_OFFSET( VipsXYZ2CMYK, out ) ); + +} + +static void +vips_XYZ2CMYK_init( VipsXYZ2CMYK *XYZ2CMYK ) +{ +} + +#endif /*HAVE_LCMS2*/ + +/** + * vips_XYZ2CMYK: (method) + * @in: input image + * @out: (out): output image + * @...: %NULL-terminated list of optional named arguments + * + * Turn XYZ to CMYK. If the image has an embedded ICC profile this will be + * used for the conversion. If there is no embedded profile, a generic + * fallback profile will be used. + * + * Conversion is from D65 XYZ with relative intent. If you need more control + * over the process, use vips_icc_export() instead. + * + * Returns: 0 on success, -1 on error + */ +int +vips_XYZ2CMYK( VipsImage *in, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_call_split( "XYZ2CMYK", ap, in, out ); + va_end( ap ); + + return( result ); +} diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index 810c2da8..d8f7ac1c 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -756,6 +756,8 @@ vips_colour_operation_init( void ) extern GType vips_icc_import_get_type( void ); extern GType vips_icc_export_get_type( void ); extern GType vips_icc_transform_get_type( void ); + extern GType vips_CMYK2XYZ_get_type( void ); + extern GType vips_XYZ2CMYK_get_type( void ); #endif extern GType vips_dE76_get_type( void ); extern GType vips_dE00_get_type( void ); @@ -790,6 +792,8 @@ vips_colour_operation_init( void ) vips_icc_import_get_type(); vips_icc_export_get_type(); vips_icc_transform_get_type(); + vips_CMYK2XYZ_get_type(); + vips_XYZ2CMYK_get_type(); #endif vips_dE76_get_type(); vips_dE00_get_type(); diff --git a/libvips/colour/colourspace.c b/libvips/colour/colourspace.c index 250c91ca..91b7e35d 100644 --- a/libvips/colour/colourspace.c +++ b/libvips/colour/colourspace.c @@ -19,6 +19,8 @@ * 17/4/15 * - better conversion to greyscale, see * https://github.com/lovell/sharp/issues/193 + * 27/12/18 + * - add CMYK conversions */ /* @@ -205,6 +207,7 @@ typedef struct _VipsColourRoute { #define LCH VIPS_INTERPRETATION_LCH #define CMC VIPS_INTERPRETATION_CMC #define LABS VIPS_INTERPRETATION_LABS +#define CMYK VIPS_INTERPRETATION_CMYK #define scRGB VIPS_INTERPRETATION_scRGB #define sRGB VIPS_INTERPRETATION_sRGB #define HSV VIPS_INTERPRETATION_HSV @@ -221,6 +224,7 @@ static VipsColourRoute vips_colour_routes[] = { { XYZ, LCH, { vips_XYZ2Lab, vips_Lab2LCh, NULL } }, { XYZ, CMC, { vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, { XYZ, LABS, { vips_XYZ2Lab, vips_Lab2LabS, NULL } }, + { XYZ, CMYK, { vips_XYZ2CMYK, NULL } }, { XYZ, scRGB, { vips_XYZ2scRGB, NULL } }, { XYZ, sRGB, { vips_XYZ2scRGB, vips_scRGB2sRGB, NULL } }, { XYZ, HSV, { vips_XYZ2scRGB, vips_scRGB2sRGB, vips_sRGB2HSV, NULL } }, @@ -234,9 +238,11 @@ static VipsColourRoute vips_colour_routes[] = { { LAB, LCH, { vips_Lab2LCh, NULL } }, { LAB, CMC, { vips_Lab2LCh, vips_LCh2CMC, NULL } }, { LAB, LABS, { vips_Lab2LabS, NULL } }, + { LAB, CMYK, { vips_Lab2XYZ, vips_XYZ2CMYK, NULL } }, { LAB, scRGB, { vips_Lab2XYZ, vips_XYZ2scRGB, NULL } }, { LAB, sRGB, { vips_Lab2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, NULL } }, - { LAB, HSV, { vips_Lab2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, vips_sRGB2HSV, NULL } }, + { LAB, HSV, { vips_Lab2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, + vips_sRGB2HSV, NULL } }, { LAB, BW, { vips_Lab2XYZ, vips_XYZ2scRGB, vips_scRGB2BW, NULL } }, { LAB, RGB16, { vips_Lab2XYZ, vips_XYZ2scRGB, vips_scRGB2RGB16, NULL } }, @@ -249,6 +255,7 @@ static VipsColourRoute vips_colour_routes[] = { { LABQ, LCH, { vips_LabQ2Lab, vips_Lab2LCh, NULL } }, { LABQ, CMC, { vips_LabQ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, { LABQ, LABS, { vips_LabQ2LabS, NULL } }, + { LABQ, CMYK, { vips_LabQ2Lab, vips_Lab2XYZ, vips_XYZ2CMYK } }, { LABQ, scRGB, { vips_LabQ2Lab, vips_Lab2XYZ, vips_XYZ2scRGB } }, { LABQ, sRGB, { vips_LabQ2sRGB, NULL } }, { LABQ, HSV, { vips_LabQ2sRGB, vips_sRGB2HSV, NULL } }, @@ -265,6 +272,7 @@ static VipsColourRoute vips_colour_routes[] = { { LCH, LABQ, { vips_LCh2Lab, vips_Lab2LabQ, NULL } }, { LCH, CMC, { vips_LCh2CMC, NULL } }, { LCH, LABS, { vips_LCh2Lab, vips_Lab2LabS, NULL } }, + { LCH, CMYK, { vips_LCh2Lab, vips_Lab2XYZ, vips_XYZ2CMYK, NULL } }, { LCH, scRGB, { vips_LCh2Lab, vips_Lab2XYZ, vips_XYZ2scRGB, NULL } }, { LCH, sRGB, { vips_LCh2Lab, vips_Lab2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, NULL } }, @@ -283,6 +291,8 @@ static VipsColourRoute vips_colour_routes[] = { { CMC, LABQ, { vips_CMC2LCh, vips_LCh2Lab, vips_Lab2LabQ, NULL } }, { CMC, LCH, { vips_CMC2LCh, NULL } }, { CMC, LABS, { vips_CMC2LCh, vips_LCh2Lab, vips_Lab2LabS, NULL } }, + { CMC, CMYK, { vips_CMC2LCh, vips_LCh2Lab, vips_Lab2XYZ, + vips_XYZ2CMYK, NULL } }, { CMC, scRGB, { vips_CMC2LCh, vips_LCh2Lab, vips_Lab2XYZ, vips_XYZ2scRGB, NULL } }, { CMC, sRGB, { vips_CMC2LCh, vips_LCh2Lab, vips_Lab2XYZ, @@ -303,6 +313,7 @@ static VipsColourRoute vips_colour_routes[] = { { LABS, LABQ, { vips_LabS2LabQ, NULL } }, { LABS, LCH, { vips_LabS2Lab, vips_Lab2LCh, NULL } }, { LABS, CMC, { vips_LabS2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, + { LABS, CMYK, { vips_LabS2Lab, vips_Lab2XYZ, vips_XYZ2CMYK, NULL } }, { LABS, scRGB, { vips_LabS2Lab, vips_Lab2XYZ, vips_XYZ2scRGB, NULL } }, { LABS, sRGB, { vips_LabS2Lab, vips_Lab2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, NULL } }, @@ -322,6 +333,7 @@ static VipsColourRoute vips_colour_routes[] = { { scRGB, LCH, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } }, { scRGB, CMC, { vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, + { scRGB, CMYK, { vips_scRGB2XYZ, vips_XYZ2CMYK, NULL } }, { scRGB, sRGB, { vips_scRGB2sRGB, NULL } }, { scRGB, HSV, { vips_scRGB2sRGB, vips_sRGB2HSV, NULL } }, { scRGB, BW, { vips_scRGB2BW, NULL } }, @@ -330,6 +342,25 @@ static VipsColourRoute vips_colour_routes[] = { { scRGB, GREY16, { vips_scRGB2BW16, NULL } }, { scRGB, YXY, { vips_scRGB2XYZ, vips_XYZ2Yxy, NULL } }, + { CMYK, XYZ, { vips_CMYK2XYZ, NULL } }, + { CMYK, LAB, { vips_CMYK2XYZ, vips_XYZ2Lab, NULL } }, + { CMYK, LABQ, { vips_CMYK2XYZ, vips_XYZ2Lab, vips_Lab2LabQ, NULL } }, + { CMYK, LCH, { vips_CMYK2XYZ, vips_XYZ2Lab, vips_Lab2LCh, NULL } }, + { CMYK, CMC, { vips_CMYK2XYZ, vips_XYZ2Lab, + vips_Lab2LCh, vips_LCh2CMC, NULL } }, + { CMYK, scRGB, { vips_CMYK2XYZ, vips_XYZ2scRGB, NULL } }, + { CMYK, sRGB, { vips_CMYK2XYZ, vips_XYZ2scRGB, + vips_scRGB2sRGB, NULL } }, + { CMYK, HSV, { vips_CMYK2XYZ, vips_XYZ2scRGB, + vips_scRGB2sRGB, vips_sRGB2HSV, NULL } }, + { CMYK, BW, { vips_CMYK2XYZ, vips_XYZ2scRGB, vips_scRGB2BW, NULL } }, + { CMYK, LABS, { vips_CMYK2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } }, + { CMYK, RGB16, { vips_CMYK2XYZ, vips_XYZ2scRGB, + vips_scRGB2RGB16, NULL } }, + { CMYK, GREY16, { vips_CMYK2XYZ, vips_XYZ2scRGB, + vips_scRGB2BW16, NULL } }, + { CMYK, YXY, { vips_CMYK2XYZ, vips_XYZ2Yxy, NULL } }, + { sRGB, XYZ, { vips_sRGB2scRGB, vips_scRGB2XYZ, NULL } }, { sRGB, LAB, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, NULL } }, { sRGB, LABQ, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, @@ -338,6 +369,8 @@ static VipsColourRoute vips_colour_routes[] = { vips_Lab2LCh, NULL } }, { sRGB, CMC, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, + { sRGB, CMYK, { vips_sRGB2scRGB, vips_scRGB2XYZ, + vips_XYZ2CMYK, NULL } }, { sRGB, scRGB, { vips_sRGB2scRGB, NULL } }, { sRGB, HSV, { vips_sRGB2HSV, NULL } }, { sRGB, BW, { vips_sRGB2scRGB, vips_scRGB2BW, NULL } }, @@ -356,6 +389,8 @@ static VipsColourRoute vips_colour_routes[] = { vips_XYZ2Lab, vips_Lab2LCh, NULL } }, { HSV, CMC, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, + { HSV, CMYK, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, + vips_XYZ2CMYK, NULL } }, { HSV, scRGB, { vips_HSV2sRGB, vips_sRGB2scRGB, NULL } }, { HSV, sRGB, { vips_HSV2sRGB, NULL } }, { HSV, BW, { vips_HSV2sRGB, vips_sRGB2scRGB, vips_scRGB2BW, NULL } }, @@ -375,6 +410,8 @@ static VipsColourRoute vips_colour_routes[] = { vips_Lab2LCh, NULL } }, { RGB16, CMC, { vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, + { RGB16, CMYK, { vips_sRGB2scRGB, vips_scRGB2XYZ, + vips_XYZ2CMYK, NULL } }, { RGB16, scRGB, { vips_sRGB2scRGB, NULL } }, { RGB16, sRGB, { vips_RGB162sRGB, NULL } }, { RGB16, HSV, { vips_RGB162sRGB, vips_sRGB2HSV, NULL } }, @@ -394,9 +431,12 @@ static VipsColourRoute vips_colour_routes[] = { vips_XYZ2Lab, vips_Lab2LCh, NULL } }, { GREY16, CMC, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, + { GREY16, CMYK, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, + vips_XYZ2CMYK, NULL } }, { GREY16, scRGB, { vips_GREY162RGB16, vips_sRGB2scRGB, NULL } }, { GREY16, sRGB, { vips_GREY162RGB16, vips_RGB162sRGB, NULL } }, - { GREY16, HSV, { vips_GREY162RGB16, vips_RGB162sRGB, vips_sRGB2HSV, NULL } }, + { GREY16, HSV, { vips_GREY162RGB16, vips_RGB162sRGB, + vips_sRGB2HSV, NULL } }, { GREY16, BW, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2BW, NULL } }, { GREY16, LABS, { vips_GREY162RGB16, vips_sRGB2scRGB, vips_scRGB2XYZ, @@ -414,6 +454,8 @@ static VipsColourRoute vips_colour_routes[] = { vips_XYZ2Lab, vips_Lab2LCh, NULL } }, { BW, CMC, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, + { BW, CMYK, { vips_BW2sRGB, vips_sRGB2scRGB, vips_scRGB2XYZ, + vips_XYZ2CMYK, NULL } }, { BW, scRGB, { vips_BW2sRGB, vips_sRGB2scRGB, NULL } }, { BW, sRGB, { vips_BW2sRGB, NULL } }, { BW, HSV, { vips_BW2sRGB, vips_sRGB2HSV, NULL } }, @@ -432,9 +474,11 @@ static VipsColourRoute vips_colour_routes[] = { { YXY, CMC, { vips_Yxy2XYZ, vips_XYZ2Lab, vips_Lab2LCh, vips_LCh2CMC, NULL } }, { YXY, LABS, { vips_Yxy2XYZ, vips_XYZ2Lab, vips_Lab2LabS, NULL } }, + { YXY, CMYK, { vips_Yxy2XYZ, vips_XYZ2CMYK, NULL } }, { YXY, scRGB, { vips_Yxy2XYZ, vips_XYZ2scRGB, NULL } }, { YXY, sRGB, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, NULL } }, - { YXY, HSV, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, vips_sRGB2HSV, NULL } }, + { YXY, HSV, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2sRGB, + vips_sRGB2HSV, NULL } }, { YXY, BW, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2BW, NULL } }, { YXY, RGB16, { vips_Yxy2XYZ, vips_XYZ2scRGB, vips_scRGB2RGB16, NULL } }, diff --git a/libvips/colour/pcolour.h b/libvips/colour/pcolour.h index be93b647..ea993163 100644 --- a/libvips/colour/pcolour.h +++ b/libvips/colour/pcolour.h @@ -216,6 +216,8 @@ extern float vips_v2Y_16[65536]; void vips_col_make_tables_RGB_8( void ); void vips_col_make_tables_RGB_16( void ); +int vips_CMYK2XYZ_set_fallback_profile( VipsImage *image ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/colour.h b/libvips/include/vips/colour.h index 7978d325..e12c3a34 100644 --- a/libvips/include/vips/colour.h +++ b/libvips/include/vips/colour.h @@ -167,6 +167,11 @@ int vips_LabS2Lab( VipsImage *in, VipsImage **out, ... ) int vips_Lab2LabS( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); +int vips_CMYK2XYZ( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); +int vips_XYZ2CMYK( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); + int vips_icc_present( void ); int vips_icc_transform( VipsImage *in, VipsImage **out, const char *output_profile, ... )