fixed extra band handling, again

This commit is contained in:
John Cupitt 2014-09-24 14:46:03 +01:00
parent 06366cf75b
commit 0a327af138
13 changed files with 39 additions and 170 deletions

26
TODO
View File

@ -1,29 +1,5 @@
- python:
- oh argh still getting this sometimes
$ python test_colour.py -v TestColour.test_colourspace
test_colourspace (__main__.TestColour) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.144s
OK
(test_colour.py:10826): GLib-GObject-WARNING **: instance of invalid
non-instantiatable type '(null)'
Trace/breakpoint trap (core dumped)
- colour difference does detach / reattach bands (badly), it should
use the thing in the base class instead
- dECMC result differs from Lindbloom's result:
http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html
requesting Ronnier's paper on his CMC colourspece, try that
- could import like this:
from gi.repository import Vips
@ -32,7 +8,7 @@
ie. make it a module, not a package, and make it clear that it
modifies Vips rather than adding anything itself
- should be a separate package?
- should be a separate package? pyvips?
easier to get into CPAN or whatever the python thing is called

View File

@ -153,7 +153,7 @@ vips_Lab2LabQ_init( VipsLab2LabQ *Lab2LabQ )
code->input_coding = VIPS_CODING_NONE;
code->input_format = VIPS_FORMAT_FLOAT;
code->input_bands = 3;
colour->input_bands = 3;
}
/**

View File

@ -94,7 +94,7 @@ vips_Lab2LabS_init( VipsLab2LabS *Lab2LabS )
code->input_coding = VIPS_CODING_NONE;
code->input_format = VIPS_FORMAT_FLOAT;
code->input_bands = 3;
colour->input_bands = 3;
}
/**

View File

@ -92,7 +92,7 @@ vips_LabS2Lab_init( VipsLabS2Lab *LabS2Lab )
code->input_coding = VIPS_CODING_NONE;
code->input_format = VIPS_FORMAT_SHORT;
code->input_bands = 3;
colour->input_bands = 3;
}
/**

View File

@ -141,7 +141,7 @@ vips_LabS2LabQ_init( VipsLabS2LabQ *LabS2LabQ )
code->input_coding = VIPS_CODING_NONE;
code->input_format = VIPS_FORMAT_SHORT;
code->input_bands = 3;
colour->input_bands = 3;
}
/**

View File

@ -325,7 +325,7 @@ vips_colour_build( VipsObject *object )
if( vips_image_pio_input( colour->in[i] ) )
return( -1 );
/* colour->in[] must be NULL-terminated, we use it as an arg to
/* colour->in[] must be NULL-terminated, we can use it as an arg to
* vips_start_many().
*/
g_assert( !colour->in[colour->n] );
@ -393,15 +393,30 @@ vips_colour_build( VipsObject *object )
*/
for( i = 0; i < colour->n; i++ )
if( extra_bands[i] ) {
VipsImage *x;
VipsImage *t1, *t2;
if( vips_bandjoin2( out, extra_bands[i], &x,
/* We can't just reattach the extra bands: they might
* be float (for example) and we might be trying to
* make a short image. Cast extra to match the body of
* the image.
*/
if( vips_cast( extra_bands[i], &t1, out->BandFmt,
NULL ) ) {
g_object_unref( out );
return( -1 );
}
if( vips_bandjoin2( out, t1, &t2,
NULL ) ) {
g_object_unref( t1 );
g_object_unref( out );
return( -1 );
}
g_object_unref( out );
out = x;
g_object_unref( t1 );
out = t2;
break;
}
@ -516,11 +531,8 @@ vips_colour_code_build( VipsObject *object )
VipsImage **t = (VipsImage **) vips_object_local_array( object, 6 );
VipsImage *in;
VipsImage *extra;
in = code->in;
extra = NULL;
/* If this is a LABQ and the coder wants uncoded, unpack.
*/
@ -537,30 +549,6 @@ vips_colour_code_build( VipsObject *object )
in, code->input_coding ) )
return( -1 );
/* Extra band processing. don't do automatic detach/reattach if either
* input or output will be coded.
*/
if( in &&
code->input_coding == VIPS_CODING_NONE &&
colour->coding == VIPS_CODING_NONE &&
code->input_bands > 0 ) {
if( in->Bands > code->input_bands ) {
if( vips_extract_band( in, &t[1], 0,
"n", code->input_bands, NULL ) )
return( -1 );
if( vips_extract_band( in, &t[2], code->input_bands,
"n", in->Bands - code->input_bands,
NULL ) )
return( -1 );
in = t[1];
extra = t[2];
}
else if( vips_check_bands_atleast(
VIPS_OBJECT_CLASS( class )->nickname,
in, code->input_bands ) )
return( -1 );
}
if( in &&
code->input_coding == VIPS_CODING_NONE &&
code->input_format != VIPS_FORMAT_NOTSET ) {
@ -579,33 +567,14 @@ vips_colour_code_build( VipsObject *object )
}
colour->n = 1;
colour->in = (VipsImage **) vips_object_local_array( object, 2 );
colour->in = VIPS_ARRAY( object, 2, VipsImage * );
colour->in[0] = in;
colour->in[1] = NULL;
if( colour->in[0] )
g_object_ref( colour->in[0] );
if( VIPS_OBJECT_CLASS( vips_colour_space_parent_class )->
if( VIPS_OBJECT_CLASS( vips_colour_code_parent_class )->
build( object ) )
return( -1 );
/* Reattach higher bands, if necessary.
*
* Our processing on the first three bands may have changed the image
* format. For example, converting LAB to LABS will make a short
* image. We need to force the extra bands to match this new type.
*/
if( extra ) {
VipsImage *x;
if( vips_cast( extra, &t[5], colour->out->BandFmt, NULL ) ||
vips_bandjoin2( colour->out, t[5], &x, NULL ) )
return( -1 );
VIPS_UNREF( colour->out );
colour->out = x;
}
return( 0 );
}
@ -643,19 +612,15 @@ vips_colour_difference_build( VipsObject *object )
{
VipsColour *colour = VIPS_COLOUR( object );
VipsColourDifference *difference = VIPS_COLOUR_DIFFERENCE( object );
VipsColourDifferenceClass *class =
VIPS_COLOUR_DIFFERENCE_GET_CLASS( object );
VipsImage **t;
VipsImage *left;
VipsImage *right;
VipsImage *extra;
t = (VipsImage **) vips_object_local_array( object, 12 );
left = difference->left;
right = difference->right;
extra = NULL;
if( left ) {
if( vips_image_decode( left, &t[0] ) )
@ -669,52 +634,9 @@ vips_colour_difference_build( VipsObject *object )
right = t[1];
}
/* Detach and reattach extra bands, if any. If both left and right
* have extra bands, give up.
/* Detach and reattach any extra bands.
*/
if( left &&
left->Bands > 3 &&
right &&
right->Bands > 3 ) {
vips_error( VIPS_OBJECT_CLASS( class )->nickname,
"%s", "both images have extra bands" );
return( -1 );
}
if( left &&
left->Bands > 3 ) {
if( vips_extract_band( left, &t[2], 0,
"n", 3,
NULL ) )
return( -1 );
if( vips_extract_band( left, &t[3], 3,
"n", left->Bands - 3,
NULL ) )
return( -1 );
left = t[2];
extra = t[3];
}
if( right &&
right->Bands > 3 ) {
if( vips_extract_band( right, &t[4], 0,
"n", 3,
NULL ) )
return( -1 );
if( vips_extract_band( right, &t[5], 3,
"n", right->Bands - 3,
NULL ) )
return( -1 );
right = t[4];
extra = t[5];
}
if( vips_check_bands_atleast( VIPS_OBJECT_CLASS( class )->nickname,
left, 3 ) )
return( -1 );
if( vips_check_bands_atleast( VIPS_OBJECT_CLASS( class )->nickname,
right, 3 ) )
return( -1 );
colour->input_bands = 3;
if( vips_colourspace( left, &t[6], difference->interpretation, NULL ) )
return( -1 );
@ -738,32 +660,15 @@ vips_colour_difference_build( VipsObject *object )
right = t[11];
colour->n = 2;
colour->in = (VipsImage **) vips_object_local_array( object, 3 );
colour->in = VIPS_ARRAY( object, 3, VipsImage * );
colour->in[0] = left;
colour->in[1] = right;
colour->in[2] = NULL;
if( colour->in[0] )
g_object_ref( colour->in[0] );
if( colour->in[1] )
g_object_ref( colour->in[1] );
if( VIPS_OBJECT_CLASS( vips_colour_space_parent_class )->
if( VIPS_OBJECT_CLASS( vips_colour_difference_parent_class )->
build( object ) )
return( -1 );
/* Reattach higher bands, if necessary.
*/
if( extra ) {
VipsImage *x;
if( vips_bandjoin2( colour->out, extra, &x, NULL ) )
return( -1 );
VIPS_UNREF( colour->out );
colour->out = x;
}
return( 0 );
}

View File

@ -216,7 +216,7 @@ vips_float2rad_init( VipsFloat2rad *float2rad )
code->input_coding = VIPS_CODING_NONE;
code->input_format = VIPS_FORMAT_FLOAT;
code->input_bands = 3;
colour->input_bands = 3;
}
/**

View File

@ -238,7 +238,7 @@ vips_icc_build( VipsObject *object )
code->in ) {
switch( cmsGetColorSpace( icc->in_profile ) ) {
case cmsSigRgbData:
code->input_bands = 3;
colour->input_bands = 3;
code->input_format =
code->in->BandFmt == VIPS_FORMAT_USHORT ?
VIPS_FORMAT_USHORT : VIPS_FORMAT_UCHAR;
@ -249,7 +249,7 @@ vips_icc_build( VipsObject *object )
#ifdef HAVE_LCMS2
case cmsSigGrayData:
code->input_bands = 1;
colour->input_bands = 1;
code->input_format =
code->in->BandFmt == VIPS_FORMAT_USHORT ?
VIPS_FORMAT_USHORT : VIPS_FORMAT_UCHAR;
@ -260,7 +260,7 @@ vips_icc_build( VipsObject *object )
#endif /*HAVE_LCMS2*/
case cmsSigCmykData:
code->input_bands = 4;
colour->input_bands = 4;
code->input_format =
code->in->BandFmt == VIPS_FORMAT_USHORT ?
VIPS_FORMAT_USHORT : VIPS_FORMAT_UCHAR;
@ -270,7 +270,7 @@ vips_icc_build( VipsObject *object )
break;
case cmsSigLabData:
code->input_bands = 3;
colour->input_bands = 3;
code->input_format = VIPS_FORMAT_FLOAT;
code->input_interpretation =
VIPS_INTERPRETATION_LAB;
@ -278,7 +278,7 @@ vips_icc_build( VipsObject *object )
break;
case cmsSigXYZData:
code->input_bands = 3;
colour->input_bands = 3;
code->input_format = VIPS_FORMAT_FLOAT;
icc->in_icc_format = TYPE_XYZ_16;
break;

