GNOME Bugzilla – Bug 688930
negative positions and scaling factors throw the bilinear sampler (others too?) off
Last modified: 2012-11-24 04:18:02 UTC
The test on which this bug is based was provided by Massimo Valentini in connection to https://bugzilla.gnome.org/show_bug.cgi?id=433436. I am starting a new bug about it because it is a separate issue. Bad news nonetheless. You'd think that resizing through negative locations using a negative magnification factor would be harmless. But it's not. Run this: <gegl> <gegl:crop x='-512' y='-512' width='1024' height='1024'/> <gegl:scale filter='linear' x='-4' y='-4'/> <gegl:crop x='-260' y='-260' width='520' height='520'/> <gegl:color value='#777' /> </gegl> and you do NOT get a constant image as expected: there are horizontal and vertical lines, that do not all cross the entire width and height, which should not be there. ----- Now: I think that I may have a fix short of retracing the buffer machinery making sure that everything "aligns". (I'll try it later today.) I suspect that there is an implicit assumption that the anchor pixel of a context_rect is as centered as it can be, in which case a sampling location is never more than .5 in the max distance from the location of the corresponding anchor pixel. This assumption is currently broken in the case of the bilinear and cubic samplers, which always anchor things at the closest pixel TO THE TOP AND LEFT. Consequently, the anchor pixel may be as far as 1 away in the max distance. A solution to this is to always use the closest pixel (like in neareast and lohalo), which requires either enlarging the context_rect slightly when the "natural" stencil size has even width and/or height---this sounds an awful lot like Massimo's suggested fix, which I dismissed as nonsense---or reflecting the data within the tight context_rect to account for things normally assumed to be left (resp. up) not being there anymore, using tricks used in Lohalo to keep the context_rect small. Incidentally, when I change the transform-core.c code to fix/break it, the last method to break---besides nearest---is Lohalo, which is the only sampler which has a nontrivial context_rect of odd width. Not a coincidence, I believe.
Actually, Massimo is almost certainly right: The simplest non-hackish way to fix this is to make sure that the context_rect of a sampler is symmetric about it's anchor point, because this way the correct "needs" information will be propagated even if the context_rect is flipped by by the transformation. Will try this now.
The reason that it fails when the scale factor is negative, is that GEGL splits the work in chunks, and proceeds top to bottom, and left to right. Since the context_rect is defective on top/left, by proceeding left to right in destination space, a negative scale factor forces to render the source bottom to top and right to left, so what is not requested is not even found in the cache of regions already rendered. If it wasn't for the cache you'd see that the required source to output whatever rectangle, is defective also with positive scale factors.
I'm pretty I fixed that bug. Not pushed yet. Trying to fix other bugs at the same time.
Just pushed it. It breaks the regression tests. But fixes this bug.
Massimo: I agree that the best thing would be to rewrite so that both the input and output buffers are scanned from left to right and top to bottom, which requires extracting the geometry from the transformation, something which is definitely feasible. Doing this may help with other things, since we then can use floor and ceil knowing exactly what happens geometrically. However, enlarging the context_rects, as you initially suggested I believe, fixes things well enough. Or so it seems.