After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 494667 - gdkpixloader jpeg loader problems with some files
gdkpixloader jpeg loader problems with some files
Status: RESOLVED FIXED
Product: gdk-pixbuf
Classification: Platform
Component: general
git master
Other All
: Normal critical
: ---
Assigned To: gtk-bugs
gtk-bugs
: 500785 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2007-11-07 16:56 UTC by Ivan Baldo
Modified: 2010-07-10 04:07 UTC
See Also:
GNOME target: ---
GNOME version: 2.19/2.20


Attachments
Test program showing the failure (1.61 KB, text/plain)
2007-11-07 17:00 UTC, Ivan Baldo
  Details
Test program showing that gdk_pixbuf_from_file() doesn't fail. (736 bytes, text/plain)
2007-11-07 17:01 UTC, Ivan Baldo
  Details
gdk-pixbuf-jpeg-spinguard.patch (1.24 KB, patch)
2007-12-02 21:36 UTC, Ed Catmur
committed Details | Review

Description Ivan Baldo 2007-11-07 16:56:06 UTC
Please describe the problem:
I get this error with some jpeg files: "Error interpreting JPEG image file (Application transferred too few scanlines)".
It happens only when I use GdkPixbufLoader but not with gdk_pixbuf_new_from_file().

Steps to reproduce:
Compile and run the test program that I will attach with several jpeg files (try to use a variety of files from different sources, not always from the same one).


Actual results:
The error "Error interpreting JPEG image file (Application transferred too few scanlines)" is generated though other programs had no problem with those jpeg files and GTK 2.10 didn't had problems too.

Expected results:
No errors at all.

Does this happen every time?
Yes, when you find the jpeg files that cannot be loaded, it happens everytime.

Other information:
Comment 1 Ivan Baldo 2007-11-07 17:00:29 UTC
Created attachment 98725 [details]
Test program showing the failure
Comment 2 Ivan Baldo 2007-11-07 17:01:28 UTC
Created attachment 98726 [details]
Test program showing that gdk_pixbuf_from_file() doesn't fail.
Comment 3 Ivan Baldo 2007-11-09 19:47:33 UTC
I found that the commit 17567 to io-jpeg.c is the culprit.
Reverting this specific part "... and it pulls the check for infinite looping out of an else branch in load_increment() so it runs unconditionally ..." fixes the problem.
So here is a reverting patch but I don't know what other effects it has (except that it fixes the problem I see), but I guess Tim Janik knows better and now could fix this the right way.

--- io-jpeg.c   (revision 17567)
+++ io-jpeg.c   (working copy)
@@ -689,7 +689,7 @@
                        src->pub.bytes_in_buffer += num_copy;
                        bufhd += num_copy;
                        num_left -= num_copy;
-               }
+               } else {
 
                 /* did anything change from last pass, if not return */
                 if (first) {
@@ -699,6 +699,7 @@
                         spinguard++;
                 else
                         last_bytes_left = src->pub.bytes_in_buffer;
+               }
 
                /* should not go through twice and not pull bytes out of buf */
                if (spinguard > 2)


Thanks!
Comment 4 Ed Catmur 2007-12-02 21:31:27 UTC
The issue is that the spinguard fails to consider the case where the caller buffer is larger than 65536 bytes.  Instrumenting with:

                /* did anything change from last pass, if not return */
                if (first) {
                        last_bytes_left = src->pub.bytes_in_buffer;
                        first = FALSE;
                } else if (src->pub.bytes_in_buffer == last_bytes_left) {
                        spinguard++;
			g_message("spinguard %d: src->pub.bytes_in_buffer (%d) == last_bytes_left (%d)", spinguard, src->pub.bytes_in_buffer, last_bytes_left);
		} else
                        last_bytes_left = src->pub.bytes_in_buffer;

		/* should not go through twice and not pull bytes out of buf */
		if (spinguard > 2)
			return TRUE;


gives:

GdkPixbuf-Message: spinguard 1: src->pub.bytes_in_buffer (0) == last_bytes_left (0)
GdkPixbuf-Message: spinguard 2: src->pub.bytes_in_buffer (0) == last_bytes_left (0)
GdkPixbuf-Message: spinguard 3: src->pub.bytes_in_buffer (0) == last_bytes_left (0)
GdkPixbuf-Message: spinguard 1: src->pub.bytes_in_buffer (65536) == last_bytes_left (65536)
GdkPixbuf-Message: spinguard 2: src->pub.bytes_in_buffer (65536) == last_bytes_left (65536)
GdkPixbuf-Message: spinguard 3: src->pub.bytes_in_buffer (65536) == last_bytes_left (65536)


The fix should be to base the spinguard on num_left as well.
Comment 5 Ed Catmur 2007-12-02 21:36:12 UTC
Created attachment 100069 [details] [review]
gdk-pixbuf-jpeg-spinguard.patch

Patch.
Comment 6 Ed Catmur 2007-12-02 21:55:37 UTC
Seems to be a whole load of duplicates and derived bugs: bug 477860, bug 495703, bug 500785, bug 494667.

Agree with Ivan that http://svn.gnome.org/viewvc/gtk%2B/trunk/gdk-pixbuf/io-jpeg.c?view=log#rev17567 is the cuplrit - blame Maemo.
Comment 7 walt 2007-12-02 23:52:27 UTC
Great work, Ed.  Your patch unbreaks the pan newsreader (two of the bugs
you listed above) so lots of people will be happy again thanks to you.

Can your patch be committed now, or does it need more testing?
Comment 8 Matthias Clasen 2007-12-03 00:44:10 UTC
Looks ok to me. Please commit to the gtk-2-12 branch, too, if you can.
Comment 9 Jonathan Matthew 2007-12-03 01:57:02 UTC
*** Bug 500785 has been marked as a duplicate of this bug. ***
Comment 10 walt 2007-12-08 19:33:22 UTC
I notice that Ed's patch has not been committed yet.  Ed is not
identified as a 'developer', so perhaps he can't commit the patch
himself?  I don't know.  It would be great if someone could do it,
though.

Thanks!
Comment 11 Matthias Clasen 2007-12-09 18:59:23 UTC
2007-12-09  Matthias Clasen  <mclasen@redhat.com>

        * io-jpeg.c: Fix the spinguard logic for big buffers.
        (#494667, Ed Catmur)
Comment 12 karl.johan 2008-01-05 18:05:00 UTC
As pointed out by #491063, the workaround is to write the data in chunks.

This fast python implementation for PyGTK, inspired by
http://docs.python.org/lib/itertools-functions.html,
might save somebody a few minutes pain:

=========================================================================

from itertools import izip, chain, repeat

size = 50000

for chunk in izip(*[chain(imagedata, repeat('', size-1))] * size):
            myPixbufLoader.write(''.join(chunk))