View File

@ -154,7 +154,6 @@ typedef struct _VipsColourCode {
*/
VipsCoding input_coding;
VipsBandFormat input_format;
int input_bands;
VipsInterpretation input_interpretation;
} VipsColourCode;

View File

@ -166,7 +166,7 @@ vips_sRGB2scRGB_init( VipssRGB2scRGB *sRGB2scRGB )
colour->bands = 3;
code->input_coding = VIPS_CODING_NONE;
code->input_bands = 3;
colour->input_bands = 3;
/* The default. This can get changed above ^^ if we see a
* 16-bit input.

View File

@ -211,7 +211,7 @@ vips_scRGB2sRGB_init( VipsscRGB2sRGB *scRGB2sRGB )
colour->bands = 3;
code->input_coding = VIPS_CODING_NONE;
code->input_bands = 3;
colour->input_bands = 3;
code->input_format = VIPS_FORMAT_FLOAT;
scRGB2sRGB->depth = 8;

View File

@ -3,7 +3,7 @@
export G_DEBUG=fatal-warnings
while true; do
if ! python test_colour.py TestColour.test_bug; then
if ! python test_colour.py TestColour.test_colourspace; then
exit
fi
done

View File

@ -107,17 +107,6 @@ class TestColour(unittest.TestCase):
self.mono = self.colour.extract_band(1)
self.all_images = [self.mono, self.colour]
def test_bug(self):
# mid-grey in Lab ... put 42 in the extra band, it should be copied
# unmodified
test = Vips.Image.black(100, 100) + [50, 0, 0, 42]
test = test.copy(interpretation = Vips.Interpretation.LAB)
# a long series should come in a circle
im = test
for col in [Vips.Interpretation.RGB16]:
im = im.colourspace(col)
def test_colourspace(self):
# mid-grey in Lab ... put 42 in the extra band, it should be copied
# unmodified