
Brunsli: Practical JPEG repacker (now part of JPEG XL) - networked
https://github.com/google/brunsli
======
rndgermandude
Preemptive disclaimer: I don't want to belittle the work the authors did here
in any way, and are actually excited especially about the reversible, lossless
jpeg<->brunsli coding and that google's buy in and network effects will most
likely mean this comes to a viewer/editing software near you in the not so
distant future (unlike lepton, which never got out of it's tiny niche).

But seeing the 22% improvement figure reminded me that the typical JPEG file
on the internet is rather unoptimized even on write-once-read-many services
like imgur or i.reddit.com which transform files (stripping meta data etc) and
do not preserve the original files. Just using the regular vanilla libjpeg
encoder you can usually save 5%-10% just by lossless recoding of the coeffs
and the better-yet-more-computionally-intense mozjpeg coder can even get you a
bit further than that.

Then again, the imgur single image view page (desktop) I just randomly opened
by randomly clicking an item on their homepage transfers 2.9MiB of data with
ads blocked (3.9MiB deflated), 385KiB of which was the actual image, and that
image can be lossless recoded by mozjpeg to 361KiB (24KiB difference, a 6.2%
reduction), so the 24KiB (0.8%) reduction out of 2.9MiB of cruft hardly
matters to them I suppose and may be cheaper in bandwidth and storage cost to
them than the compute cost (and humans writing and maintaining the code).

Using brunsli, that same 385KiB imgur file went down to 307KiB so roughly a
20% reduction, but still only 2.6% reduction of that massive 2.9MiB the imgur
site transferred in total.

~~~
zxcvbn4038
I get what your saying but when your storing millions of images and
transferring them frequently those small reductions in size are very
significant when you get your storage and/or transit bill. A.lot of the fluff
and filler you mentioned is cached, so your not bringing it down every
request. Even if it wasn’t you can assume it’s deemed becc

~~~
IshKebab
I think that's his point - you can _already_ reduce JPEG size a bit by using
fancier libraries, but even huge sites like Imgur apparently don't bother.

~~~
jonsneyers
Maybe Imgur doesn't bother, I don't know. I work for Cloudinary, and we do
bother. A lot.

------
crazygringo
Sorry, can someone here clarify --

Does this reduce the size of JPEG files, maintaining JPEG format?

Or is this about repacking JPEG files into JPEG XL files (while reducing
size), while maintaining the ability to losslessly revert to JPEG?

The page never explicitly states what format the "repacking" is _into_ , and
it has so many references to JPEG XL that it no longer seems obvious that it's
into just JPEG?

~~~
rndgermandude
It does not maintain the JPEG format, tho it will be part of the JPEG XL
format.

It is repacking/recoding jpegs in a lossless and reversible manner, so that
clients supporting brunsli can be served directly with the optimized version
(their apache and nginx modules seem to serve files with a image/x-j mime),
and clients without support can be served with the original jpeg file (or
served with a brunsli file and decoded with a wasm-brunsli->native jpeg
decoder pipeline if wasm is an option), while you only have to keep the
brunsli (or original jpeg) file around.

Since JPEG XL isn't finished yet, there still might be minor differences in
the end that make the current brunsli format incompatible to the JPEG XL
format, so I wouldn't mass-convert your files just yet.

------
twotwotwo
This could be what provides the 'activation energy' to get large Web sites
working with JXL; it avoids the situation where you don't want to touch a new
standard until everyone else switches too. If Google ships a decoder in
Chromium, I would give JXL decent odds of getting a lasting niche.

Also, 20% off JPEG1 sizes is better than it may sound; you only save about 30%
more by switching to any of the new codecs (JXL's VarDCT or the video-codec-
based ones) that apply a ton of new tools. Given JPEG1 was published 1992,
that just confirms to me Tim Terriberry's quip that it was "alien technology
from the future."

Working against JPEG XL: it's four modern image formats in one (VarDCT,
Brunsli, FUIF, and a separate lossless codec) so a ton of work to
independently implement. Also, video codecs _already_ have ecosystem support,
and have or will probably get hardware support first.

