-
-
Notifications
You must be signed in to change notification settings - Fork 665
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resize improvements; add ceil
and gap
options
#1769
Conversation
Just came across a handy utility to analyze image scaling algorithms, see: jsummers/resamplescope. I had a try to run this on libvips, and it seems to identify a possible precision and/or rounding error within the downscaler (
(These graphs were produced with the vector path disabled) |
It seems it wasn't entirely safe to remove the round-to-nearest behaviour in I now see:
The dashed line might be a precision error, but I'm not sure. Will continue to investigate this. |
I think perhaps the dashed line for libvips is it using fixed-point arithmetic plus a set of pre-computed masks. If you cast to float or double before reduce, it'll recompute the masks for each point and you should see smooth lines. |
Ah, I think you're right. I tried this within the Perhaps some kind of issue in the |
It looks like the Patchdiff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp
index 1111111..2222222 100644
--- a/libvips/resample/reduceh.cpp
+++ b/libvips/resample/reduceh.cpp
@@ -109,7 +109,7 @@ vips_reduce_get_points( VipsKernel kernel, double shrink )
return( 1 );
case VIPS_KERNEL_LINEAR:
- return( 2 * rint( shrink ) + 1 );
+ return( 2 );
case VIPS_KERNEL_CUBIC:
case VIPS_KERNEL_MITCHELL:
@@ -140,7 +140,8 @@ vips_reduce_make_mask( double *c, VipsKernel kernel, double shrink, double x )
break;
case VIPS_KERNEL_LINEAR:
- calculate_coefficients_triangle( c, shrink, x );
+ c[0] = 1.0 - x;
+ c[1] = x;
break;
case VIPS_KERNEL_CUBIC: |
I think I found it, see commit kleisauke@87043ef. I'm not quite sure why this is necessary, but it seems to fix the graphs now. 🎉
|
I noticed that a test case fails with Test image is from lovell/sharp#2408. Reproduction vipsthumbnail sharp-2408.jpg -s 1400x -o tn_%s.jpg --vips-novector (Notice that the above border is missing) Expected output vips cast sharp-2408.jpg x.v double
vipsthumbnail x.v -s 1400x -o tn_%s.jpg --vips-novector I'm not sure if there is a way to fix this without increasing the precision of the pre-computed masks. |
c02063a
to
b1349dc
Compare
I dropped commit kleisauke@18eebf7 and kleisauke@7681da1 since they appear to be incorrect (see for example the above test case). After further testing, the reported issues on sharp (lovell/sharp#2408 and lovell/sharp#2411) could be fixed with commit kleisauke@b1349dc. This does not cause regressions on the pyvips-issue-148 and vips-issue-703 repositories. |
any ETA on this? |
@markusmoormann I can't give any dates, unfortunately. I've just moved the fixes for the rounding issues to PR #1872.
I still haven't found a way to avoid passing these arguments. @jcupitt Do you have any ideas for this? |
@kleisauke @jcupitt any news on this? We are still struggling with this issue |
@kleisauke @jcupitt |
#1872 is merged now and in 8.10.3: https://github.com/libvips/libvips/releases/tag/v8.10.3 So if that's enough you may be OK. I should have a bit more free time now I'm done on something else, so I'll try to catch up on libvips. Sorry for being slow. |
@jcupitt thank you very much! works fine |
c458af4
to
f9201c5
Compare
Rebased. Commit f9201c5 adds a unit test (based on comment lovell/sharp#3066 (comment)) to test whether we use double-precision calculations in $ vips black x.jpg 1600 1000
$ vipsthumbnail x.jpg -s 10x -o vips.jpg
$ convert x.jpg -thumbnail 10x magick.jpg
$ vipsheader vips.jpg magick.jpg
vips.jpg: 10x6 uchar, 1 band, b-w, jpegload
magick.jpg: 10x6 uchar, 1 band, b-w, jpegload Previous behaviour: $ vipsheader vips.jpg
vips.jpg: 10x7 uchar, 1 band, b-w, jpegload Note that this PR is still a draft because of:
I don't know if there's any other way to resolve that. |
ceil
and gap
options
I finally found a way to get rid of those double-precision This is ready for review now. |
FWIW, the CIFuzz and latest OSS-Fuzz build seems to fail due to https://bugs.chromium.org/p/aomedia/issues/detail?id=3274. Edit: I triggered a re-run of the CIFuzz job, since commit https://aomedia.googlesource.com/aom/+/be05bfaceb4d3b7ed66a4d2e7a4927f484397efa ought to fix that. |
I've not forgotten this, I just have a lot of work right now :( I promise I'll read it this weekend! |
This looks great. I like your idea of moving the shrink into reduce. I saw a couple of tiny things, but that's all We need an update for the ChangeLog. Maybe:
Though that seems very vague! I'm sure you can think of something better. |
Your ChangeLog notes looks OK. Perhaps we should not use
Still a bit vague, but I can't think of anything better without going into too much detail. |
\o/ woo! I'll push the changelog notes. |
This PR adds a round-up option to shrink (see #2046 for context) and allows to configure the gap between
vips_shrink()
andvips_reduce()
. The kleisauke/pyvips-issue-148 repository contains some analysis with the test image from libvips/pyvips#148 before and after this PR.The calculation of the integer part within resize has also been slightly changed. When resizing a 2049×2047 image to 256×256 the int part is now (4, 3) times instead of (4, 4) times.