From d62bec6ecc71ccf601de3b82cb35edb5729b9251 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 16 Dec 2014 14:14:32 +0000 Subject: [PATCH] bug in copy fallback for bandmean, rank and bool on one band images. --- libvips/conversion/bandbool.c | 5 ++-- libvips/conversion/bandmean.c | 5 ++-- libvips/conversion/bandrank.c | 6 ++++- test/test_conversion.py | 8 +++---- test/test_convolution.py | 44 ++++++++++++++++++++--------------- 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/libvips/conversion/bandbool.c b/libvips/conversion/bandbool.c index d5ebd9a9..faea1e32 100644 --- a/libvips/conversion/bandbool.c +++ b/libvips/conversion/bandbool.c @@ -82,13 +82,14 @@ vips_bandbool_build( VipsObject *object ) if( vips_check_noncomplex( class->nickname, bandbool->in ) ) return( -1 ); + bandary->n = 1; + bandary->in = &bandbool->in; + if( bandbool->in->Bands == 1 ) return( vips_bandary_copy( bandary ) ); } bandary->out_bands = 1; - bandary->n = 1; - bandary->in = &bandbool->in; if( VIPS_OBJECT_CLASS( vips_bandbool_parent_class )-> build( object ) ) diff --git a/libvips/conversion/bandmean.c b/libvips/conversion/bandmean.c index 418c5640..e0c48b03 100644 --- a/libvips/conversion/bandmean.c +++ b/libvips/conversion/bandmean.c @@ -163,13 +163,14 @@ vips_bandmean_build( VipsObject *object ) VipsBandary *bandary = (VipsBandary *) object; VipsBandmean *bandmean = (VipsBandmean *) object; + bandary->n = 1; + bandary->in = &bandmean->in; + if( bandmean->in && bandmean->in->Bands == 1 ) return( vips_bandary_copy( bandary ) ); bandary->out_bands = 1; - bandary->n = 1; - bandary->in = &bandmean->in; if( VIPS_OBJECT_CLASS( vips_bandmean_parent_class )->build( object ) ) return( -1 ); diff --git a/libvips/conversion/bandrank.c b/libvips/conversion/bandrank.c index 940bd3f5..115150f5 100644 --- a/libvips/conversion/bandrank.c +++ b/libvips/conversion/bandrank.c @@ -189,8 +189,12 @@ vips_bandrank_build( VipsObject *object ) if( vips_check_noncomplex( class->nickname, in[i] ) ) return( -1 ); - if( n == 1 ) + if( n == 1 ) { + bandary->in = in; + bandary->n = 1; + return( vips_bandary_copy( bandary ) ); + } /* We need to keep one band element for every input image * on the stack. diff --git a/test/test_conversion.py b/test/test_conversion.py index cdded776..f2c3dd36 100755 --- a/test/test_conversion.py +++ b/test/test_conversion.py @@ -147,7 +147,7 @@ class TestConversion(unittest.TestCase): else: return [reduce(lambda a, b: int(a) & int(b), x)] - self.run_unary([self.colour], band_and, fmt = int_formats) + self.run_unary(self.all_images, band_and, fmt = int_formats) def test_band_or(self): def band_or(x): @@ -156,7 +156,7 @@ class TestConversion(unittest.TestCase): else: return [reduce(lambda a, b: int(a) | int(b), x)] - self.run_unary([self.colour], band_or, fmt = int_formats) + self.run_unary(self.all_images, band_or, fmt = int_formats) def test_band_eor(self): def band_eor(x): @@ -165,7 +165,7 @@ class TestConversion(unittest.TestCase): else: return [reduce(lambda a, b: int(a) ^ int(b), x)] - self.run_unary([self.colour], band_eor, fmt = int_formats) + self.run_unary(self.all_images, band_eor, fmt = int_formats) def test_bandjoin(self): def bandjoin(x, y): @@ -183,7 +183,7 @@ class TestConversion(unittest.TestCase): else: return [sum(x) // len(x)] - self.run_unary([self.colour], bandmean, fmt = noncomplex_formats) + self.run_unary(self.all_images, bandmean, fmt = noncomplex_formats) def test_bandrank(self): def median(x, y): diff --git a/test/test_convolution.py b/test/test_convolution.py index 5520abf4..9d2b031b 100755 --- a/test/test_convolution.py +++ b/test/test_convolution.py @@ -4,6 +4,7 @@ from __future__ import division from builtins import zip from builtins import range from numbers import Number +from functools import reduce import unittest import operator @@ -60,7 +61,7 @@ def conv(image, mask, x_position, y_position): p = run_fn2(operator.mul, m, i) s = run_fn2(operator.add, s, p) - return run_fn2(operator.div, s, mask.get_scale()) + return run_fn2(operator.truediv, s, mask.get_scale()) def compass(image, mask, x_position, y_position, n_rot, fn): acc = [] @@ -112,29 +113,34 @@ class TestConvolution(unittest.TestCase): true = conv(im, msk, 49, 49) self.assertAlmostEqualObjects(result, true) - def test_x(self): - im = self.mono - msk = self.sobel - - result = conv(im, msk, 24, 49) - msk = msk.rot45() - - result = conv(im, msk, 24, 49) - msk = msk.rot45() - def test_compass(self): for im in self.all_images: for msk in self.all_masks: for prec in [Vips.Precision.INTEGER, Vips.Precision.FLOAT]: - convolved = im.compass(msk, - times = 3, - angle = Vips.Angle45.D45, - combine = Vips.Combine.MAX, - precision = prec) + for times in range(1, 4): + convolved = im.compass(msk, + times = times, + angle = Vips.Angle45.D45, + combine = Vips.Combine.MAX, + precision = prec) - result = convolved.getpoint(25, 50) - true = compass(im, msk, 24, 49, 3, max) - self.assertAlmostEqualObjects(result, true) + result = convolved.getpoint(25, 50) + true = compass(im, msk, 24, 49, times, max) + self.assertAlmostEqualObjects(result, true) + + for im in self.all_images: + for msk in self.all_masks: + for prec in [Vips.Precision.INTEGER, Vips.Precision.FLOAT]: + for times in range(1, 4): + convolved = im.compass(msk, + times = times, + angle = Vips.Angle45.D45, + combine = Vips.Combine.SUM, + precision = prec) + + result = convolved.getpoint(25, 50) + true = compass(im, msk, 24, 49, times, operator.add) + self.assertAlmostEqualObjects(result, true) if __name__ == '__main__': unittest.main()