From 1a25c7a083eaf10bb8f7155d6c3d150b4b690be8 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 25 Mar 2016 10:42:21 +0000 Subject: [PATCH] better rounding in vipsthumbnail --- TODO | 7 ++++--- test/test_thumbnail.sh | 34 +++++++++++++++++++++------------- tools/vipsthumbnail.c | 9 ++++++--- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/TODO b/TODO index e9875188..5cfb21f4 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,8 @@ -- test_thumbnail.sh is failing ... 1000->999 makes a 998 image +- check C++ API for new operations -- move 16->8 conversion to a separate pass? with so many constants, can't we - get an error for some mask sizes? +- check dosc for new ops, esp function list + +- try make dist, check po - try SEQ_UNBUFFERED on jpg source, get out of order error? diff --git a/test/test_thumbnail.sh b/test/test_thumbnail.sh index 0b2af7d8..5044d0a0 100755 --- a/test/test_thumbnail.sh +++ b/test/test_thumbnail.sh @@ -8,11 +8,13 @@ . ./variables.sh -# make a 1000x1000 mono test image +# make a 1000x1000 mono test image ... add a bit so the image should not +# contain any zeros, helps to spot missing tiles and bad pixels echo building test image ... vips extract_band $image $tmp/t1.v 1 -vips replicate $tmp/t1.v $tmp/t2.v 2 2 -vips extract_area $tmp/t2.v $tmp/t1.v 10 10 1000 1000 +vips linear $tmp/t1.v $tmp/t2.v 1 20 --uchar +vips replicate $tmp/t2.v $tmp/t1.v 2 2 +vips crop $tmp/t1.v $tmp/t2.v 10 10 1000 1000 # is a difference beyond a threshold? return 0 (meaning all ok) or 1 (meaning # error, or outside threshold) @@ -25,29 +27,35 @@ break_threshold() { size=1000 while [ $size -gt 99 ]; do printf "testing size to $size ... " - vipsthumbnail $tmp/t1.v -o $tmp/t2.v --size $size - if [ $(vipsheader -f width $tmp/t2.v) -ne $size ]; then - echo $tmp/t2.v failed -- bad size - echo output width is $(vipsheader -f width $tmp/t2.v) + vipsthumbnail $tmp/t2.v -o $tmp/t1.v --size $size + if [ $(vipsheader -f width $tmp/t1.v) -ne $size ]; then + echo $tmp/t1.v failed -- bad size + echo output width is $(vipsheader -f width $tmp/t1.v) exit fi - if [ $(vipsheader -f height $tmp/t2.v) -ne $size ]; then - echo $tmp/t2.v failed -- bad size - echo output height is $(vipsheader -f width $tmp/t2.v) + if [ $(vipsheader -f height $tmp/t1.v) -ne $size ]; then + echo $tmp/t1.v failed -- bad size + echo output height is $(vipsheader -f width $tmp/t1.v) exit fi - vips project $tmp/t2.v $tmp/cols.v $tmp/rows.v + vips project $tmp/t1.v $tmp/cols.v $tmp/rows.v min=$(vips min $tmp/cols.v) if break_threshold $min 0; then - echo $tmp/t2.v failed -- has a black column + echo $tmp/t1.v failed -- has a black column exit fi min=$(vips min $tmp/rows.v) if break_threshold $min 0; then - echo $tmp/t2.v failed -- has a black row + echo $tmp/t1.v failed -- has a black row + exit + fi + + min=$(vips min $tmp/t1.v) + if break_threshold $min 0; then + echo $tmp/t1.v failed -- has black pixels exit fi diff --git a/tools/vipsthumbnail.c b/tools/vipsthumbnail.c index bd326e09..c4659ede 100644 --- a/tools/vipsthumbnail.c +++ b/tools/vipsthumbnail.c @@ -187,11 +187,14 @@ calculate_shrink( VipsImage *im ) /* Calculate the horizontal and vertical shrink we'd need to fit the * image to the bounding box, and pick the biggest. * - * In crop mode we aim to fill the bounding box, so we must use the + * In crop mode, we aim to fill the bounding box, so we must use the * smaller axis. + * + * Add a small amount so when vips_resize() later rounds down, we + * don't round below target. */ - double horizontal = (double) width / thumbnail_width; - double vertical = (double) height / thumbnail_height; + double horizontal = (double) width / (thumbnail_width + 0.1); + double vertical = (double) height / (thumbnail_height + 0.1); if( crop_image ) { if( horizontal < vertical )