GNOME Bugzilla – Bug 665897
Scaled down images have poor quality
Last modified: 2016-08-15 18:00:49 UTC
Images that have been scaled down are displayed with a poor quality. This is more noticeable with some images than others. It is most noticeable in images with "fuzzy" or out of focus sections. It appears at all zoomed-out levels (25%, 30%, 43%, etc.) I've noticed. At 100% images look fine. I've included an archive which contains a screnshot comparing the same image displayed with eog and Geeqie (which displays it normally), as well as the image file itself. I checked the preferences, and "Smooth images when zoomed-out" is enabled, as the screenshot will show. I have noticed this problem on two different systems, both Linux. To reproduce, simply open the included jpg file and view at less than 100% I first encountered the bug with version 3.2.1, in Ubuntu 11.10 I do not believe the bug occurred with earlier versions that were shipped with Ubuntu 11.04 and 10.10 (Sorry, I do not have the exact version numbers for eog in front of me). My speculation (and to be clear, this is *speculation*) is that this has to do with the interpolation method, perhaps using Nearest Neighbor instead of Bilinear or some higher quality one.
The attachment was too large, and was rejected. The attachment can be downloaded at: http://www.filedropper.com/eogzoominbugtar This attachment contains a screenshot showing the problem as well as the image file itself.
We are using cairo for scaling. Indeed, the quality of the interpolation in the downscaling algorithms is not as good as the ones in GdkPixbuf. But we're not going back to GdkPixbuf. This probably needs to be fixed in cairo
Created attachment 203457 [details] [review] Use the preferred interpolation type when zoomed instead of assuming the right one
There was something odd in the drawing code. We were assuming that the cairo was using by default the one we use for the antialiasing case (CAIRO_FILTER_BILINEAR) but instead, it was using CAIRO_FILTER_GOOD. The patch above fixes this. However, I don't see any visible difference, the quality is pretty much the same. The patch should go in nevertheless, I think.
Review of attachment 203457 [details] [review]: (In reply to comment #4) > There was something odd in the drawing code. We were assuming that the cairo > was using by default the one we use for the antialiasing case > (CAIRO_FILTER_BILINEAR) but instead, it was using CAIRO_FILTER_GOOD. The patch > above fixes this. However, I don't see any visible difference, the quality is > pretty much the same. The patch should go in nevertheless, I think. I was wondering about that code snippet too, when I started looking into this last night. So, yes, let's get this in for starters. After some googling this appears to be an issue with pixman (the library underneath cairo): http://comments.gmane.org/gmane.comp.graphics.pixman/326 Check the comparision images in the first response, looks exactly like our problem here. I couldn't test the patch in that thread yet as I doesn't apply to the current code anymore. Unfortunately the supersampling patches for pixman seem to be dormant as I can't find any other activity regarding this beyond this email thread which is from August 2010. :( I wonder how the filtering quality would be when we switch to a Clutter-based view widget?
Comment on attachment 203457 [details] [review] Use the preferred interpolation type when zoomed instead of assuming the right one Thanks.
Good catch, that certainly seems to be the issue. I don't remember how the scaling looks with clutter, but I asked ebassi and they're using GL for the scaling, so this shouldn't be hitting the pixman issue.
*** Bug 670835 has been marked as a duplicate of this bug. ***
*** Bug 673536 has been marked as a duplicate of this bug. ***
I believe there is some progress on this from Pixman. A patch has appeared but I have not yet tested it. http://www.mail-archive.com/pixman@lists.freedesktop.org/msg01802.html
*** Bug 704571 has been marked as a duplicate of this bug. ***
*** Bug 711410 has been marked as a duplicate of this bug. ***
EOG 3.8.2 still has this bug. I have compared it with GIMP and Shotwell, they do not have it. I see lots of noise on JPG files, also on 100% zoom, so it is not exactly how this bug is described to be.
Created attachment 274797 [details] lots of noise in EOG, also 100% zoom This is my test with EOG 3.8.2, compared with Shotwell. Zoom is 100% in both. EOG has lots of noise, also in smaller view and 100%. It is a 18MP file.
Still a problem with 3.12.1. It’s especially bad with high res film scans that have strong grain. I tend to view pictures only with Chromium because their scaling algo is decent. Funny how Chromium views images much faster *and* with much higher quality than eog.
*** Bug 731931 has been marked as a duplicate of this bug. ***
*** Bug 722084 has been marked as a duplicate of this bug. ***
I see a lot of noise when I view large resolution photos made with high ISO (> 1000) using Eye of Gnome. The problem does NOT happen with other image viewers (e.g., Gwenview, Mirage, Shotwell, Okular). An example: https://dl.dropboxusercontent.com/u/2171814/casamento-rodrigo-juliete-por-francisco-cribari-grande--06122014-0052.jpg I run Ubuntu 14.04 64 bit and Eye of Gnome 3.10.2.
A screenshot: https://dl.dropboxusercontent.com/u/2171814/Screenshot%20from%202014-12-09%2013%3A20%3A33.png
Felix, let me paste the explanation you gave in comment 2 of issue 722084: """ This is due to a lack of bilinear filtering when scaling the image. We have a known issue with cairo here which although it is told to apply bilinear filtering upon scaling only does nearest neighbor filtering. """ I confirm what it's said in comments 13 and 14: problem is present even when zoom is 100%. I would change the title of this report.
*** Bug 743289 has been marked as a duplicate of this bug. ***
@cribari: Yes, that's exactly what is described here. Due to the insufficient filtering the existing noise gets even more visible. At 100% no filtering should occur. Maybe it's not exactly 100% due to rounding. Could you start eog from the terminal with EOG_DEBUG_WINDOW=1 set and post the output? About the general filtering problem. cairo-1.14 introduced more filtering options which produce a better view. Those however seem to be too slow for interactive use. So, I'll try if it is possible to use a low res filter while zooming and scrolling and update the view with the hires variant, but I can't promise that for 3.16.
The output: ** (eog:13693): WARNING **: Couldn't register with accessibility bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken. (eog:13693): EOG-WARNING **: Failed to open file '/home/cribari/.cache/thumbnails/normal/cf833abbf9478640547815a1efdda390.png': No such file or directory (eog:13693): EOG-WARNING **: Failed to open file '/home/cribari/.cache/thumbnails/normal/850d0d7d6e73ebca1e0826acb1165de4.png': No such file or directory (In reply to Felix Riemann from comment #22) > @cribari: > Yes, that's exactly what is described here. Due to the insufficient > filtering the existing noise gets even more visible. > > At 100% no filtering should occur. Maybe it's not exactly 100% due to > rounding. > Could you start eog from the terminal with EOG_DEBUG_WINDOW=1 set and post > the output? > > About the general filtering problem. cairo-1.14 introduced more filtering > options which produce a better view. Those however seem to be too slow for > interactive use. So, I'll try if it is possible to use a low res filter > while zooming and scrolling and update the view with the hires variant, but > I can't promise that for 3.16.
Did you set EOG_DEBUG_WINDOW=1? Then you should get some lines like [0,565931 (0,001443)] eog-scroll-view.c:1849 (display_draw) zoom 0,57, xofs: 0, yofs: 11 scaled w: 1447 h: 814 However, that's only necessary if you have the problem, that the image is filtered although it set to 100% zoom.
The output: cribari@darwin3:~/temp/eog$ eog ** (eog:14777): WARNING **: Couldn't register with accessibility bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken. cribari@darwin3:~/temp/eog$ export EOG_DEBUG_WINDOW=1 cribari@darwin3:~/temp/eog$ eog ** (eog:14848): WARNING **: Couldn't register with accessibility bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken. [0,025250 (0,025250)] eog-window.c:5655 (eog_window_new) [0,027518 (0,002268)] eog-window.c:5045 (eog_window_init) [0,135787 (0,108269)] eog-window.c:3956 (eog_window_cmd_zoom_fit) [0,139343 (0,003556)] eog-window.c:603 (update_action_groups_state) [0,140801 (0,001458)] eog-window.c:1974 (update_ui_visibility) [2,234666 (2,093865)] eog-window.c:5443 (eog_window_focus_out_event) [4,405159 (2,170493)] eog-window.c:5443 (eog_window_focus_out_event) [7,374104 (2,968945)] eog-window.c:5991 (eog_window_is_empty) [7,374137 (0,000033)] eog-window.c:5991 (eog_window_is_empty) [7,374156 (0,000019)] eog-window.c:5781 (eog_window_open_file_list) [7,409031 (0,034875)] eog-window.c:5697 (eog_job_model_cb) [7,413694 (0,004663)] eog-window.c:603 (update_action_groups_state) [7,415843 (0,002149)] eog-scroll-view.c:452 (check_scrollbar_visibility) Widget Size allocate: 1, 1 Bar: 0, 0 [7,419391 (0,003548)] eog-window.c:1268 (eog_window_obtain_desired_size) Setting window size: 852 x 918 [7,435113 (0,015722)] eog-scroll-view.c:452 (check_scrollbar_visibility) Widget Size allocate: 540, 378 Bar: 0, 0 [7,435174 (0,000061)] eog-scroll-view.c:452 (check_scrollbar_visibility) Widget Size allocate: 540, 378 Bar: 0, 0 [7,751586 (0,316412)] eog-window.c:1315 (eog_job_load_cb) [8,016371 (0,264785)] eog-window.c:890 (eog_window_display_image) [8,232971 (0,216600)] eog-window.c:516 (update_status_bar) [8,233255 (0,000284)] eog-scroll-view.c:452 (check_scrollbar_visibility) Widget Size allocate: 540, 378 Bar: 0, 0 [8,234060 (0,000805)] eog-window.c:516 (update_status_bar) [8,302620 (0,068560)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [8,318226 (0,015606)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [11,018533 (2,700307)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [11,142003 (0,123470)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [11,276351 (0,134348)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [11,310751 (0,034400)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [11,346271 (0,035520)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [11,368832 (0,022561)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [11,411753 (0,042921)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [11,535605 (0,123852)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [13,477648 (1,942043)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [13,594216 (0,116568)] eog-window.c:3991 (eog_window_cmd_go_next) [13,599779 (0,005563)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [13,613481 (0,013702)] eog-scroll-view.c:1902 (display_draw) zoom 0,08, xofs: 144, yofs: 0 scaled w: 252 h: 377 [13,784146 (0,170665)] eog-window.c:1315 (eog_job_load_cb) [14,033591 (0,249445)] eog-window.c:890 (eog_window_display_image) [14,274141 (0,240550)] eog-window.c:516 (update_status_bar) [14,274585 (0,000444)] eog-scroll-view.c:452 (check_scrollbar_visibility) Widget Size allocate: 540, 378 Bar: 0, 0 [14,275343 (0,000758)] eog-window.c:516 (update_status_bar) [14,300964 (0,025621)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [14,353911 (0,052947)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [16,959338 (2,605427)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [17,149298 (0,189960)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [17,992758 (0,843460)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [18,780748 (0,787990)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [19,198497 (0,417749)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [19,381811 (0,183314)] eog-window.c:3991 (eog_window_cmd_go_next) [19,389584 (0,007773)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [19,788411 (0,398827)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [20,136172 (0,347761)] eog-window.c:1315 (eog_job_load_cb) [20,389745 (0,253573)] eog-window.c:890 (eog_window_display_image) (eog:14848): EOG-WARNING **: Failed to open file '/home/cribari/.cache/thumbnails/normal/cea339159e58be2baed818b51a5e318b.png': No such file or directory [20,626386 (0,236641)] eog-window.c:516 (update_status_bar) [20,626659 (0,000273)] eog-scroll-view.c:452 (check_scrollbar_visibility) Widget Size allocate: 540, 378 Bar: 0, 0 [20,627126 (0,000467)] eog-window.c:516 (update_status_bar) [20,652601 (0,025475)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [20,707435 (0,054834)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [26,126429 (5,418994)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [26,319165 (0,192736)] eog-scroll-view.c:1902 (display_draw) zoom 0,11, xofs: 0, yofs: 8 scaled w: 540 h: 361 [26,731849 (0,412684)] eog-window.c:5107 (eog_window_dispose) [26,732756 (0,000907)] eog-window.c:1780 (fullscreen_clear_timeout) [26,732775 (0,000019)] eog-window.c:1812 (slideshow_clear_timeout) cribari@darwin3:~/temp/eog$ (In reply to Felix Riemann from comment #24) > Did you set EOG_DEBUG_WINDOW=1? Then you should get some lines like > > [0,565931 (0,001443)] eog-scroll-view.c:1849 (display_draw) zoom 0,57, xofs: > 0, yofs: 11 scaled w: 1447 h: 814 > > However, that's only necessary if you have the problem, that the image is > filtered although it set to 100% zoom.
At risk of blowing out the complexity, one option to deliver fast, high-quality scaling would be to construct an image pyramid, then when you want to render the image at a given size (less than 100%), scale down from the next-larger pyramid layer using the current fast scaling method. With a scaling factor of 2 for each layer of the pyramid, even the current fast scaling method should deliver high-quality results for the layers (if it works as I'm guessing, see below), and it should also work for scaling from the appropriate pyramid layer to the final size, as you'll never be scaling down more than 50%. I've not tried the algorithm described above, but my gut feel is that it should be comparable to something like the linear downscaling implemented in GIMP - maybe not quite as good, but not obviously worse in most cases. Obviously there's a CPU hit to get this done (shouldn't be a problem if you can thread it, and/or kick it off after the initial display of the image), and a 33% increase in RAM to store the additional pyramid layers, so there might need to be some safeguards around crazy-big images. At a guess I'd say what cairo is currently doing for eog *is* a by-the-book bilinear scaling: for each pixel in the destination image it finds where its centre would be in the original image and takes a weighted average of the four nearest source pixels. That works okay for upsampling, but for downsampling it becomes nearest-four-neighbours - better than nearest neighbour, but not by much once you're scaling much below 50%. (In reply to Felix Riemann from comment #22) > About the general filtering problem. cairo-1.14 introduced more filtering > options which produce a better view. Those however seem to be too slow for > interactive use. So, I'll try if it is possible to use a low res filter > while zooming and scrolling and update the view with the hires variant, but > I can't promise that for 3.16.
Created attachment 299476 [details] screenshot showing additional dithering in EOG As others have said, EOG image quality is visibly poorer than Chromium or Firefox, even at 100%. As can be seen in the attached screenshot, EOG seems to be doing more/worse dithering than Chromium. Is this because EOG is not using the full bit depth of the image? Or is EOG not using the full bit depth of the display? I'm using EOG 3.10.2-0ubuntu5 on Ubuntu 14.04 with cairo 1.13.0~20140204-0ubuntu1. I will attach the original image in the next comment.
Created attachment 299479 [details] original image for previous comment Partial output of ImageMagick's identify -verbose command: Type: TrueColor Endianess: Undefined Colorspace: sRGB Depth: 8-bit Channel depth: red: 8-bit green: 8-bit blue: 8-bit
Output of xwininfo -root|grep Depth Depth: 24
Created attachment 299480 [details] EOG_DEBUG_WINDOW=1 output Terminal output when running with EOG_DEBUG_WINDOW=1 set. I opened the Saturn image attached above and then immediately clicked the toolbar icon to adjust to 100% size, then closed the application.
There are so many problems with EOG, event memory usage is so leaky. Watching many large images one after another makes it using hundreds of MB of memory and creating swap at some point.
I understand that this is pixman's bug. Is it being tracked on their bug tracker? I couldn't find it.
There has been a fair bit of discussion about zooming to even numbers (ex bug 748913). I would image zooming to even multiples/fractions of the image such as 25,50,75% would allow to use simpler and thus less resource intensive anti-aliasing algorithms. Might be able to kill two birds with one stone.
Zooming a common FullHD (1920x1080) image to fit a 1366x768 display would require a zoom factor of 71.1%.
Created attachment 321092 [details] [review] [PATCH] Use better downscaling filter This patch uses CAIRO_FILTER_GOOD for image scaling, instead of _BILINEAR. The improvement can be seen here: http://imgur.com/a/NaoOs The test case, which was used to demonstrate a similar problem in Firefox, is here: https://autoindustry.files.wordpress.com/2009/03/ferrari_dino_concept_car_by_nixseraph.jpg I've only tested with eog 3.18.1, because the current master won't build against Fedora 23's libraries, but this patch is the same search-and-replace that produced the linked screenshots.
Hey, that's a nice find. When this ticket was started we switched away from FILTER_GOOD as it seemingly didn't cause an improvement in image quality. Apparently things changed a bit and it indeed seems to have an improved quality while also being fast enough for eog's mousewheel zooming (FILTER_BEST, which was my alternative to FILTER_BILINEAR so far, was much too slow in this point). I'll see if I can find out what happened to FILTER_GOOD.
Should've read your commit message which gives an explanation already. :) I am fine with giving this a go as it should be an improvement over the current situation in most cases. If things turn out to be too slow, it might be possible to reduce the filter quality during zooming. This will only have a visible effect with cairo-1.14.0 onwards, but eog-3.19/3.20 requires gtk+-3.19 which already has a dependency on cairo-1.14.0. So, we should be fine here, especially since older cairo versions just fall back to the current behaviour. Note that FILTER_BEST would produce a different (more pixelated) image when zooming in. However, as eog used the bilinear (less pixelated) zoom-in for pretty much forever now, the current setting should be fine. Thanks a lot for trying FILTER_GOOD again! :) commit fbc11280c6929852100de40e2dc70f5ec2adcea7 Author: Russell Haley <> Date: Sat Feb 13 18:59:17 2016 -0600 EogScrollView: Use better downscaling filter to fix Bug 665897 Replace all instances of CAIRO_FILTER_BILINEAR with CAIRO_FILTER_GOOD. This produces much less aliasing on downscaled images. CAIRO_FILTER_GOOD uses the same method as CAIRO_FILTER_BILINEAR for scale factors greater than 0.75, according to https://bugs.webkit.org/show_bug.cgi?id=147826. Comparison screenshots made with eog 3.18.1: http://imgur.com/a/NaoOs CAIRO_FILTER_BEST is better still, but the the visual difference is almost imperceptible and the performance impact is severe. https://bugzilla.gnome.org/show_bug.cgi?id=665897 --- This problem has been fixed in the unstable development version. The fix will be available in the next major software release. You may need to upgrade your Linux distribution to obtain that newer version.
The image quality is better, but very bad performance. https://youtu.be/QddT0tQsXRQ
It's not perfect, but it should help. commit 88c4f54eb9cee69b1eebef462df27f76119bec62 Author: Felix Riemann <> Date: Mon Feb 15 20:49:48 2016 +0100 EogScrollView: Implement simple two-pass filtering Show the filtered image only after a short time. This should improve the UI's responsiveness quite a bit. https://bugzilla.gnome.org/show_bug.cgi?id=665897
(In reply to Felix Riemann from comment #39) > This should improve the UI's responsiveness quite a bit. Yes. In some areas with large images it does not look perfect, for example, when you hover over the CSD button. But it is now much more responsive. Thank you.
*** Bug 748712 has been marked as a duplicate of this bug. ***
Unfortunately, this commit seems to introduce a crash: commit 88c4f54eb9cee69b1eebef462df27f76119bec62 Author: Felix Riemann <friemann@gnome.org> Date: Mon Feb 15 20:49:48 2016 +0100 EogScrollView: Implement simple two-pass filtering Show the filtered image only after a short time. This should improve the UI's responsiveness quite a bit. https://bugzilla.gnome.org/show_bug.cgi?id=665897
Running eog /path/to/a/file leads to a crash with this backtrace: (gdb) bt
+ Trace 236161
(In reply to Debarshi Ray from comment #43) > Running eog /path/to/a/file leads to a crash with this backtrace: Once the window shows up, move the mouse over it to trigger a redraw.
Created attachment 325560 [details] [review] EogScrollView: Prevent a crash when queueing a new draw
Review of attachment 325560 [details] [review]: Nice catch! Thanks! Interestingly it's not causing crashes for me. However, valgrind rightfully complains about it.
(In reply to Felix Riemann from comment #46) > Interestingly it's not causing crashes for me. However, valgrind rightfully > complains about it. Could be because I have this in my ~/.bash_profile: MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) export MALLOC_PERTURB_ See: http://udrepper.livejournal.com/11429.html
*** Bug 769499 has been marked as a duplicate of this bug. ***