Bug 74286 - [Chromium] Use decoding swizzle only on libjpeg-turbo 1.1.90+
Summary: [Chromium] Use decoding swizzle only on libjpeg-turbo 1.1.90+
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Images (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: noel gordon
URL:
Keywords:
Depends on: 76881
Blocks: 59670
  Show dependency treegraph
 
Reported: 2011-12-12 04:03 PST by Hironori Bono
Modified: 2012-01-30 22:41 PST (History)
7 users (show)

See Also:


Attachments
Patch (2.33 KB, patch)
2012-01-26 21:44 PST, noel gordon
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Hironori Bono 2011-12-12 04:03:39 PST
(Copied from <http://crbug.com/106954>.)

Chrome Version       17.0.963.0 and 17.0.963.2 (Dev Channel)
URLs (if applicable) : all pages with contains images 
Other browsers tested:
Add OK or FAIL after other browsers where you have tested this issue:
Safari 5:
Firefox 4.x:
IE 7/8/9:

What steps will reproduce the problem?
1. open chromium in start page (all thumbails fail render)
2. go to all webpages (whatever, whichever is)
3. view images

What is the expected result?
render JPEG images in any pages

What happens instead?

this

http://wstaw.org/m/2011/12/09/plasma-desktopX20437.png
http://wstaw.org/m/2011/12/09/plasma-desktopOG6636.png http://wstaw.org/m/2011/12/09/plasma-desktopgO6636.png
http://wstaw.org/m/2011/12/09/plasma-desktopW20437.png
http://wstaw.org/m/2011/12/09/plasma-desktopp20437.png

Please provide any additional information below. Attach a screenshot if
possible.

system archlinux 64bits.

build with:

GYP_DEFINES=gcc_version=46 werror= no_strict_aliasing=1 linux_sandbox_path=/usr/lib/chromium-dev/chromium-sandbox linux_sandbox_chrome_path=/usr/lib/chromium-dev/chromium release_extra_cflags=-march=x86-64 -mtune=native -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 disable_nacl=1 use_system_ffmpeg=0 build_ffmpegsumo=1 proprietary_codecs=1 use_system_vpx=1 use_system_speex=1 use_system_libxslt=1 use_system_libxml=1 use_system_bzip2=1 use_system_zlib=1 use_system_libjpeg=1 use_system_libpng=1 use_system_yasm=1 use_system_libevent=1 use_system_icu=0 use_system_ssl=0 use_pulseaudio=1 use_gconf=0 use_gnome_keyring=0 linux_link_gnome_keyring=0 target_arch=x64  linux_strip_binary=1 remove_webcore_debug_symbols=1

libjpeg-turbo 1.1.1-3 (latest update: 2011-06-26) (install by the distro [extra] repository)

up to 17.0.963.0, work with external libjpeg libs

when use internal (use_system_libjpeg=0) with latest version of chromium Dev-Channel the render JPEG images works without problem

in compile time don't show any error

greetings
Comment 1 Hironori Bono 2011-12-12 04:06:25 PST
Greetings Noel,

Unfortunately, the decoding swizzle code (introduced by WebKit r101286 <http://trac.webkit.org/changeset/101286>) works only on libjpeg-turbo 1.1.90 or later. Is it possible to avoid using your swizzle code when we build Chromium with a USE_SYSTEM_JPEG macro, i.e. OS(CHROMIUM) && defined(USE_SYSTEM_JPEG)?

Regards,

Hironori Bono
Comment 2 Peter Kasting 2011-12-12 12:46:20 PST
(In reply to comment #1)
> Unfortunately, the decoding swizzle code (introduced by WebKit r101286 <http://trac.webkit.org/changeset/101286>) works only on libjpeg-turbo 1.1.90 or later. Is it possible to avoid using your swizzle code when we build Chromium with a USE_SYSTEM_JPEG macro, i.e. OS(CHROMIUM) && defined(USE_SYSTEM_JPEG)?

Is there any way to query the libjpeg-turbo version, either via macros, or in some sort of package configure script that can then set the appropriate Chrome build options?

I kind of dislike turning this off for all "use system libraries" cases because then even systems with more recent libraries miss out on the optimization.
Comment 3 Hironori Bono 2011-12-13 01:43:31 PST
Greetings Peter,

Many thanks for your comments.

(In reply to comment #2)
> Is there any way to query the libjpeg-turbo version, either via macros, or in some sort of package configure script that can then set the appropriate Chrome build options?

Unfortunately, I cannot find any macros representing the version in the (original) source code of libjpeg-turbo. I will file a feature request for it.

> I kind of dislike turning this off for all "use system libraries" cases because then even systems with more recent libraries miss out on the optimization.

It makes sense. I have focused on the "use_system_jpeg=1" option too much even though this bug name is "Use decoding swizzle only on libjpeg-turbo 1.1.90+".

Until libjpeg-turbo adds its version number, should we enable this swizzle code for performance or disable it for compatibility with existing libjpeg-turbo?

Regards,

Hironori Bono
Comment 4 Paweł Hajdan, Jr. 2011-12-13 02:08:03 PST
(In reply to comment #2)
> Is there any way to query the libjpeg-turbo version, either via macros,
> or in some sort of package configure script that can then set the appropriate Chrome build options?

Note that it's not just about compile-time compatibility. It should be possible to compile against libjpeg-turbo and then use vanilla libjpeg at run-time without problems.

Currently it's not the case, see https://bugs.gentoo.org/show_bug.cgi?id=393471#c3 and the next comment on that bug.

The fix for this should allow the users to use any of libjpeg, libjpeg-turbo at run time and get correct rendering.

> I kind of dislike turning this off for all "use system libraries" cases because then
> even systems with more recent libraries miss out on the optimization.

Arguably correctness is more important than performance. I don't find fast and broken rendering very useful.
Comment 5 Hironori Bono 2011-12-13 02:45:09 PST
Greetings,

I should have written the background of this issue in details.

(In reply to comment #4)
> Arguably correctness is more important than performance. I don't find fast and broken rendering very useful.

I assume we all think correctness is important. I think Peter just likes to find possible options that we can provide the performance gain provided by libjpeg-turbo 1.1.90+ on all platforms that have it installed. (JPEGImageDecoder.cpp is used not only for Chromium but also for all WebKit-based browsers.)
Unfortunately, as written in my comment, we do not have good options to satisfy his request for now and we need to find good alternatives, such as:
* Disable the swizzle code on all platforms:
* Enable the swizzle code only when we compile WebKit with a USE() macro;
* Enable the swizzle code only when we compile WebKit with use_system_jpeg=0.
Since each option has both advantages and disadvantages, I would like to hear your thoughts.

Regards,

Hironori Bono
Comment 6 Mike Gilbert 2011-12-13 10:49:57 PST
(In reply to comment #5)
> * Enable the swizzle code only when we compile WebKit with a USE() macro;

This seems like the most flexible option to me.

Over in Gentoo land, we could introduce a portage use flag that would translate into a gyp definition and enable or disable the "swizzle" code explicitly.

This would also allow us to add libjpeg-turbo as an optional dependency; if the user enables the use flag, we hard depend on libjpeg-turbo. If they disable it, we depend on either libjpeg or libjpeg-turbo.

Other distros could make the decision when they build packages.

Just my 2 cents as a user and a Gentoo dev. Hopefully Pawel agrees with me.
Comment 7 Paweł Hajdan, Jr. 2011-12-14 00:52:43 PST
(In reply to comment #5)
> JPEGImageDecoder.cpp is used not only for Chromium but also for all WebKit-based browsers.

Just wait for all those WebKit-based browsers used in the Linux land to hit the same problem. They just update WebKit much more rarely than Chromium does. I'm pretty sure they'd be affected in the same way.

> Unfortunately, as written in my comment, we do not have good
> options to satisfy his request for now and we need to find good alternatives, such as:
> * Disable the swizzle code on all platforms:
> * Enable the swizzle code only when we compile WebKit with a USE() macro;
> * Enable the swizzle code only when we compile WebKit with use_system_jpeg=0.

Provided we get -DUSE_SYSTEM_LIBJPEG in that WebKit file when -Duse_system_jpeg=1 is passed (I haven't checked that, and it's obviously fixable by ensuring proper gyp dependencies are in place).

For me, all of those options are fine. You probably want something that'd make it enabled for Google Chrome, so my best bet is a USE() macro, controlled by use_system_jpeg on the Chrome side.

(In reply to comment #6)
> Over in Gentoo land, we could introduce a portage use flag
> that would translate into a gyp definition and enable or disable the "swizzle" code explicitly.

Note: I'm not enthusiastic about such a flag. IMO it's an unnecessary complication.

> Other distros could make the decision when they build packages.

Sounds good. In Gentoo though I'd _probably_ prefer to have the swizzle code off, until the vanilla libjpeg also supports it.
Comment 8 Hironori Bono 2012-01-04 17:36:50 PST
Greetings,

I'm a little out-of-sync due to vacation.

(In reply to comment #7)
> Provided we get -DUSE_SYSTEM_LIBJPEG in that WebKit file when -Duse_system_jpeg=1 is passed (I haven't checked that, and it's obviously fixable by ensuring proper gyp dependencies are in place).

Oops, I forgot describing about the USE(SYSTEM_LIBJPEG) macro. (I assumed everyone had knowledge about WebKit macros.) As listed in its definition (copied from Platform.h), USE(SYSTEM_LIBJPEG) becomes 1 when we have a '-DWTF_USE_SYSTEM_LIBJPEG=1' flag.

#define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE && WTF_USE_##WTF_FEATURE)

Regards,

Hironori Bono
Comment 9 Hironori Bono 2012-01-10 00:38:12 PST
Greetings,

I have finally caught up with the discussion in <https://bugs.gentoo.org/show_bug.cgi?id=393471>. As written in this discussion libjpeg-turbo now adds new colorspace extensions (JCS_EXT_RGBA, JCS_EXT_ARGB, etc.) so we can check if libjpeg-turbo can fill alpha values with 0xFF. So, can we use these extensions and use swizzling only when we can use these new extensions?

Regards,

Hironori Bono
Comment 10 noel gordon 2012-01-26 20:47:35 PST
Detecting JCS_ALPHA_EXTENSIONS should be enough to test for a modern libjpeg-turbo I believe.
Comment 11 noel gordon 2012-01-26 21:35:01 PST
(In reply to comment #10)
> Detecting JCS_ALPHA_EXTENSIONS should be enough to test for a modern libjpeg-turbo I believe.

And that was added at r732
  http://libjpeg-turbo.svn.sourceforge.net/viewvc/libjpeg-turbo/trunk/jpeglib.h?r1=732&r2=731&pathrev=732

And bug 76881 updates libjpeg-turbo to r733.
Comment 12 noel gordon 2012-01-26 21:44:25 PST
Created attachment 124255 [details]
Patch
Comment 13 Kenneth Russell 2012-01-27 10:16:42 PST
Comment on attachment 124255 [details]
Patch

Looks fine assuming it compiles and runs. r=me
Comment 14 noel gordon 2012-01-29 14:23:50 PST
(In reply to comment #4)
> (In reply to comment #2)
> > Is there any way to query the libjpeg-turbo version, either via macros,
> > or in some sort of package configure script that can then set the appropriate Chrome build options?
> 
> Note that it's not just about compile-time compatibility. It should be possible to compile against libjpeg-turbo and then use vanilla libjpeg at run-time without problems.
> 
> Currently it's not the case, see https://bugs.gentoo.org/show_bug.cgi?id=393471#c3 and the next comment on that bug.
> 
> The fix for this should allow the users to use any of libjpeg, libjpeg-turbo at run time and get correct rendering.

Simple rule: if you build against libjpeg-x for any x including turbo, then you should run against libjpeg-x.  There is a cautionary note about this in the libjpeg.txt|.doc included in libjpeg distributions.
https://bugs.gentoo.org/show_bug.cgi?id=393471#c3 shows what happens when you ignore that cautionary note (broken rendering, or no jpeg at all).  The rule is not specific to libjpeg-turbo; it applies to all libjpeg.
Comment 15 noel gordon 2012-01-29 14:25:55 PST
(In reply to comment #13)
> (From update of attachment 124255 [details])
> Looks fine assuming it compiles and runs. r=me

Compiles, runs, and the relevant tests look good to me.  Submitting.
Comment 16 noel gordon 2012-01-29 15:19:36 PST
(In reply to comment #11)
> (In reply to comment #10)
> > Detecting JCS_ALPHA_EXTENSIONS should be enough to test for a modern libjpeg-turbo I believe.
> 
> And that was added at r732
>   http://libjpeg-turbo.svn.sourceforge.net/viewvc/libjpeg-turbo/trunk/jpeglib.h?r1=732&r2=731&pathrev=732
> 
> And bug 76881 updates libjpeg-turbo to r733.

I note that the libjpeg-turbo GenToo currently uses is buggy and contains a security flaw.  Consider upgrading to r729+.
Comment 17 WebKit Review Bot 2012-01-29 16:00:02 PST
Comment on attachment 124255 [details]
Patch

Clearing flags on attachment: 124255

Committed r106203: <http://trac.webkit.org/changeset/106203>
Comment 18 WebKit Review Bot 2012-01-29 16:00:07 PST
All reviewed patches have been landed.  Closing bug.
Comment 19 DRC 2012-01-30 22:41:31 PST
(In reply to comment #14)
> Simple rule: if you build against libjpeg-x for any x including turbo, then you should run against libjpeg-x.  There is a cautionary note about this in the libjpeg.txt|.doc included in libjpeg distributions.
> https://bugs.gentoo.org/show_bug.cgi?id=393471#c3 shows what happens when you ignore that cautionary note (broken rendering, or no jpeg at all).  The rule is not specific to libjpeg-turbo; it applies to all libjpeg.

Even though it looks like you guys have resolved this issue, I wanted to add a general comment for posterity regarding API/ABI compatibility, which is basically what this issue boils down to.  The warning you parsed from libjpeg.txt is from the Thomas Lane days and has remained unchanged since at least jpeg-6b (1998.)  What it's basically saying is:  the libjpeg API/ABI exposes all of its configuration structures, and thus if the IJG has to add features to libjpeg, these new features may render the API/ABI backward-incompatible with previous releases.  That is exactly what happened with jpeg-7, and again with jpeg-8.

This is why libjpeg-turbo emulates all three of those API/ABIs.  If you are building libjpeg-turbo with (for instance) jpeg-6b emulation, it should effectively work as a drop-in replacement for jpeg-6b.  jpeg-7 and jpeg-8, similarly, except that a couple of features of jpeg-7 and jpeg-8 (DCT scaling and fancy downsampling in the compressor) are not supported, and those parameters are silently ignored if passed to libjpeg-turbo (irrelevant in your case, since you're using libjpeg-turbo in a web browser.)

When building as a shared library on Linux, all of the symbols are versioned, which should prevent an application from using a shared library that exports a different version of the libjpeg API/ABI from the one against which the application was linked.

In short, there should be no danger with interchanging libjpeg-turbo at run time with a version of libjpeg that exports the same API/ABI.  The only potential problem involves the colorspace extensions, and jcstest.c in the libjpeg-turbo source shows how to detect their presence at run time.  This allows applications that were built against libjpeg-turbo to safely fall back or to generate an error if the application dynamic links against libjpeg at run time.

Anyhow, the above scenario may be rare enough to not warrant consideration, but I mainly wanted to document that it is technically feasible to swap libjpeg with libjpeg-turbo and vice versa at run time, if the need ever arises.  That was one of the big reasons why we chose to build a SIMD-accelerated JPEG library around the libjpeg API instead of another one.  I never imagined it would become so popular 2 years later.  :)