
Guetzli: A New Open-Source JPEG Encoder - ashishgandhi
https://research.googleblog.com/2017/03/announcing-guetzli-new-open-source-jpeg.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+blogspot/gJZg+(Official+Google+Research+Blog)
======
londons_explore
This seems to be optimizing for a "perceptual loss function" over in
[https://github.com/google/butteraugli/blob/master/butteraugl...](https://github.com/google/butteraugli/blob/master/butteraugli)

Looking at the code to that, it looks like 1500 lines of this:

    
    
        double MaskDcB(double delta) {
          PROFILER_FUNC;
          static const double extmul = 0.349376011816;
          static const double extoff = -0.894711072781;
          static const double offset = 0.901647926679;
          static const double scaler = 0.380086095024;
          static const double mul = 18.0373825149;
          static const std::array<double, 512> lut =
              MakeMask(extmul, extoff, mul, offset, scaler);
          return InterpolateClampNegative(lut.data(), lut.size(), delta);
        }
    

The code has _hundreds_ of high precision constants. Some even seem to be set
to nonsensical values (like kGamma to 0.38) Where did all of them come from?
The real science here seems to be the method by which those constants were
chosen, and I see no details how it was done.

~~~
londons_explore
Upon more investigation, these numbers are certainly machine generated. Here
is an example:

A constant lookup table is used for determining the importance of a change vs
distance. Seperate tables are used for vertical and horizontal distances (I
guess eyes might be slightly more sensitive to vertical edges than horizontal
ones?).

Those tables are _wildly_ different in magnitude:

    
    
        static const double off = 1.4103373714040413;  // First value of Y lookup table
        static const double off = 11.38708334481672;   // First value of X lookup table
    
    

However, later on, when those tables are used, another scale factor is used
(simplified code):

    
    
        static const double xmul = 0.758304045695;
        static const double ymul = 2.28148649801;
    

The two constant scale factors directly multiply together, so there is no need
for both. No human would manually calculate to 10 decimal places a number
which had no effect. Hence, my theory is these numbers have been auto-
generated by some kind of hill climbing type algorithm.

~~~
cjhanks
Yeah, this looks like an optimizer wrote the program. I presume the code was
tested against natural images... so it might not be appropriate for all image
types.

------
pjsg
As the author of the original libjpeg (back in 1991), I think this has been a
long time coming! More power to Google.

~~~
agumonkey
Impressive :)

What are you on these days ? image codecs still ?

~~~
pjsg
No -- computer security -- which is a fascinating field. There are arms races
here between the good people and the bad people. It isn't clear that the
forces of good are winning. It is a Red Queen problem.

The original libjpeg code was written to try and change the Usenet News binary
pictures groups over from GIF to JPEG (so that more images would fit down the
rather narrow transatlantic pipe that I had at the time). The choice of
license turned out to be a good one (it predated the GPL V2) -- who knows what
would have happened if we (the precursor to the IJG) had chosen that one.

~~~
agumonkey
Were you already security saavy before or did you learn on the spot ? It's as
exciting as scary, and I wouldn't touch it with a ten foot pole :)

(thanks for the answer btw)

