diff --git a/libvips/colour/LabQ2sRGB.c b/libvips/colour/LabQ2sRGB.c index 1a298442..706ca9c1 100644 --- a/libvips/colour/LabQ2sRGB.c +++ b/libvips/colour/LabQ2sRGB.c @@ -86,7 +86,7 @@ static float vips_v2Y_16[65536]; * The matrix already includes the D65 channel weighting, so we just scale by * Y. */ -#define SCALE (VIPS_D65_Y0 / 3.0) +#define SCALE (VIPS_D65_Y0) /* linear RGB -> XYZ matrix. */ diff --git a/libvips/colour/colourspace.c b/libvips/colour/colourspace.c index c403ae9a..1aa1e400 100644 --- a/libvips/colour/colourspace.c +++ b/libvips/colour/colourspace.c @@ -164,10 +164,19 @@ static VipsColourRoute vips_colour_routes[] = { gboolean vips_colourspace_issupported( const VipsImage *image ) { - VipsInterpretation interpretation = - vips_image_guess_interpretation( image ); + VipsInterpretation interpretation; int i; + /* Treat RGB and RGB16 as sRGB. If you want some other treatment, + * you'll need to use the icc funcs. + * + * sRGB2XYZ can handle 8 and 16-bit images. + */ + interpretation = vips_image_guess_interpretation( image ); + if( interpretation == VIPS_INTERPRETATION_RGB || + interpretation == VIPS_INTERPRETATION_RGB16 ) + interpretation = VIPS_INTERPRETATION_sRGB; + for( i = 0; i < VIPS_NUMBER( vips_colour_routes ); i++ ) if( vips_colour_routes[i].from == interpretation ) return( TRUE ); @@ -209,6 +218,15 @@ vips_colourspace_build( VipsObject *object ) interpretation = vips_image_guess_interpretation( colourspace->in ); + /* Treat RGB and RGB16 as sRGB. If you want some other treatment, + * you'll need to use the icc funcs. + * + * sRGB2XYZ can handle 8 and 16-bit images. + */ + if( interpretation == VIPS_INTERPRETATION_RGB || + interpretation == VIPS_INTERPRETATION_RGB16 ) + interpretation = VIPS_INTERPRETATION_sRGB; + /* No conversion necessary. */ if( interpretation == colourspace->space ) { diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 0073fd1b..23a2b26c 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -234,8 +234,13 @@ vips_icc_build( VipsObject *object ) if( icc->out_profile ) switch( cmsGetColorSpace( icc->out_profile ) ) { case icSigRgbData: - colour->interpretation = VIPS_INTERPRETATION_RGB; - colour->format = VIPS_FORMAT_UCHAR; + colour->interpretation = + icc->depth == 8 ? + VIPS_INTERPRETATION_RGB : + VIPS_INTERPRETATION_RGB16; + colour->format = + icc->depth == 8 ? + VIPS_FORMAT_UCHAR : VIPS_FORMAT_USHORT; colour->bands = 3; icc->out_icc_format = icc->depth == 16 ? diff --git a/libvips/colour/sRGB2XYZ.c b/libvips/colour/sRGB2XYZ.c index a8f8dd76..0579a1ad 100644 --- a/libvips/colour/sRGB2XYZ.c +++ b/libvips/colour/sRGB2XYZ.c @@ -9,6 +9,8 @@ * 21/9/12 * - redone as a class * - sRGB only, support for other RGBs is now via lcms + * 6/11/12 + * - add 15-bit sRGB import */ /* @@ -57,12 +59,8 @@ G_DEFINE_TYPE( VipssRGB2XYZ, vips_sRGB2XYZ, VIPS_TYPE_COLOUR_CODE ); /* Convert a buffer of 8-bit pixels. */ static void -vips_sRGB2XYZ_line_8( VipsColour *colour, - VipsPel *out, VipsPel **in, int width ) +vips_sRGB2XYZ_line_8( float *q, VipsPel *p, int width ) { - VipsPel *p = in[0]; - float *q = (float *) out; - int i; for( i = 0; i < width; i++ ) { @@ -86,12 +84,8 @@ vips_sRGB2XYZ_line_8( VipsColour *colour, /* Convert a buffer of 16-bit pixels. */ static void -vips_sRGB2XYZ_line_16( VipsColour *colour, - VipsPel *out, VipsPel **in, int width ) +vips_sRGB2XYZ_line_16( float *q, unsigned short *p, int width ) { - unsigned short *p = in[0]; - float *q = (float *) out; - int i; for( i = 0; i < width; i++ ) { @@ -112,6 +106,35 @@ vips_sRGB2XYZ_line_16( VipsColour *colour, } } +static void +vips_sRGB2XYZ_line( VipsColour *colour, + VipsPel *out, VipsPel **in, int width ) +{ + if( colour->in[0]->BandFmt == VIPS_FORMAT_UCHAR ) + vips_sRGB2XYZ_line_8( (float *) out, + (VipsPel *) in[0], width ); + else + vips_sRGB2XYZ_line_16( (float *) out, + (unsigned short *) in[0], width ); +} + +static int +vips_sRGB2XYZ_build( VipsObject *object ) +{ + VipsColourCode *code = (VipsColourCode *) object; + + if( code->in ) + code->input_format = + code->in->BandFmt == VIPS_FORMAT_USHORT ? + VIPS_FORMAT_USHORT : VIPS_FORMAT_UCHAR; + + if( VIPS_OBJECT_CLASS( vips_sRGB2XYZ_parent_class )-> + build( object ) ) + return( -1 ); + + return( 0 ); +} + static void vips_sRGB2XYZ_class_init( VipssRGB2XYZClass *class ) { @@ -120,6 +143,7 @@ vips_sRGB2XYZ_class_init( VipssRGB2XYZClass *class ) object_class->nickname = "sRGB2XYZ"; object_class->description = _( "convert an sRGB image to XYZ" ); + object_class->build = vips_sRGB2XYZ_build; colour_class->process_line = vips_sRGB2XYZ_line; } @@ -137,6 +161,10 @@ vips_sRGB2XYZ_init( VipssRGB2XYZ *sRGB2XYZ ) code->input_coding = VIPS_CODING_NONE; code->input_bands = 3; + + /* The default. This can get changed above ^^ if we see a + * 16-bit input. + */ code->input_format = VIPS_FORMAT_UCHAR; }