From cffe3bf965412dd184c0a57abb6c3a5b5cd14781 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 19 Jan 2014 17:30:56 +0000 Subject: [PATCH] pack Radiance images to and from 0-1 so this now works: $ vips copy uffizi_probe.hdr x.jpg $ eog x.jpg $ vips copy x.jpg x.hdr $ vips copy x.hdr x2.jpg $ eog x2.jpg --- ChangeLog | 1 + TODO | 1 + libvips/colour/colourspace.c | 27 ++++++++++++++++++++------- libvips/foreign/foreign.c | 35 +++++++++++++++++++++++++++-------- libvips/foreign/radiance.c | 2 +- libvips/foreign/radsave.c | 4 ++-- 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 326e89d3..a751638c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 19/1/14 started 7.38.1 - bump soname, thanks benjamin +- better conversion to and from scrgb/xyz for rad (hdr) 18/1/14 started 7.38.0 - version bump diff --git a/TODO b/TODO index 352a1fa0..701fda57 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,4 @@ + - need to do mosaicing and inplace, plus im_label_regions in morph - now vips_linear() has uchar output, can we do something with orc? diff --git a/libvips/colour/colourspace.c b/libvips/colour/colourspace.c index 88d6eb65..111438ed 100644 --- a/libvips/colour/colourspace.c +++ b/libvips/colour/colourspace.c @@ -6,6 +6,8 @@ * - add B_W as a source / dest * - add GREY16 as a source / dest * - add RGB16 as a source + * 19/1/14 + * - auto-decode RAD images */ /* @@ -399,11 +401,13 @@ vips_colourspace_build( VipsObject *object ) int i, j; VipsImage *x; - VipsImage **t; + VipsImage **t = (VipsImage **) + vips_object_local_array( object, 1 ); + VipsImage **pipe = (VipsImage **) + vips_object_local_array( object, MAX_STEPS ); VipsInterpretation interpretation; - t = (VipsImage **) vips_object_local_array( object, MAX_STEPS ); /* Verify that all input args have been set. */ @@ -411,7 +415,18 @@ vips_colourspace_build( VipsObject *object ) build( object ) ) return( -1 ); - interpretation = vips_image_guess_interpretation( colourspace->in ); + x = colourspace->in; + + /* Unpack radiance-coded images. We can't use interpretation for this, + * since rad images can be scRGB or XYZ. + */ + if( x->Coding == VIPS_CODING_RAD ) { + if( vips_rad2float( x, &t[0], NULL ) ) + return( -1 ); + x = t[0]; + } + + interpretation = vips_image_guess_interpretation( x ); /* Treat RGB and RGB16 as sRGB. If you want some other treatment, * you'll need to use the icc funcs. @@ -430,8 +445,6 @@ vips_colourspace_build( VipsObject *object ) return( vips_image_write( colourspace->in, colourspace->out ) ); } - x = colourspace->in; - for( i = 0; i < VIPS_NUMBER( vips_colour_routes ); i++ ) if( vips_colour_routes[i].from == interpretation && vips_colour_routes[i].to == colourspace->space ) @@ -447,9 +460,9 @@ vips_colourspace_build( VipsObject *object ) } for( j = 0; vips_colour_routes[i].route[j]; j++ ) { - if( vips_colour_routes[i].route[j]( x, &t[j], NULL ) ) + if( vips_colour_routes[i].route[j]( x, &pipe[j], NULL ) ) return( -1 ); - x = t[j]; + x = pipe[j]; } g_object_set( colourspace, "out", vips_image_new(), NULL ); diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 33de8c4c..51f1167f 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -6,6 +6,8 @@ * - flatten alpha with vips_flatten() * 28/5/13 * - auto rshift down to 8 bits during save + * 19/1/14 + * - pack and unpack rad to scrgb */ /* @@ -1149,8 +1151,8 @@ vips_foreign_convert_saveable( VipsForeignSave *save ) in = out; } - /* If this is an VIPS_CODING_RAD, we go to float RGB or XYZ. We should - * probably un-gamma-correct the RGB :( + /* If this is an VIPS_CODING_RAD, we unpack to float. This could be + * scRGB or XYZ. */ if( in->Coding == VIPS_CODING_RAD ) { VipsImage *out; @@ -1248,10 +1250,27 @@ vips_foreign_convert_saveable( VipsForeignSave *save ) */ } - /* Interpret the Type field for colorimetric images. + /* If the saver supports RAD, we need to go to scRGB or XYZ. */ - if( in->Bands == 3 && + if( class->coding[VIPS_CODING_RAD] ) { + if( in->Type != VIPS_INTERPRETATION_scRGB && + in->Type != VIPS_INTERPRETATION_XYZ ) { + VipsImage *out; + + if( vips_colourspace( in, &out, + VIPS_INTERPRETATION_scRGB, NULL ) ) { + g_object_unref( in ); + return( -1 ); + } + g_object_unref( in ); + + in = out; + } + } + else if( in->Bands == 3 && vips_colourspace_issupported( in ) ) { + /* Interpret the Type field for colorimetric images. + */ VipsImage *out; if( vips_colourspace( in, &out, @@ -1307,10 +1326,10 @@ vips_foreign_convert_saveable( VipsForeignSave *save ) /* Already NONE, nothing to do. */ } - else if( class->coding[VIPS_CODING_RAD] ) { + else if( class->coding[VIPS_CODING_LABQ] ) { VipsImage *out; - if( vips_float2rad( in, &out, NULL ) ) { + if( vips_Lab2LabQ( in, &out, NULL ) ) { g_object_unref( in ); return( -1 ); } @@ -1318,10 +1337,10 @@ vips_foreign_convert_saveable( VipsForeignSave *save ) in = out; } - else if( class->coding[VIPS_CODING_LABQ] ) { + else if( class->coding[VIPS_CODING_RAD] ) { VipsImage *out; - if( vips_Lab2LabQ( in, &out, NULL ) ) { + if( vips_float2rad( in, &out, NULL ) ) { g_object_unref( in ); return( -1 ); } diff --git a/libvips/foreign/radiance.c b/libvips/foreign/radiance.c index 4275375c..e45a944f 100644 --- a/libvips/foreign/radiance.c +++ b/libvips/foreign/radiance.c @@ -1162,7 +1162,7 @@ vips2rad_put_header( Write *write ) if( !vips_image_get_string( write->in, "rad-format", &str ) ) vips_strncpy( write->format, str, 256 ); - if( write->in->Type == VIPS_INTERPRETATION_RGB ) + if( write->in->Type == VIPS_INTERPRETATION_scRGB ) strcpy( write->format, COLRFMT ); if( write->in->Type == VIPS_INTERPRETATION_XYZ ) strcpy( write->format, CIEFMT ); diff --git a/libvips/foreign/radsave.c b/libvips/foreign/radsave.c index 43ee0f09..b870f7d3 100644 --- a/libvips/foreign/radsave.c +++ b/libvips/foreign/radsave.c @@ -89,7 +89,7 @@ vips_foreign_save_rad_build( VipsObject *object ) #define D VIPS_FORMAT_DOUBLE #define DX VIPS_FORMAT_DPCOMPLEX -static int bandfmt_rad[10] = { +static int vips_foreign_save_rad_format_table[10] = { /* UC C US S UI I F X D DX */ F, F, F, F, F, F, F, F, F, F }; @@ -112,7 +112,7 @@ vips_foreign_save_rad_class_init( VipsForeignSaveRadClass *class ) foreign_class->suffs = vips__rad_suffs; save_class->saveable = VIPS_SAVEABLE_RGB; - save_class->format_table = bandfmt_rad; + save_class->format_table = vips_foreign_save_rad_format_table; save_class->coding[VIPS_CODING_NONE] = FALSE; save_class->coding[VIPS_CODING_RAD] = TRUE;