Commit Graph

90 Commits

Author SHA1 Message Date
Andreas Kling
681a2ac14e LibGfx: Remove support for the various "portable" image formats
These formats are not supported by other browsers.
2024-06-17 21:57:35 +02:00
Andreas Kling
7141319a7c LibGfx: Remove DDS image format support
This format is not supported by other browsers.
2024-06-17 21:57:35 +02:00
Andreas Kling
4b4254c3d0 LibGfx: Remove QOI image format support
This format is not supported by other browsers.
2024-06-17 21:57:35 +02:00
Andreas Kling
2a888ca626 LibGfx: Remove home-grown JPEG codec in favor of libjpeg-turbo 2024-06-17 17:59:54 +02:00
Andreas Kling
28d4e326f8 LibGfx: Use the woff2 library to decode WOFF2 font files
This saves us the trouble of maintaining our own implementation,
and instantly brings us to full WOFF2 feature parity with others.

Co-Authored-By: Andrew Kaster <akaster@serenityos.org>
2024-06-07 18:42:12 +02:00
Andreas Kling
04a6e2f83d LibWeb: Remove Gfx::BitmapFont
This class supported the binary bitmap font file format in SerenityOS,
and isn't something we need in Ladybird.
2024-06-04 18:45:30 +02:00
Andreas Kling
1b2d08ee7e LibGfx: Remove a bunch of unused classes 2024-06-04 18:45:30 +02:00
Nico Weber
ed2658d72c LibGfx/WebP: Move some to-be-shared code to WebPSharedLossless.h
No behavior change. No measurable performance different either.

(I tried `hyperfine 'Build/lagom/bin/image --no-output foo.webp'`
for a few input images before and after this change, and I didn't
see a difference. I also tried if moving both
Gfx::CanonicalCode::read_symbol() and
Compress::CanonicalCode::read_symbol() inline, and that didn't
help either.)
2024-05-20 13:17:34 -04:00
Lucas CHOLLET
1ba8a6f80f LibGfx: Add an implementation of the MedianCut algorithm
This is useful to find the best matching color palette from an existing
bitmap. It can be used in PixelPaint but also in encoders of old image
formats that only support indexed colors e.g. GIF.
2024-05-18 18:30:07 +02:00
Nico Weber
b6bbff5f3f LibGfx/WebPWriter: Move VP8L compression to WebPWriterLossless.{h,cpp}
* Matches how the loader is organized
* `compress_VP8L_image_data()` will grow longer when we add actual
  compression
* Maybe someone wants to write a lossy compressor one day

No behavior change.
2024-05-16 08:06:50 +02:00
Lucas CHOLLET
2513a1b83f LibGfx: Add a GIF writer
This version is really barebone as it does not support colors (only
black and white) or animated images.
2024-05-14 12:33:53 -06:00
Nico Weber
6c79efcae4 LibGfx: Move AnimationWriter to its own file
No behavior change.
2024-05-14 13:43:03 -04:00
Nico Weber
d04f9cf3c8 LibGfx+image: Add scaffolding for writing webp files 2024-05-06 17:32:19 +02:00
Nico Weber
ea441fea95 LibGfx: Move QMArithmeticDecoder to its own file
It will be used by the JPEG2000 decoder as well.

Pure code move, no behavior change.
2024-04-19 10:59:11 +02:00
Nico Weber
1ab28276f6 LibGfx: Add the start of a JPEG2000 loader
JPEG2000 is the last image format used in PDF filters that we
don't have a loader for. Let's change that.

This adds all the scaffolding, but no actual implementation yet.
2024-03-25 20:35:00 +01:00
Nico Weber
65bd090815 LibGfx/ISOBMFF: Start creating JPEG2000 box types
`isobmff` can now dump the id in a JPEG2000SignatureBox.
Creates JPEG2000Boxes.{h,cpp} to house JPEG2000 box types.
2024-03-25 20:35:00 +01:00
Shannon Booth
e800605ad3 AK+LibURL: Move AK::URL into a new URL library
This URL library ends up being a relatively fundamental base library of
the system, as LibCore depends on LibURL.

This change has two main benefits:
 * Moving AK back more towards being an agnostic library that can
   be used between the kernel and userspace. URL has never really fit
   that description - and is not used in the kernel.
 * URL _should_ depend on LibUnicode, as it needs punnycode support.
   However, it's not really possible to do this inside of AK as it can't
   depend on any external library. This change brings us a little closer
   to being able to do that, but unfortunately we aren't there quite
   yet, as the code generators depend on LibCore.
2024-03-18 14:06:28 -04:00
MacDue
6c26ff567e LibGfx+LibWeb: Move HTML::CanvasPathClipper to Gfx::PathClipper
This does not depend on anything outside of LibGfx, and seems like it
may be useful elsewhere.