Further out: "JPEG restoration" is something I mostly see experimental work
about but could also take the old format a bit further. The idea is to use
priors about what real images should look like to make an educated guess at
the information that was quantized away, so you get less of the characteristic
blocking and ringing from overcompresed images.

(For example, look at Knusperli, JXL's "edge-preserving filter", or AV1's
CDEF. The "quantization constraint" supported by the first two of those is, to
me, what makes it "restoration" and not just another loop filter: it can
always return pixels that could have compressed to the exact DCT coefficients
in the file.)

~~~
JyrkiAlakuijala
The separate lossless codec and FUIF and some additional ideas have been
integrated into the modular mode. The modular mode and VarDCT can be mixed in
the same image.

JPEG XL decoder no longer performs 'quantization constraint', it is a classic
loop filter, just with heuristics and control fields to maintain detail much
better than loop filters in video codecs.

If you start with sharp high quality originals that don't have yuv420 in them,
you usually will see 65 % savings with JPEG XL, i.e. more than 30 % on top of
brunsli. You can think of VarDCT-mode as guetzli(-35 %) + brunsli(-22 %) +
format specific changes(-30 %) like variable sized dcts, better colorspace,
adaptive quantization and loop filtering.

~~~
twotwotwo
Thanks, I appreciate the corrections and detail.