------
vladdanilov
I'm working on a similar thing
([http://getoptimage.com](http://getoptimage.com)). While Guetzli is still
visually better and a bit smaller in file size, it's terribly slow and
requires a lot of memory. But it's a great experiment. So much knowledge has
been put into it.

I believe using a full blown FFT and complex IQA metrics is too much. I have
great results with custom quantization matrices, Mozjpeg trellis quantization,
and a modification of PSNR-HVS-M, and there's still a lot of room for
improvement.

~~~
awalton
> it's terribly slow and requires a lot of memory.

...and generates a solution that uses far less bandwidth, especially after
thousands or millions of hits, which is the real point of the exercise.

Cloud computing companies _love_ this. They've got a lot of bored hardware to
put to use. It's absolutely no surprise to see solutions like this coming from
Google. Spending a dollar of compute time to save $1000 in bandwidth is a no-
brainer win for a company with a million servers.

~~~
vladdanilov
At the image upload rate nowadays, there's a place for a practical solution,
and for any external company, that kind of cloud computing will cost a
fortune.

------
mattpavelle
I'll run some of my own experiments on this today, but I'm initially concerned
about color muting.

Specifically looking at the cat's eye example, in the bottom of the pupil area
there's a bit of green (reflection?) in the lower pupil. In the original it is
#293623 (green) - in the libjpeg it is #2E3230 (still green, slightly muted).
But in the Guetzil encoded image it is #362C35 - still slightly green but
quite close to grey.

In my experience people love to see colors "pop" in photos (and photography is
where JPEG excels) - hopefully this is just an outlier and the majority of
compressions with this tool don't lose color like this.

~~~
jacobolus
In general if you want to avoid any color changes in blobs a few pixels in
size, you’ll want to take it easy on the compression, and take the hit of a
larger file size in trade.

I suspect that if you give this algorithm twice the file size as a budget,
that green color will come back.

~~~
mattpavelle
I agree, giving more file size may get us our colors back. And after some
experimentation I'd like to be able to confirm something a bit abstract like,
"Guetzli is good for reducing artifacts by sacrificing color" or some such
snippet.

It would definitely have its uses as such. Or maybe it's great all around and
I just found one bad example?

~~~
JyrkiAlakuijala
Guetzli sacrifices some chromaticity information, but tries to keep that in
balance with the intensity loss. Guetzli sacrifices colors much less than the
commonly used YUV420 mode -- the common default mode in JPEG encoding.

------
i80and
Some comparison with the mozjpeg encoder here:
[https://github.com/google/guetzli/issues/10](https://github.com/google/guetzli/issues/10)

TLDR:

> We didn't do a full human rater study between guetzli and mozjpeg, but a few
> samples indicated that mozjpeg is closer to libjpeg than guetzli in human
> viewing.

------
onion2k
Sort of related, but what's the story with fractal image compression? When I
was at university (~20 years ago) there was a lot of research going in to it,
with great promises heralded for web-based image transfer. There was a
Netscape plugin that handled them. They seemed to just disappear in the early
2000s.

~~~
TD-Linux
I think this paper was part of it, which showed that the advantages of fractal
image compression could equivalently be achieved with smooth wavelets and
efficient representation of zerotrees, except with a lot more speed and
flexibility (sorry no PDF):
[https://www.researchgate.net/publication/5585498_A_wavelet-b...](https://www.researchgate.net/publication/5585498_A_wavelet-
based_analysis_of_fractal_image_compression)

~~~
i336_
> _sorry no PDF_

No _directly-linkable_ PDF :P

[https://news.ycombinator.com/item?id=12374235](https://news.ycombinator.com/item?id=12374235)

------
dmitrygr
Cool, but neither the article nor the paper
([https://arxiv.org/pdf/1703.04416.pdf](https://arxiv.org/pdf/1703.04416.pdf))
mention just how much slower it is.

~~~
robryk
It's about 1 MPixel / minute on a typical desktop. The other paper mentions
that it's extremely slow, but truly we did forget to give actual numbers
there.

------
SloopJon
The Github README says, "Guetzli generates only sequential (nonprogressive)
JPEGs due to faster decompression speeds they offer." What's the current
thinking on progressive JPEGs? Although I haven't noticed them recently, I
don't know whether they're still widely used.

~~~
E6300
As a user, I dislike progressive images because of the ambiguity regarding
when they've finished loading.

~~~
nsuser3
As a user, I love progressive images because I can see the whole image very
fast. (I don't have to wait for it)

------
kozak
Wow, "webmasters creating webpages" is something that I haven't heard for a
very long time! I'm nostalgic.

------
discreditable
Previous discussion:
[https://news.ycombinator.com/item?id=13377539](https://news.ycombinator.com/item?id=13377539)

------
sschueller
Lots of Swiss German coming from Google lately. Zöpfli, Brötli and now
Guetzli.

I'm still hoping for a Google Now that understands Swiss German :)

~~~
cimnine
There's a huge Google lab in Zurich [1], probably that's why.

[1]
[https://careers.google.com/locations/zurich/](https://careers.google.com/locations/zurich/)

------
kzrdude
I wonder, does google's blog pick up that I can't read their web page due to
javascript blocking? Do they evaluate how many readers are turned away due to
such issues?

~~~
matt4077
Larry Page doesn't care, but it does keep Sergey up at night.

------
ktta
I wonder how Dropbox's Lepton[1] compresses JPEGs encoded using Guetzli. Since
they already pack more info/byte would there be noticeable compression?

Someone out there must have tried this.

[1]:[https://blogs.dropbox.com/tech/2016/07/lepton-image-
compress...](https://blogs.dropbox.com/tech/2016/07/lepton-image-compression-
saving-22-losslessly-from-images-at-15mbs/)

~~~
Scaevolus
I'd expect it to still save >20%. Lepton uses arithmetic encoding instead of
Huffman (-10%), and predicts each 8x8 block based on its neighbors (-20%).
Guetzli shouldn't interfere with either of these.

~~~
JyrkiAlakuijala
When we pack guetzlified JPEGs we see slightly smaller wins than with stock
JPEGs. Think -14% for guetzlified JPEGs vs. -20% libjpeg JPEGs.

------
leetbulb
I use ImageOptim ([https://imageoptim.com](https://imageoptim.com)) for small
tasks. For larger tasks, [https://kraken.io](https://kraken.io) is nuts.

------
d--b
Why spend a lot of time improving jpeg instead of spending time promoting a
HEVC-based standard like that one?
[http://bellard.org/bpg/](http://bellard.org/bpg/)

~~~
mtgx
If anything, they would spend the time to make it AV1-based, which apparently
was expected to come out this month:

[http://www.streamingmedia.com/Articles/Editorial/-110383.asp...](http://www.streamingmedia.com/Articles/Editorial/-110383.aspx)

[http://aomedia.org/about-us/](http://aomedia.org/about-us/)

~~~
ktta
Nope, they pushed the expected release date to end of this year[1]. I was
really hoping it would come out this month too, then I realized we won't see
much adoption till 2019. 2018 will be spent with a couple releases of software
decoders, and some adoption, and 2019 is when the hardware decoders will
released. Which is when we can expect everyone to more to AV1.

But I'm still skeptical because HEVC might be more widespread with hardware
decoders everywhere and people might just not care enough to move to the new
standard. Unless MPEG-LA exploits its dominance really bad with license fees,
then we can expect MPEG codecs to die off. Although I think x264 will still
live.

[1]:
[https://fosdem.org/2017/schedule/event/om_av1/attachments/sl...](https://fosdem.org/2017/schedule/event/om_av1/attachments/slides/1795/export/events/attachments/om_av1/slides/1795/av1_update.pdf)

(4th slide. This codec will be standardized after the experiments are removed
and it is frozen to test software.)

~~~
MikusR
The problem with HEVC is HEVC Advance. A second patent pool that appeared 2
years ago.

~~~
Veratyr
Not just HEVC Advance. There are also some patent holders who aren't members
of any pool, like Technicolour.

------
j0hnM1st
MacOS setup and testing with Lenna

[https://agileblaze.com/google-guetzli-image-compression-
setu...](https://agileblaze.com/google-guetzli-image-compression-setup-on-
macos/)

------
drdebug
This really looks great. I really wish the author(s) could provide a detailed
overview of the human vision model algorithm being implemented, what it is
doing and why, so we could reproduce an implementation, may be even provide
improvements? Otherwise amazing work.

------
iagooar
This Swiss naming of algorithms really gets old, especially if you speak
(Swiss) German...

------
rurban
Nice Makefile, jirki. I really have to look into premake which generated it.

But I get a gflags linking error with 2.1 and 2.2 with
-DGFLAGS_NAMESPACE=google. This is atrocious.
"google::SetUsageMessage(std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)" Without this it works
fine.

Guess I still have some old incompat gflags headers around.

EDIT: The fix on macports with 2.2 installed default into /usr/local is: make
CXX=g++-mp-6 verbose=0 LDFLAGS="-L/usr/local/lib -L/opt/local/lib -v"
CFLAGS=-I/usr/local/include

i.e. enforce gflags 2.2 over the system 2.1

------
whywhywhywhy
Great tech, shame about the name

------
tannhaeuser
Is JPEG2000 with progressive/resolution-responsive transcoding still a thing
or is HTML <picture> the way to go for responsive images (or maybe WepP)?

~~~
purerandomness
JPEG2000 died a bitter patent death.

~~~
userbinator
Actually, it's alive and well in the form of embedded images in PDFs, where
it's known as JPXFilter. Most of the ebooks (scans) I've downloaded from
archive.org use it. If it didn't have any huge advantage I doubt they would've
chosen it over standard JPEG.

The real problem, as far as I can see, is that JPEG2000 is _really slow_ to
decode due to its complexity.

~~~
acdha
Modern implementations are decent but there's no open source implementation in
that class. OpenJPEG is improving but it's much slower than Kakadu (which is
what CoreImage uses) or Aware.

~~~
boxerab
shameless plug for my JPEG 2000 codec:
[https://github.com/GrokImageCompression/grok](https://github.com/GrokImageCompression/grok)
. Performance currently around 1/3 Kakadu

~~~
acdha
Heh, yes - I've been following that since you announced it. It'd be really
nice if we could start getting the OSS toolchain onto a JP2 implementation
with decent performance — I think jasper really soured the reputation for many
people.

------
kup0
So far the results have been useful for me. It's been able to reduce size on
some tougher images that other optimizers would ruin quality-wise.

------
ZeroGravitas
How relevant to web pages is this?

The blog makes it sound like that's the target but the paper has this line:

"Our results are only valid for high-bitrate compression, which is useful for
long-term photo storage."

Do the author's think the size/quality benefits still show up when targetting
lower bitrates/qualities that are more common on the web? Do they intend to
try to prove it?

~~~
JyrkiAlakuijala
Quality-wise, Guetzli is applicable to about 50% of the JPEG images in the
internet. The other half is stored with lower than 85 quality, and Guetzli
declines to attempt to compress to that quality.

Another limitation is that Guetzli runs very slowly. This gives a further
limiting axis: Guetzli in its current form cannot be applied to a huge corpus
of images. Perhaps this covers half of the images on the internet.

So, let's say that Guetzli is 25% relevant to the web pages.

------
corybrown
Very cool. I'm not an expert, but does JPEG generally have a ton of
flexibility in compression? Why so much difference in sizes?

~~~
JyrkiAlakuijala
Three main methods:

1) YUV420 vs YUV444. Guetzli practically always goes for YUV444.

2) Choosing quantization matrices.

3) After normal quantization, choose even more zeros. JPEG encodes zeros very
efficiently.

When doing the above, increase the errors where it matters least (certain RGB
values hide errors in certain components, and certain types of visual noise
hides other kind of noise).

~~~
TD-Linux
Step 3), choosing more zeros, can be generalized with trellis quantization,
which does a search for the best values to encode for each block for the best
distortion-per-rate score, where distortion can be any metric (edit:
apparently guetzli does some sort of whole frame search for this). mozjpeg
does trellis with effectively the PSNR-HVS metric. Because the other two steps
are only one setting that affects the entire picture, I do wonder how Guetzli
would perform if it was just a wrapper around mozjpeg.

------
wildpeaks
Just tried the precompiled binary from:

[https://github.com/google/guetzli/releases](https://github.com/google/guetzli/releases)

and I'm getting "Invalid input JPEG file" from a lot of images unfortunately.

~~~
robryk
Sorry for that. See the following for a likely reason and workaround:

[https://github.com/google/guetzli/issues/40#issuecomment-287...](https://github.com/google/guetzli/issues/40#issuecomment-287209517)

~~~
wildpeaks
Thanks, I'll give it a try :)

------
mkj
Nice work. And yet google images still has horribly compressed low resolution
thumbnails...

------
underlines
if it may benefit anyone, i used this simple batch file to test out the lower
bound -quality 84 with drag and drop of one/multiple images on win 86-64:

    
    
      echo Drag and drop one or multiple jpg or png files onto this batch file, to compress with google guetzli using a psychovisual model
      if [%1]==[] goto :eof
      :loop
      echo compressing...
      guetzli_windows_x86-64.exe -quality 84 %1 "%~dpn1_guetzlicompressed%~x1"
      shift
      if not [%1]==[] goto loop
      echo DONE
    

i'm concerned about the color changes that are clearly visible throughout the
whole image.

~~~
JyrkiAlakuijala
Guetzli runs the whole image to the same specified quality -- when artefacts
start to emerge, they are everywhere, not just in one sensitive area. Guetzli
can be more likely worth its cpu cost at a higher quality, around 92-96.

------
sam-mueller
Are there any plans to make Guetzli available as a library for iOS and
Android? Would be great to process images right on device with this level of
compression.

------
simplehuman
[http://getoptimage.com/](http://getoptimage.com/) is better

------
shmerl
How does it compare to mozjpeg?

------
phkahler
Does it support 12-bit jpeg?

------
saltysalty
I am not an expert, but AFAIK JPEG is a lossy format. The comparison is purely
based on the size, and I couldn't find anything in the paper about data loss
compared to other encoders. Can someone please explain why is this a fair
comparison?

~~~
janwas
We did an experiment with comparisons of Guetzli and (slightly larger) libjpeg
output: [https://arxiv.org/abs/1703.04416](https://arxiv.org/abs/1703.04416)
Turns out that 75% of the 614 ratings are in favor of the Guetzli version.

