serenity/Userland/Libraries/LibGfx
Nico Weber 6ab69b1cc1 LibGfx/WebPWriterLossless: Use predictor transform
...for images that don't use a color indexing transform.

For now, write the predictor transform unconditionally, and predict
every pixel as its left neighbor (that is, use predictor 1 everywhere).

This will grow a better heuristic in time, and eventually we might want
to use more than 1 of the 13 different predictor modes. But on average,
doing this unconditionally is better than not doing it unconditionally.
(Also, it's possible to disable this transform using `image`'s
`--webp-allowed-transforms` flag.)

Using the same benchmark as in #24819, this reduces the total size
of the test images further, from 88M to 69M (21.6%). It does increase
runtime for compressing all these images from about 4.4s to 4.7s,
a 6.8% slowdown.

For the usual test image (no effect on the two animations, which use
the color indexing transform):

    sunset_retro.png (876K):
        1.2M -> 730K, 31.4 ms ± 0.8 ms -> 31.4 ms ± 0.7 ms

From 37% larger than the input to 16% _smaller_ than the input :^)
(A 39% size reduction for this image.)

Compressing sunset_retro.png with zopflipng produces a 820K image,
so we're smaller even than what the best PNG encoder can do with
this image.

It's not a win for all images: For example, the size of
qoi_benchmark_suite/screenshot_web/sublime.png goes from 1.0M to 1.5M,
a fairly dramatic size increase. Hopefully we can get that back in
the future with better heuristics. (The input sublime.png is 1.3M,
and sublime.png encoded using our QOI encoder creates a 1.6M file,
so the 1.5M isn't atrocious, even though it's much bigger than the
size without the predictor transform.)

Our WebP Lossless writer currently now has a similar feature set
to our QOI writer: RLE, color cache, left prediction, and
subtract green is somewhat similar to QOI's luma chunk. The WebP
writer also writes huffman trees, which QOI doesn't do. For most
images, the WebP writer creates smaller files than the QOI writer,
while being about 50% slower. The WebP writer also writes smaller
files than Serenity OS's png writer, while being ~40x as fast
(for sunset_retro, ~30ms instead of ~1.3s; 730K output instead of
999K).

Only doing RLE and using a single predictor for the entire image is
similar to what fpng is doing (...but fpng uses the T predictor always).

We still don't write a meta prefix image to keep the huffman trees
flatter, we still don't do full LZ77 backward matches, and we still
don't write color transforms. But the writer has now enough features
to be in usable shape. It's now Serenity OS's best-compressing lossless
image writer.

The test_webp_color_indexing_transform_single_channel test uses a
linear horizontal gradient, which the predictor transform compresses
so well that encoded_data_without_color_indexing ends up being
smaller than the color indexed file. Just disable the predictor
transform in that test for now.
2024-07-28 12:35:41 -04:00
..
Filters
Font LibGfx: Add cache for glyph paths 2024-06-10 17:41:33 -04:00
ICC Everywhere: Use east const in more places 2024-04-19 06:31:19 -04:00
ImageFormats LibGfx/WebPWriterLossless: Use predictor transform 2024-07-28 12:35:41 -04:00
AffineTransform.cpp
AffineTransform.h LibGfx: Add shortcut to draw_scaled_bitmap_with_transform() for scales 2024-05-29 08:17:01 +02:00
AntiAliasingPainter.cpp
AntiAliasingPainter.h LibGfx+LibWeb: Move generally useful path methods to LibGfx 2024-06-09 14:12:06 -04:00
Bitmap.cpp LibGfx: Make non-shared Bitmap used malloc() instead of mmap() 2024-04-29 09:49:28 +02:00
Bitmap.h LibGfx: Add const overloads of Bitmap::begin() / end() 2024-05-06 17:32:19 +02:00
BitmapMixer.cpp
BitmapMixer.h
BoundingBox.h
CharacterBitmap.h
CIELAB.h
ClassicStylePainter.cpp
ClassicStylePainter.h
ClassicWindowTheme.cpp
ClassicWindowTheme.h
CMakeLists.txt LibGfx/WebP: Move some to-be-shared code to WebPSharedLossless.h 2024-05-20 13:17:34 -04:00
CMYKBitmap.cpp
CMYKBitmap.h
Color.cpp
Color.h LibGfx: Remove unused AK/SIMD.h include in Color.h 2024-07-05 00:52:30 +02:00
CornerRadius.h LibGfx+LibWeb: Move generally useful path methods to LibGfx 2024-06-09 14:12:06 -04:00
CursorParams.cpp
CursorParams.h
DeltaE.cpp
DeltaE.h
DisjointRectSet.h
EdgeFlagPathRasterizer.cpp LibGfx: Add early bounds checking to accumulate_non_zero_scanline() 2024-05-27 13:02:17 +02:00
EdgeFlagPathRasterizer.h
FontCascadeList.cpp
FontCascadeList.h
Forward.h
FourCC.h
GradientPainting.cpp
Gradients.h
GrayscaleBitmap.h
ImmutableBitmap.cpp
ImmutableBitmap.h
Line.h
Matrix.h
Matrix3x3.h
Matrix4x4.h
MedianCut.cpp LibGfx: Add an implementation of the MedianCut algorithm 2024-05-18 18:30:07 +02:00
MedianCut.h LibGfx: Add an implementation of the MedianCut algorithm 2024-05-18 18:30:07 +02:00
Orientation.h
Painter.cpp LibGfx: Add shortcut to draw_scaled_bitmap_with_transform() for scales 2024-05-29 08:17:01 +02:00
Painter.h
PaintStyle.h
Palette.cpp LibGfx: Remove unnecessary use of LibGUI in Gfx::Palette 2024-06-02 20:26:56 +02:00
Palette.h LibGfx: Remove unnecessary use of LibGUI in Gfx::Palette 2024-06-02 20:26:56 +02:00
Path.cpp LibGfx: Add Path::transform() 2024-06-10 17:41:33 -04:00
Path.h LibGfx: Add Path::transform() 2024-06-10 17:41:33 -04:00
PathClipper.cpp LibGfx+LibWeb: Move HTML::CanvasPathClipper to Gfx::PathClipper 2024-03-17 09:30:53 +01:00
PathClipper.h LibGfx+LibWeb: Move HTML::CanvasPathClipper to Gfx::PathClipper 2024-03-17 09:30:53 +01:00
Point.cpp Everywhere: Use east const in more places 2024-04-19 06:31:19 -04:00
Point.h
Quad.h LibGfx+LibWeb: Move generally useful path methods to LibGfx 2024-06-09 14:12:06 -04:00
Rect.cpp
Rect.h
ShareableBitmap.cpp LibIPC+Userland: Make IPC::File always own its file descriptor 2024-04-19 06:34:07 -04:00
ShareableBitmap.h
Size.cpp
Size.h LibCrypto+LibGfx: Fix GCC 14 compile errors 2024-04-20 15:52:29 -06:00
StandardCursor.h
StylePainter.cpp
StylePainter.h
SystemTheme.cpp
SystemTheme.h
TabPosition.h
TextAlignment.h
TextAttributes.h
TextDirection.cpp
TextDirection.h
TextElision.h
TextLayout.cpp
TextLayout.h
TextWrapping.h
TIFFGenerator.py LibGfx/TIFF: Manually check for the presence of two baseline tags 2024-05-06 17:33:25 +02:00
Triangle.cpp
Triangle.h
Vector2.h
Vector3.h
Vector4.h
VectorGraphic.cpp
VectorGraphic.h
VectorN.h
WindowTheme.cpp
WindowTheme.h