Nobody made use of the ErrorOr return value and it just added more
chance of confusion, since it was not clear if failing to sniff an
image should return an error or false. The answer was false, if you
returned Error you'd crash the ImageDecoder.
At the moment, this processes the RIFF chunk structure and extracts
the ICCP chunk, so that `icc` can now print ICC profiles embedded
in webp files. (And are image files really more than containers
of icc profiles?)
It doesn't even decode image dimensions yet.
The lossy format is a VP8 video frame. Once we get to that, we
might want to move all the image decoders into a new LibImageDecoders
that depends on both LibGfx and LibVideo. (Other newer image formats
like heic and av1f also use video frames for image data.)
The patch also contains modifications on several classes, functions or
files that are related to the `JPGLoader`.
Renaming include:
- JPGLoader{.h, .cpp}
- JPGImageDecoderPlugin
- JPGLoadingContext
- JPG_DEBUG
- decode_jpg
- FuzzJPGLoader.cpp
- Few string literals or texts
When trying to figure out the correct implementation, we now have a very
strong distinction on plugins that are well suited for sniffing, and
plugins that need a MIME type to be chosen.
Instead of having multiple calls to non-static virtual sniff methods for
each Image decoding plugin, we have 2 static methods for each
implementation:
1. The sniff method, which in contrast to the old method, gets a
ReadonlyBytes parameter and ensures we can figure out the result
with zero heap allocations for most implementations.
2. The create method, which just creates a new instance so we don't
expose the constructor to everyone anymore.
In addition to that, we have a new virtual method called initialize,
which has a per-implementation initialization pattern to actually ensure
each implementation can construct a decoder object, and then have a
correct context being applied to it for the actual decoding.
Originally I simply thought that passing file paths is quite OK, but as
Linus pointed to, it turned out that passing file paths to ensure some
files are able to be decoded is awkward because it does not work with
images being served over HTTP.
Therefore, ideally we should just use the MIME type as an optional
argument to ensure that we can always fallback to use that in case
sniffing for the correct image type has failed so we can still detect
files like with the TGA format, which has no magic bytes.
Because TGA images don't have magic bytes as a signature to be detected,
instead assume a sequence of ReadonlyBytes is a possible TGA image only
if we are given a path so we could check the extension of the file and
see if it's a TGA image.
When we know the path of the file being loaded, we will try to first
check its extension, and only if there's no match to a known decoder,
based on simple extension lookup, then we would probe for other formats
as usual with the normal sniffing method.
The spec had its first stable release today, so I figured we should
support it as well!
As usual, by using the regular LibGfx image decoder plugin architecture,
we immediately get support for it everywhere: ImageViewer, FileManager
thumbnails, PixelPaint, and (with a small change in the subsequent
commit) even the Browser :^)
To transparently support multi-frame images, all decoder plugins have
already been updated to return their only bitmap for frame(0).
This patch completes the remaining cleanup work by removing the
ImageDecoder::bitmap() API and having all clients call frame() instead.
Previously, ImageDecoder::create() would return a NonnullRefPtr and
could not "fail", although the returned decoder may be "invalid" which
you then had to check anyway.
The new interface looks like this:
static RefPtr<Gfx::ImageDecoder> try_create(ReadonlyBytes);
This simplifies ImageDecoder since it no longer has to worry about its
validity. Client code gets slightly clearer as well.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *