diff --git a/libvips/arithmetic/hough_circle.c b/libvips/arithmetic/hough_circle.c index 86c76a50..66b5d5cc 100644 --- a/libvips/arithmetic/hough_circle.c +++ b/libvips/arithmetic/hough_circle.c @@ -150,11 +150,12 @@ vips_hough_circle_vote_endpoints_clip( VipsImage *image, int y, int x1, int x2, int quadrant, void *client ) { int r = *((int *) client); - guint *line = (guint *) VIPS_IMAGE_ADDR( image, 0, y ) + r; int b = image->Bands; if( y >= 0 && y < image->Ysize ) { + guint *line = (guint *) VIPS_IMAGE_ADDR( image, 0, y ) + r; + if( x1 >=0 && x1 < image->Xsize ) line[x1 * b] += 1; diff --git a/libvips/create/mask_butterworth.c b/libvips/create/mask_butterworth.c index 4e9d9cac..c5f4a4a6 100644 --- a/libvips/create/mask_butterworth.c +++ b/libvips/create/mask_butterworth.c @@ -64,9 +64,12 @@ vips_mask_butterworth_point( VipsMask *mask, double dx, double dy ) double cnst = (1.0 / ac) - 1.0; double fc2 = fc * fc; - double dist2 = fc2 / (dx * dx + dy * dy); + double d = dx * dx + dy * dy; - return( 1.0 / (1.0 + cnst * pow( dist2, order )) ); + if( d == 0 ) + return( 0 ); + else + return( 1.0 / (1.0 + cnst * pow( fc2 / d, order )) ); } static void diff --git a/libvips/draw/draw_flood.c b/libvips/draw/draw_flood.c index 2d2367a1..fd159166 100644 --- a/libvips/draw/draw_flood.c +++ b/libvips/draw/draw_flood.c @@ -297,7 +297,6 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 ) { const int width = flood->test->Xsize; - VipsPel *p; int i; g_assert( flood_connected( flood, @@ -309,23 +308,33 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 ) * pixel is unpainted, we know all the intervening pixels must be * unpainted too. */ - p = VIPS_IMAGE_ADDR( flood->test, x + 1, y ); - for( i = x + 1; i < width; i++ ) { - if( !flood_connected( flood, p ) ) - break; - p += flood->tsize; + if( x < width ) { + VipsPel *p = VIPS_IMAGE_ADDR( flood->test, x + 1, y ); + + for( i = x + 1; i < width; i++ ) { + if( !flood_connected( flood, p ) ) + break; + p += flood->tsize; + } + *x2 = i - 1; } - *x2 = i - 1; + else + *x2 = width; /* Search left. */ - p = VIPS_IMAGE_ADDR( flood->test, x - 1, y ); - for( i = x - 1; i >= 0; i-- ) { - if( !flood_connected( flood, p ) ) - break; - p -= flood->tsize; + if( x > 0 ) { + VipsPel *p = VIPS_IMAGE_ADDR( flood->test, x - 1, y ); + + for( i = x - 1; i >= 0; i-- ) { + if( !flood_connected( flood, p ) ) + break; + p -= flood->tsize; + } + *x1 = i + 1; } - *x1 = i + 1; + else + *x1 = 0; /* Paint the range we discovered. */ diff --git a/libvips/iofuncs/streami.c b/libvips/iofuncs/streami.c index 899fe7ee..e39aa0a9 100644 --- a/libvips/iofuncs/streami.c +++ b/libvips/iofuncs/streami.c @@ -654,7 +654,8 @@ vips_streami_read( VipsStreami *streami, void *buffer, size_t length ) SANITY( streami ); - if( vips_streami_unminimise( streami ) ) + if( vips_streami_unminimise( streami ) || + vips_streami_test_features( streami ) ) return( -1 ); bytes_read = 0; @@ -849,8 +850,9 @@ vips_streami_descriptor_to_memory( VipsStreami *streami ) gboolean vips_streami_is_mappable( VipsStreami *streami ) { - if( vips_streami_unminimise( streami ) ) - return( FALSE ); + if( vips_streami_unminimise( streami ) || + vips_streami_test_features( streami ) ) + return( -1 ); /* Already a memory object, or there's a filename we can map, or * there's a seekable descriptor. @@ -881,7 +883,8 @@ vips_streami_map( VipsStreami *streami, size_t *length_out ) SANITY( streami ); - if( vips_streami_unminimise( streami ) ) + if( vips_streami_unminimise( streami ) || + vips_streami_test_features( streami ) ) return( NULL ); if( !streami->data ) { @@ -932,7 +935,8 @@ vips_streami_seek( VipsStreami *streami, gint64 offset, int whence ) SANITY( streami ); - if( vips_streami_unminimise( streami ) ) + if( vips_streami_unminimise( streami ) || + vips_streami_test_features( streami ) ) return( -1 ); if( streami->data ) { diff --git a/test/test-suite/test_create.py b/test/test-suite/test_create.py index aecac264..eaa3e4c6 100644 --- a/test/test-suite/test_create.py +++ b/test/test-suite/test_create.py @@ -121,8 +121,8 @@ class TestCreate: sigma = im.deviate() mean = im.avg() - assert pytest.approx(sigma, 0.2) == 10 - assert pytest.approx(mean, 0.2) == 100 + assert sigma == pytest.approx(10, abs=0.2) + assert mean == pytest.approx(100, abs=0.2) def test_grey(self): im = pyvips.Image.grey(100, 90) @@ -197,11 +197,11 @@ class TestCreate: p = im(255, 0) assert_almost_equal_objects(p, [1, 1, 1]) p = im(0.2 * 255, 0) - assert pytest.approx(p[0], 0.1) == 0.1 + assert p[0] == pytest.approx(0.1, abs=0.1) p = im(0.3 * 255, 0) - assert pytest.approx(p[1], 0.1) == 0.1 + assert p[1] == pytest.approx(0.1, abs=0.1) p = im(0.1 * 255, 0) - assert pytest.approx(p[2], 0.1) == 0.1 + assert p[2] == pytest.approx(0.1, abs=0.1) def test_logmat(self): im = pyvips.Image.logmat(1, 0.1) @@ -237,7 +237,7 @@ class TestCreate: assert im.height == 128 assert im.bands == 1 assert im.format == pyvips.BandFormat.FLOAT - assert pytest.approx(im.max(), 0.01) == 1 + assert im.max() == pytest.approx(1, abs=0.01) p = im(32, 32) assert p[0] == 1.0 @@ -275,7 +275,7 @@ class TestCreate: assert im.height == 128 assert im.bands == 1 assert im.format == pyvips.BandFormat.FLOAT - assert pytest.approx(im.min(), 0.01) == 0 + assert im.min() == pytest.approx(0, abs=0.01) p = im(0, 0) assert p[0] == 0.0 v, x, y = im.maxpos() @@ -288,7 +288,7 @@ class TestCreate: assert im.height == 128 assert im.bands == 1 assert im.format == pyvips.BandFormat.UCHAR - assert pytest.approx(im.min(), 0.01) == 0 + assert im.min() == pytest.approx(0, abs=0.01) p = im(64, 64) assert p[0] == 255 @@ -300,7 +300,7 @@ class TestCreate: assert im.bands == 1 assert im.format == pyvips.BandFormat.FLOAT p = im(45, 0) - assert pytest.approx(p[0], 0.0001) == 1.0 + assert p[0] == pytest.approx(1.0, abs=0.0001) v, x, y = im.minpos() assert x == 64 assert y == 64 @@ -318,7 +318,7 @@ class TestCreate: assert im.height == 128 assert im.bands == 1 assert im.format == pyvips.BandFormat.FLOAT - assert pytest.approx(im.max(), 0.01) == 1 + assert im.max() == pytest.approx(1, abs=0.01) p = im(32, 32) assert p[0] == 1.0 @@ -329,7 +329,7 @@ class TestCreate: assert im.height == 128 assert im.bands == 1 assert im.format == pyvips.BandFormat.FLOAT - assert pytest.approx(im.min(), 0.01) == 0 + assert im.min() == pytest.approx(0, abs=0.01) p = im(0, 0) assert p[0] == 0.0 @@ -341,7 +341,7 @@ class TestCreate: assert im.bands == 1 assert im.format == pyvips.BandFormat.FLOAT p = im(45, 0) - assert pytest.approx(p[0], 0.001) == 1.0 + assert p[0] == pytest.approx(1.0, abs=0.001) def test_mask_ideal_band(self): im = pyvips.Image.mask_ideal_band(128, 128, 0.5, 0.5, 0.7) @@ -349,7 +349,7 @@ class TestCreate: assert im.height == 128 assert im.bands == 1 assert im.format == pyvips.BandFormat.FLOAT - assert pytest.approx(im.max(), 0.01) == 1 + assert im.max() == pytest.approx(1, abs=0.01) p = im(32, 32) assert p[0] == 1.0 @@ -360,7 +360,7 @@ class TestCreate: assert im.height == 128 assert im.bands == 1 assert im.format == pyvips.BandFormat.FLOAT - assert pytest.approx(im.min(), 0.01) == 0 + assert im.min() == pytest.approx(0, abs=0.01) p = im(0, 0) assert p[0] == 0.0 @@ -372,7 +372,7 @@ class TestCreate: assert im.bands == 1 assert im.format == pyvips.BandFormat.FLOAT p = im(45, 0) - assert pytest.approx(p[0], 0.001) == 1.0 + assert p[0] == pytest.approx(1, abs=0.001) def test_sines(self): im = pyvips.Image.sines(128, 128)