GNOME Bugzilla – Bug 104693
Scaling down a small image loses some pixel data.
Last modified: 2009-08-15 18:40:50 UTC
I saw this with 1.2.3 as well. In any case, when scaling down an already-small image -- for example, and icon (whether xpm, png, or whatever) that is 32x32pixels and making it 24x24pixels -- some image data is lost. The lost data appears as a streak of nothingness down the center of the scaled-down image. In the case of scaling from 32x32 to 24x24, the 24x24 value is critical; image data doesn't go on vacation if using some other oddball dimesions (like 22x22 for example). So I thought "rounding error" or the like, but 24x24 are happy dimensions, being 75% of the originals. Furthermore, apparently I can only reproduce this repeatedly if The Gimp is built from source (either 1.2.3 or 1.2.4-pre2); the RH-distributed 1.2.3 rpm seems to work fine as I can't induce this pixel loss at all. The XPM used for this exercise is a 32x32 blob representing xscreensaver that has a transparent background. Both this original XPM and a visual of the madness I speak forth here are available at this URL: http://www.valaran.com/~kw/fire.html
This is strange... I tried to reproduce it but I did not see any problems (gimp 1.2.4-pre2, platform: sparc-sun-solaris2.8). However, I remember seeing a similar problem on a Linux PC some time ago. This may be due to some problems in your compiler or libraries. It would be nice if you could mention the version of the compiler that you are using ("gcc --version"), the libraries used during compilation and linking ("ldd `which gimp`") and any other information that could help those who could try to reproduce this bug. Can anybody else confirm this bug report?
I've tested this on an i686 using gimp-1.2 (1.2.4pre2) and gimp-1.3 (current CVS) with all three interpolation routines and I can not reproduce the problem.
OK. I can reproduce this on an LFS (LinuxFromScratch) box as well, but let's stick with RH 7.3 as the reference point. Compiler and libs? Ok, here goes: $ ldd gimp libgtk-1.2.so.0 => /usr/lib/libgtk-1.2.so.0 (0x40021000) libgdk-1.2.so.0 => /usr/lib/libgdk-1.2.so.0 (0x40150000) libgmodule-1.2.so.0 => /usr/lib/libgmodule-1.2.so.0 (0x40185000) libglib-1.2.so.0 => /usr/lib/libglib-1.2.so.0 (0x40188000) libdl.so.2 => /lib/libdl.so.2 (0x401ac000) libXi.so.6 => /usr/X11R6/lib/libXi.so.6 (0x401af000) libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0x401b7000) libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x401c5000) libm.so.6 => /lib/i686/libm.so.6 (0x4029a000) libc.so.6 => /lib/i686/libc.so.6 (0x42000000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) $ gcc -v Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110) Flags and environment variables passed to configure (as specified in my spec): %build export CFLAGS=-march=i686 export LDFLAGS=-s ./configure \ --prefix=/usr \ --sysconfdir=/etc \ --localstatedir=/var \ --disable-nls \ --disable-perl \ --enable-shared \ --enable-static \ --host=i686-pc-linux-gnu \ --build=i686-pc-linux-gnu I've also posted the config.log and config.h at the previously-mentioned URL.
One more note: I understand that gcc 2.96 was never an "official" release and I am aware that it is known to have a few exotic issues. However this bug is reproducable on an LFS box with gcc 2.95.3. Back to the RH box, a few relevant RPM package versions: $ rpm -qa | grep -E '^XFree86-(devel-)?[0-9]+\.' XFree86-devel-4.2.0-8 XFree86-4.2.0-8 $ rpm -q gcc binutils glibc glibc-devel gtk+ gtk+-devel glib glib-devel gcc-2.96-110 binutils-2.11.93.0.2-11 glibc-2.2.5-34 glibc-devel-2.2.5-34 gtk+-1.2.10-15 gtk+-devel-1.2.10-15 glib-1.2.10-5 glib-devel-1.2.10-5
Well, sticking with a known-to-be-buggy compiler (such as 2.96) is not a good excuse. I'm surprised that 2.95.3 gives the same problem since I'm using gcc-2.95.4 and I can not reproduce it.
Yes I entirely that sticking with 2.96 is "no excuse". There *are* updated gcc RPMs for RH 7.3 but at this time I cannot install them as it would cause an undersirable disruption (that particular box is used for all sorts of things). However I do have a rather ancient RH 6.2 box I can attempt a build on. Or perhaps try the gimp 1.3 series. I'll do one or the other or both later today.
You didn't tell us which interpolation routine is selected in the preferences. It would be interesting to know if the problem can be reproduced with all interpolation algorithms or not.
Ah yes, my apologies. Well I had removed entirely my ~/.gimp-1.2/ and started fresh. So the interpolation routine was the default -- linear. It also bombs on cubic, but it does NOT bomb on nearest neighbor. Also if I use the transform tool (rather than "right-click on image -> Image -> Scale Image..." dialog) none of this happens regardless of the interpolation routine. sigh... Furhtermore, this is all independent of image format.
I am having the same problem, although with large photos. When I scale a 2272x1704 image down to 1280x960, I am seeing the same "streak of nothingness" down the center of the image as the original poster. Scaling down to other resolutions works fine though. Here are the details: - Debian 3.0r1 stable - installed from binary, gimp1.2_1.2.3-2_i386.deb ~$ ldd `which gimp` libgtk-1.2.so.0 => /usr/lib/libgtk-1.2.so.0 (0x40018000) libgdk-1.2.so.0 => /usr/lib/libgdk-1.2.so.0 (0x4013d000) libgmodule-1.2.so.0 => /usr/lib/libgmodule-1.2.so.0 (0x40172000) libglib-1.2.so.0 => /usr/lib/libglib-1.2.so.0 (0x40175000) libdl.so.2 => /lib/libdl.so.2 (0x40198000) libXi.so.6 => /usr/X11R6/lib/libXi.so.6 (0x4019b000) libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0x401a3000) libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x401b0000) libm.so.6 => /lib/libm.so.6 (0x4028a000) libc.so.6 => /lib/libc.so.6 (0x402ab000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) I'll try compiling the latest stable version of The Gimp and see if the problem persists.
Although I don't think that it could be a display problem, I would like to be sure... So, can you confirm that the vertical line is saved in the file? Do you still see it if you save the (incorrect) image to a file (.xcf, .png or other format) and re-load it later? Also, it looks like the error shown in the screenshot is affecting the alpha channel (transparency) while the colors are correct. So I would like to know if you have ever seen this with non-transparent images. What do you get if you use "Flatten Image" just before scaling? Do you see a line containing the background color, is is everything correct?
Go here and grab the flattened XPM: http://www.valaran.com/~kw/fire.html Does not appear to be the fault of the alpha channel.
FWIW, I compiled 1.2.3 on Debian 3.0r1 stable (instead of using the supplied deb) and the "streak of nothingness" problem is gone. Rob
Could you (Keith or Rob or anyone else who can reproduce this) try the following: - load the xscreensaver XPM, - flatten it, - set your background color to magenta and foreground to green, or any other combination that is very visible and does not occur in the image, - scale the image to 24x24, - save as .xcf or .xcf.gz, - attach the file to this bug report ("Create a new attachment").
Greets. Sorry, I've been away on vacation. I'm not sure what you mean about changing the {fore,back}ground colors. Do want me to actually do a fill with those colors?
I mean changing the {fore,back}ground color in the toolbox. You do not need to fill with these colors or to use them in any way. I would like to know if the black line that you see in the image is partially transparent, pure black, or if it contains some parts of the background color. That's why I would like you to set your {fore,back}ground colors to something that can easily be identified. Also, saving the result in XCF format ensures that some other (non visible) information is included in the file. This will be more useful than saving the result in XPM format, which discards a lot of info about the image. Please attach the result to this bug report.
Created attachment 14277 [details] flattened xscreensaver 24x24 XCF (foreground:#ff00ff, background:#00ff00)
Ok I've added the flattened image with a foreground of #ff00ff and background #00ff00. Hopefully I did that right. :)
I still do not understand what goes wrong with your copy of the GIMP, but at least I was able to generate the same bad image using a "good" copy of the GIMP. I noticed that the line in the middle of your image is not pure black: instead, it is very dark red, like if a black line had been drawn in the image before rescaling and then averaged with the red parts of the flame by the linear scaling algorithm. Also, I saw that the part of the image to the right of that black line has been shifted slightly to the right. So everything looks like if a part of the image had been shifted by 1 pixel to the right just before rescaling. The empty space in this 1 pixel column is probably unitialized memory (or set to 0), so this gives a transparent line if the image has an alpha channel (opacity = 0) and a black line (RGB = 0, 0, 0) if the image does not have an alpha channel. Here is how I managed to recreate your image using a working GIMP: - make a 20x32 selection from (12, 0) to the bottom right corner of the image; - move this selection 1 pixel to the right, anchor it there, deselect; - if you want to test with a flattened image, flatten now and then take a 1 pixel brush to draw a black line from (12, 0) to (12, 32); - set the interpolation type to linear (in 1.2.x, this is under Preferences->Environment; in 1.3.x, this is in the Scale dialog); - rescale to 24x24 So although I still have no idea why your image is not scaled correctly, I managed to recreate a perfect copy of what you get as a result. I do not understand why the 13th column of your image is shifted to the right before scaling. I hope that someone else can investigate this problem and come up with a bright idea that can explain what is happening here...
I have been able to reproduce this repeatedly with any 32x32 image (new or old) that is resized to 24x24. Maybe it is a glibc issue or some other lib issue? I can reproduce this on two different boxes (one RH7.3, the other LFS) both with glibc 2.2.5 and XFree86 4.2.0. I'm curious as to what environment RH used when they built the gimp 1.2.3 that is shipped with RH 7.3 because that gimp works; only a gimp that I build from source misbehaves. ?:-/ Go here and check out "Yet another interesting image" (item number 4): http://www.valaran.com/~kw/fire.html
Aha. This bug can probably be closed now, but I will not do it because I do not know yet *exactly* what the cause is, but right now I believe it is either the GIMP's or the compiler's fault. A little bit more history (NOTE: are GIMP references are to v1.2.4_pre2 although it is probably interchangable with 1.2.3 and even 1.3.13): - Since attempting to conquer this bug, I have upgraded my XFree86 from 4.2.0 to 4.3.0 (by compiling source with an LFS patched gcc 2.95.3). The GIMP bug was still present. - I upgraded gcc to 3.2.2 and binutils to 2.13.2.1 (again, compiling from sources). Rebuilt the GIMP and still no change. NOTE: this compiler suite will be used from here on in. - I rebuilt my glibc 2.2.5 after having patched it w/ a patch from LFS (for various security bugs, etc). Rebuilt the GIMP. No change. Bug still present. - I rebuilt glib1 and gtk+1, with the new compiler and newly compiled glibc. Then rebuilt the GIMP. No change. - On the verge of giving the f' up, I then decided to change my usual ./configure invocation from: export CFLAGS=-march=i686 ./configure \ --prefix=/usr \ --sysconfdir=/etc \ --localstatedir=/var \ --disable-print \ --disable-perl \ --disable-nls \ --enable-shared \ --enable-static \ --enable-debug \ --host=i686-pc-linux-gnu \ --build=i686-pc-linux-gnu to: ./configure \ --prefix=/usr \ --sysconfdir=/etc \ --localstatedir=/var \ --disable-print \ --disable-perl \ --disable-nls \ --enable-shared \ --enable-debug To my absolute surprise, this eliminated the bug. The only real difference being the absence of $CFLAGS and no --host/--build specification. This is where I am moderately confused: both the CFLAGS and host/build specification were actually redundant, AFAICS, because my compiler produces i686 code anyway, and configure will guess i686-pc-linux-gnu anyway. Does anyone have an explanation? For the record, the bug was also visible in 1.3.13 when compiling with a specified CFLAGS and --host/--build.
Interesting. When you build the GIMP using your latest configuration and you look at the gcc options passed on the command line, do you see any parameters such as "-march=..." or "-mcpu=..."? If the differences in the configure options are the only things that influence this bug, it would be very interesting to see how these translate in different command-line options for gcc.
No such arguments at all. All I see is: -g -g -O2 -Wall (--enable-debug, hence -g, but why two of them I don't know :) I am in the process of rebuilding again, this time with CFLAGS=-march=i686 prior to running configure, but without setting --host/--build. Now the compile commands have the flags -g -march=i686 -Wall No -O at all. And only one -g. ?! Anyway, if this gimp has the bug, I will recompile *yet again* but specifying CFLAGS='-march=i686 -O2'. If it works, then we know there is something awry with the optimazations (or lack thereof) and I would really really like to see if someone else out there can procuce the same bug.
Yup. Sure enough, it has the bug. So I conclude it has nothing to do with specifying --host/--build, and everything to do with a $CFLAGS that does not have optimizations specified. I am going to confirm now by specifying CFLAGS='-march=i686 -O2' during yet another build.
Yes, it is confirmed. The optimization flag (-O2) is required. Without it, this bug is present. Now, I will feel really stupid if this is mentioned in a FAQ or README somewhere and I just never saw it. If it is not mentioned, perhaps it should be?? If anyone out there has as much free time as I do (I really don't; I jut multitask well), please please please try to reproduce this by compiled the GIMP without any -O gcc flags whatsoever. Thanks.
Funny indeed. I can confirm the problem with the current unstable CVS tree. Compiled with CFLAGS="-g -march=i686", scaling from 32x32 to 24x24 produces the described artefacts.
Aha! So I am not insane (well, still debateable...)! Praise the GIMP! It amazes me that a *lack* of -O gcc flags causes this problem; usually the *addition* of -O breaks things (if it breaks anything at all), not the removal of -O. Hmm. I do not have enough free time to compare assembler output. ;-) But it looks like our troubled function is scale_region() or get_scaled_row() in paint_funcs.c ?
dsrogers Sven: that bug about scaling artifacts when optimization is turned off could be caused by a statement that rounds several times, that is reduced by the optimizer to round less. . . dsrogers you could check my modifing shrink_line to use just doubles, until you are done with the incremental changes. Submarine dsrogers: Do you use floating-point? dsrogers hmm. what looks suspecious (without looking at asm) is line 2897 and line 2908 with their (int) typecasts. dsrogers and they are very similar. likely reduced to a common subexpression during an optimizaiton. dsrogers resulting in one or two less roundings per iteration. dsrogers Submarine: I am not srue what you mean. Submarine Are the expressions you are alluding to integer or floating-point? dsrogers they are floating point, but with integer casts. dsrogers max = ((int)(position+step)) - ((int)(position)); dsrogers and dsrogers mant = ((position+step) - (int)(position + step)); dsrogers I don't think I can, but I will try. Submarine I don't see any common subexpression here!? Submarine Just to tell you something that may have nothing to do with the problem: dsrogers they are not completly similar, but they are close. Submarine on x86/Linux, x87 floating point code may perform differently depending on optimization Submarine the x87 computes on 64 bit mantissas internally Submarine but double's have shorter mantissas Submarine so the result of a computation depends on how the compiler schedules registers dsrogers which means they might be rearranged by the optimizer to have a common sub expression. Submarine on FreeBSD, it seems that by default they set the x87 to normal double precision to avoid such effects Submarine thought a C99/IEEE compliant optimizer was really constrained as to what it could do with floating-point dsrogers if you know anything on the subject, you are probably right. dsrogers I am guessing here. dsrogers Submarine: do you thinke the result could be different enough to change an (eventually) integer result? Submarine well, you can always find borderline cases! dsrogers indeed.
Fixed in HEAD branch. I'm leaving the bug open because the affected version in the report is 1.2.4-pre2. Should the fix be backported? 2003-04-27 Pedro Gimeno <pggimeno@wanadoo.es> * app/paint-funcs/paint-funcs.c (shrink_line): Mostly rewritten to improve accuracy. Fixes bug #104693.
If the fix is straight-forward and localized, it should be backported. If there's a chance that it introduces other problems, leave 1.2 untouched.
*** Bug 97187 has been marked as a duplicate of this bug. ***
I'm quite confident that the new code will behave correctly as long as the assertions are never hit. I'm setting target milestone to 1.2.5 because I think that this will let enough time for the fix in the 1.3 series to be tested. When (if) 1.2.5 is about to be released, the new code can be backported (assuming that there's no report about the assertions being hit, of course).
If you think it's worth to backport it to 1.2, please do so now. This should give us more chances to have it tested.
Now fixed also in STABLE: 2003-05-21 Pedro Gimeno <pggimeno@wanadoo.es> * app/paint_funcs.c (shrink_line): Ported back fix for bug #104693 from HEAD branch (new algorithm for downscaling).
The fix is part of the stable release 1.2.5. Closing this bug.