I was mostly going by the committee draft on the arXiv
([https://arxiv.org/abs/1908.03565](https://arxiv.org/abs/1908.03565) ), which
still mentioned the quantization constraint (J.3) and a "mathematically
lossless" mode (annex O) distinct from modular. "Four formats" was just
imprecise wording on my part.

The material already public about JPEG XL's design rationale, testing, and so
on has been really fun to follow as an outsider. I selfishly hope there's more
of it as the work on it and rollout continue. Even with the standard itself
public, a lot can be mysterious to those not immersed in this stuff.

~~~
janwas
Yes, quantization constraint was removed post-CD and Annex O was recently
merged into the modular mode to simplify the standard. JXL's page count is 1/2
to 1/3 of contemporary video codecs.

~~~
twotwotwo
Thanks. If there are places the public can follow progress post-CD, I'm
curious. (I see [https://gitlab.com/wg1/jpeg-xl/](https://gitlab.com/wg1/jpeg-
xl/) was updated late Feb, yay.)

~~~
janwas
:) There are updates every ~3 months at
[https://jpeg.org/news.html](https://jpeg.org/news.html).

------
jncraton
Does anyone know how this compares to other projects such as Lepton?

[https://github.com/dropbox/lepton](https://github.com/dropbox/lepton)

The goals and results appear similar. Is the primary difference that brunsli
will likely actually be part of a standard (JPEG XL)?

~~~
gbanfalvi
And how does it compare against HEIF?

~~~
0-_-0
HEIF can't compress JPEG images losslessly

~~~
rndgermandude
Indeed, HEIF/HEIC is basically a slightly dumbed down HEVC (h.265) i-frame
(full frame) (HEIC)[1] and new container format (HEIF)[2], similar to WEBP
being VP8 i-frames in a RIFF container. So they are used as full blown codecs
in practice, usually not in a lossless mode, so shifting JPEG to HEIC or WEBP
will lose some quality.

[1] Decoding HEIC in Windows (10) requires you to have installed a compatible
HEVC decoder. Which is 99 cents (and the hassle of setting up a store accounts
and payment processing with MS) or an alternative free one which will use the
HEVC codec that is shipped with hardware such as newer Intels (QSV) or GPUs.
Thank you patent mess!

[2] HEIF the container format can contain JPEG data, but in practice does not
or only as a supplementary image (previews, pre-renders, thumbnails, etc)

------
sischoel
If someone is wondering where the name comes from:
[https://www.saveur.com/article/Recipes/Basler-Brunsli-
Chocol...](https://www.saveur.com/article/Recipes/Basler-Brunsli-Chocolate-
Almond-Spice-Cookies/)

Not sure if it is the best recipe - the ones I use are usually written in
German.

~~~
waffle_ss
Brotli, another compression algorithm created by Google is also named after a
Swiss baked good:
[https://en.wikipedia.org/wiki/Spanisch_Br%C3%B6tli](https://en.wikipedia.org/wiki/Spanisch_Br%C3%B6tli)

~~~
pw6hv
Zopfli also comes from a Swiss bakery product. Developers must like
carbohydrates :)

~~~
spider-mario
And let’s not forget Gipfeli and Knusperli ;)

[https://github.com/google/gipfeli](https://github.com/google/gipfeli)

[https://github.com/google/knusperli](https://github.com/google/knusperli)

~~~
camillovisini
How about grittibanzli?

[https://github.com/google/grittibanzli](https://github.com/google/grittibanzli)

------
oefrha
Huh, I always just used good ol’ jpegtran:

    
    
      jpegtran -copy none -optimize -progressive -outfile "$image" "$image"
    

I have a wrapper script around this to allow bulk optimization as well as
calculating stats.

Time to switch I guess.

~~~
marton78
You should use mozjpeg instead. It's a jpegtran fork and drop in replacement
which optimizes the Huffman table even better.

~~~
jonsneyers
Does it really optimize the Huffman trees better? I wouldn't think there's
more you can do to optimize Huffman trees than make them reflect the actual
histogram.

Mozjpeg does try different progressive scan scripts – different scripts lead
to different compression behavior. That helps a bit, though I don't like it
when it separates the Cb and Cr planes, becauses that leads to "flash of weird
color" when decoding progressively. See also:
[https://cloudinary.com/blog/progressive_jpegs_and_green_mart...](https://cloudinary.com/blog/progressive_jpegs_and_green_martians)

------
taf2
I like the check list for features... can't wait for

"Nginx transcoding module"

------
zxcvbn4038
I understand what your saying but when your storing millions of images and
transferring them frequently those small reductions in size are very
significant when you get your storage and/or transit bill at end of month. A
lot of the fluff and filler you mentioned is compressed and cached, so your
not bringing it down every request and not in raw form. Even if you are
sending a huge amount of uncachable stuff with each request it doesn’t mean
savings wouldn’t be appreciated. It’s funds for a team lunch if nothing else!

------
wiradikusuma
Could someone explain what a "repacker" is?

What I know: In Photoshop, when I save an image as JPEG, I can decide the
"quality" (Low, Medium, High, etc). The lower it is, the smaller the file size
but the image will have (more) artifacts. The resulting image can then be
opened in any image viewer including browsers.

Also, I was told to save the "master" copy in a lossless format (e.g. TIFF or
PNG) because JPEG is a lossy format (like MP3 to WAV).

So how does a "repacker" come to play?

~~~
mkl
JPEG compression works in two phases:

1\. Discrete Cosine Transform, discarding insignificant information.

2\. Compression of bitstream.

Step 1 is lossy in practice because it throws away things that seem
insignificant. The "quality" control determines what counts as insignificant.
Step 2 is lossless, and just tries to make the data coming out of Step 1 take
up as little space as possible.

A repacker redoes Step 2 better: it makes the file smaller without reducing
the quality, by changing how the data is compressed, not changing which parts
are kept.

------
wyoh
> Brunsli has been specified as the lossless JPEG transport layer in the
> Committee Draft of JPEG XL Image Coding System and is ready to power faster
> and more economical transfer and storage of photographs.

I thought the lossless part of JPEG XL was done by FUIF, am I misunderstanding
something?

~~~
janwas
Lossless transcoding of JPEG bitstreams is done by Brunsli, there is also
lossless storage of pixels, based on tech from FUIF plus an adaptive predictor
by Alex Rhatushnyak.

~~~
JyrkiAlakuijala
Plus the 'select' predictor from WebP lossless :-)

~~~
jonsneyers
Plus tons of cross-pollination from the PIK/VarDCT mode, e.g. the (MA)ANS and
Brotli entropy coding and the Patches intra/inter block copy mechanism :)