No behaviour change.
2024-03-17 09:30:53 +01:00
Nico Weber
58838db445 LibGfx: Add the start of a JBIG2 loader
JBIG2 is infamous for two things:

1. It's used in xerox scanners were it falsifies scanned numbers:

https://www.dkriesel.com/en/blog/2013/0802_xerox-workcentres_are_switching_written_numbers_when_scanning

2. It was allegedly used in an iOS zero day, in a very cool way:

https://googleprojectzero.blogspot.com/2021/12/a-deep-dive-into-nso-zero-click.html

Needless to say, we need support for it in Serenity. (...because it's
used in PDF files.)

This adds all the scaffolding, but no actual implementation yet.

It's enough for `file` to print the mime type of .jb2 files, but `image`
can't do anything with the files yet.
2024-03-09 16:01:22 +01:00
Andrew Kaster
dd6f47e696 Meta: Don't search for both Python and Python3 in CMake
CMake will cache the result here, so there's no need to look for both.
2024-02-16 23:14:49 -07:00
Nico Weber
187862ebe0 LibGfx: Add a .pam loader
.pam is a "portrable arbitrarymap" as documented at
https://netpbm.sourceforge.net/doc/pam.html

It's very similar to .pbm, .pgm, and .ppm, so this uses the
PortableImageMapLoader framework. The header is slightly different,
so this has a custom header parsing function.

Also, .pam only exixts in binary form, so the ascii form support
becomes optional.
2024-01-26 07:36:53 +01:00
kleines Filmröllchen
60c3a1a77b LibGfx: Use LibRIFF for IFF parsing 2024-01-15 23:23:26 -07:00
Nico Weber
bc6eebb1d7 LibGfx: Add CMYKBitmap
This is a simple container for 2d CMYK data.

This is a new class instead of a new format in Bitmap because:
* Almost all clients of Bitmap will want to deal with RGB data
* It keeps the ARGB32 typedef working
* Bitmap already does a lot of things

The idea is that a few select places will be able to use
CMYKBitmap and a color profile to do a better CMYK -> RGB conversion
than an image decoder could do, and then store the result in a Bitmap
for later display then.

CMYKBitmap misses some of Bitmap's features, such as shared
memory support, high-dpi scaling capability, etc.
2024-01-10 09:39:00 +01:00
Andreas Kling
f900957d26 LibGfx+LibWeb: Move Gfx::ScaledFont caching from LibWeb into LibGfx
Before this change, we would only cache and reuse Gfx::ScaledFont
instances for downloaded CSS fonts.

By moving it into Gfx::VectorFont, we get caching for all vector fonts,
including local system TTFs etc.

This avoids a *lot* of style invalidations in LibWeb, since we now vend
the same Gfx::Font pointer for the same font when used repeatedly.
2023-12-26 18:15:55 +01:00
Lucas CHOLLET
64912d4d02 LibGfx/TIFF: Add support for images with CCITT3 1D compression
This compression (tag Compression=2) is not very popular on its own, but
a base to implement CCITT3 2D and CCITT4 compressions.

As the format has no real benefits, it is quite hard to find an app that
accepts tho encode that for you. So I used the following program that
calls `libtiff` directly:
```cpp
#include <vector>
#include <cstdlib>
#include <iostream>

#include <tiffio.h>

// An array containing 0 and 1 of length width * height.
extern std::vector<uint8_t> array;
int main() {
    // From: https://stackoverflow.com/a/34257789

    TIFF *image = TIFFOpen("input.tif", "w");
    int const width = 400;
    int const height = 300;
    TIFFSetField(image, TIFFTAG_IMAGEWIDTH, width);
    TIFFSetField(image, TIFFTAG_IMAGELENGTH, height);
    TIFFSetField(image, TIFFTAG_PHOTOMETRIC, 0);
    TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_CCITTRLE);

    TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 1);
    TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1);

    std::vector<uint8_t> scan_line(width / 8 + 8, 0);
    int count = 0;
    for (int i = 0; i < height; i++) {
        std::fill(scan_line.begin(), scan_line.end(), 0);
        for (int x = 0; x < width; ++x) {
            uint8_t eight_pixels = scan_line.at(x / 8);
            eight_pixels = eight_pixels << 1;
            eight_pixels |= !array.at(i * width + x);
            scan_line.at(x / 8) = eight_pixels;
        }
        int bytes = int(width / 8.0 + 0.5);
        if (TIFFWriteScanline(image, scan_line.data(), i, bytes) != 1)
            std::cerr << "Something went wrong\n";
    }

    TIFFClose(image);
}
```
2023-12-19 21:01:24 +01:00
Aliaksandr Kalenik
2cb0039a13 LibGfx+LibWeb: Produce font cascade list in CSS font matching algorithm
According to the CSS font matching algorithm specification, it is
supposed to be executed for each glyph instead of each text run, as is
currently done. This change partially implements this by having the
font matching algorithm produce a list of fonts against which each
glyph will be tested to find its suitable font.

Now, it becomes possible to have per-glyph fallback fonts: if the
needed glyph is not present in a font, we can check the subsequent
fonts in the list.
2023-12-10 17:32:04 +01:00
Nico Weber
64ffae9c55 LibGfx/ICC: Move enums to dedicated Enums.{cpp,h}
We will need to use ColorSpace in TagTypes.h, and it can't include
Profile.h.

Also makes Profile.cpp a bit smaller.

No behavior change, pure code move.
2023-12-04 08:02:36 +00:00
Lucas CHOLLET
9836a9ad0e LibGfx/TIFF: Introduce a code generator
This will allow us to generate code that handle and provide easy access
to metadata stored in TIFF's tags. The generator is a Python script, and
it output both TIFFMetadata.h and TIFFTagHandler.cpp files.

The generator will definitely need some update to support all TIFF and
EXIF tags, but that will still be easier than writing everything
ourselves.

Some small modifications are needed in TIFFLoader.cpp to make it
compatible with the new `Metadata` class.
2023-11-27 09:07:16 -07:00
Aliaksandr Kalenik
f4a5c136c3 LibGfx+LibWeb: Add ImmutableBitmap for images bitmap caching in painter
Before this change, we used Gfx::Bitmap to represent both decoded
images that are not going to be mutated and bitmaps corresponding
to canvases that could be mutated.

This change introduces a wrapper for bitmaps that are not going to be
mutated, so the painter could do caching: texture caching in the case
of GPU painter and potentially scaled bitmap caching in the case of CPU
painter.
2023-11-26 12:55:43 +01:00
Lucas CHOLLET
4ab2903e25 LibGfx/TIFF: Make TIFFLoadingContext::handle_tag be a free function
And move it to another file. This code is going to be generated soon, so
let's put it in another file.
2023-11-18 11:14:37 +00:00
Sam Atkins
dfa79ba6d8 LibGfx: Move implementation code for Tables.h into Tables.cpp 2023-11-08 09:34:09 +01:00
Lucas CHOLLET
75caccafa4 LibGfx: Add a TIFF loader 2023-11-06 12:29:30 -07:00
Nicolas Ramz
fda5590313 LibGfx/ILBM: Add an IFF-ILBM decoder :)
IFF was a generic container fileformat that was popular on the Amiga
since it was the only file format supported by Deluxe Paint.

ILBM is an image format popular in the late eighties/nineties
that uses the IFF container.

This is a very first version of the decoder that only supports
(byterun) compressed files with bpp <= 8.

Only the minimal chunks are decoded: CMAP, BODY, BMHD.

I am planning to add support for the following variants:

- EHB (32 colours + lighter 32 colours)
- HAM6 / HAM8 (special mode that allowed to display the whole Amiga
4096 colours / 262 144 colours palette)
- TrueColor (24bit)

Things that could be fun to do:

- Still images could be animated using color cycle information
2023-08-15 18:36:11 +01:00
Andreas Kling
9ba4c33940 LibGfx: Add support for WOFF2 compressed web fonts
Co-authored-by: Luke Wilde <lukew@serenityos.org>
2023-08-12 20:12:13 +02:00
Zaggy1024
66c9696687 LibGfx: Add initial ISO BMFF parsing and a utility to print file info
Currently, the `isobmff` utility will only print the media file type
info from the FileTypeBox (major brand and compatible brands), as well
as the names and sizes of top-level boxes.
2023-07-27 12:02:37 +01:00
Lucas CHOLLET
e8a63eeb0e LibGfx/JPEGXL: Add a JPEG-XL decoder :^)
JPEG-XL is a new image format standardized by the same committee as the
original JPEG image format. It has all the nice feature of recent
formats, and great compression ratios. For more details, look at:
https://jpegxl.info/

This decoder is far from being feature-complete, as it features a grand
total of 60 FIXMEs and TODOs but anyway, it's still a good start.

I developed this decoder in the Serenity way, I just try to decode a
specific image while staying as close as possible to the specification.

Considering that the format supports a lot of options, and that we
basically support only one possibility for each of them, I'm pretty sure
that we can only decode the image I've developed this decoder for.

Which is:
0aff 3ffa 9101 0688 0001 004c 384b bc41
5ced 86e5 2a19 0696 03e5 4920 8038 000b
2023-07-21 10:47:34 -06:00
MacDue
16b487c270 LibGfx: Add simple VectorGraphic abstract base class
This is currently very bare-bones with just the size and a few methods
to rasterize/draw the graphic.
2023-07-14 06:51:05 +02:00
MacDue
e1cf868e6e LibGfx: Use AntiAliasingPainter::fill_path() for drawing font glyphs
Using the general AA painter fill_path() is indistinguishable from the
previous rasterizer, so this switch simply allows us to share more code.
2023-07-10 20:56:25 +02:00
MacDue
ae18186905 LibGfx: Implement image decoder for TinyVG (.tvg)
This adds a decoder for the TinyVG vector format (https://tinyvg.tech/).
TinyVG is a very simple binary vector format, but it is good enough to
represent a lot of SVGs, without needing the full web engine.

The main use case for Serenity is for scalable icons (which .tvg easily
handles).
2023-07-03 23:54:51 +02:00
Lucas CHOLLET
226b214142 LibGfx/JPEG: Add a JPEG encoder :^)
This encoder is very naive as it only output SOF0 images and uses
pre-defined Huffman tables.

There is also a small bug with quantization which make using it
over-degrade the quality.
2023-06-22 21:13:04 +02:00
MacDue
48fa8f97d3 LibGfx: Implement new antialiased filled path rasterizer
This is an implementation of the scanline edge-flag algorithm for
antialiased path filling described here:
https://mlab.taik.fi/~kkallio/antialiasing/EdgeFlagAA.pdf

The initial implementation does not try to implement every possible
optimization in favour of keeping things simple. However, it does
support:

   - Both evenodd and nonzero fill rules
   - Applying paint styles/gradients
   - A range of samples per pixel (8, 16, 32)
   - Very nice antialiasing :^)

This replaces the previous path filling code, that only really applied
antialiasing in the x-axis.

There's some very nice improvements around the web with this change,
especially for small icons. Strokes are still a bit wonky, as they don't
yet use this rasterizer, but I think it should be possible to convert
them to do so.
2023-06-01 06:25:00 +02:00
Nico Weber
fbc53c1ec3 LibGfx+LibVideo: Move VP9/BooleanDecoder to LibGfx/ImageFormats
...and keep a forwarding header around in VP9, so we don't have to
update all references to the class there.

In time, we probably want to merge LibGfx/ImageDecoders and LibVideo
into LibMedia, but for now I need just this class for the lossy
webp decoder. So move just it over.

No behvior change.
2023-05-27 05:47:42 +02:00
Nico Weber
bc207fd0a0 LibGfx/WebP: Move lossy decoder to its own file
Pure code move (except of removing `static` on the two public functions
in the new header), not behavior change.

There isn't a lot of lossy decoder yet, but it'll make implementing it
more convenient.

No behavior change.
2023-05-09 06:35:56 +02:00
Nico Weber
65c7145e69 LibGfx/WebP: Move lossless decoder to its own file
Pure code move (except of removing `static` on the two public functions
in the new header), not behavior change.
2023-05-08 12:52:05 +02:00
Nico Weber
923027b1df LibGfx: Add DeltaE() function 2023-04-30 05:57:20 +02:00
Lucas CHOLLET
496b7ffb2b LibGfx: Move all image loaders and writers to a subdirectory 2023-03-21 22:39:25 +01:00
Cameron Youell
1d24f394c6 Everywhere: Use LibFileSystem where trivial 2023-03-21 19:03:21 +00:00
Lucas CHOLLET
9c9bd271c8 LibGfx/PortableFormat: Add PortableFormatWriter
Currently, the encoder only output ppm files, but it can easily be
extended to support both PBM and PGM.
2023-03-13 15:15:41 +00:00
MacDue
a425b6f772 LibGfx: Make all fill_path() code member functions and move into .cpp
This makes all the code for fill_path() member functions of the painter,
and moves them into a new FillPathImplementation.cpp. This allows us
to avoid polluting Painter.h with implementation details, and makes
the edit, compile, retry loop much shorter.
2023-03-11 18:34:26 +00:00
Nico Weber
0ba532e14e LibGfx: Add a function to create an in-memory sRGB profile
This might be useful for converting data from arbitrary profiles to
sRGB.

For now, this only encodes the transfer function and puts in zero values
for chromaticities, whitepoint, and chromatic adaptation matrix.
This makes the profile unusable for now. But I've spent a very long time
reading things and need to check in some code, and it's some progress.

The encoded transfer function exactly matches the one in GIMP's built-in
sRGB ICC profile (but not the Compact-ICC-Profiles v4 one or the
RawTherapee v4 one -- I'll add a comment about why later.)
2023-03-04 21:38:47 +00:00