1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-10 12:07:35 +00:00
Commit graph

1969 commits

Author SHA1 Message Date
Nico Weber
5ff2a824cc LibGfx/ICC: Move MatrixMatrixConversion::map() inline
According to ministat, a bit faster to render page 3 of 0000849.pdf:

```
    N           Min           Max        Median         Avg       Stddev
x  50      1.000875     1.0427601     1.0208509   1.0201902   0.01066116
+  50    0.99707389       1.03614     1.0084391   1.0107864  0.010002724
Difference at 95.0% confidence
	-0.00940384 +/- 0.0041018
	-0.921773% +/- 0.402062%
	(Student's t, pooled s = 0.0103372)
```
2024-01-12 12:37:56 +00:00
Nico Weber
4704e6aa5f LibGfx/ICC: Refactor matrix/matrix conversion code a bit
No behavior change; the goal is to make it usable by LibPDF too.
2024-01-12 09:09:56 +01:00
Nico Weber
2fc6ec0f46 LibGfx/ICC: Fastpath for matrix->matrix image conversions
Doesn't help with PDF at all since that doesn't call convert_image()
(-‸ლ)
2024-01-12 09:09:56 +01:00
Nico Weber
89315787ae LibGfx/ICC: Cache presence of various tags
Reduces time spent rendering page 3 of 0000849.pdf from 1.45s to 1.32s
on my machine.

Also reduces the time to run Meta/test_pdf.py on 0000.zip
(without 0000849.pdf) from 58s to 55s.
2024-01-11 08:15:22 +00:00
Nico Weber
3365a92ead LibGfx/ICC: Cache inverted matrix on profile
Reduces time spent rendering page 3 of 0000849.pdf from 1.85s to 1.45s
on my machine.

As determined by running

    time Build/lagom/bin/pdf --page 3 --render out.png \
        ~/Downloads/0000/0000849.pdf

a few times and eyeballing the min time.

Also reduces the time to run Meta/test_pdf.py on 0000.zip
(without 0000849.pdf) from 1m7s to 58s.
2024-01-11 08:15:22 +00:00
Nico Weber
19d434b229 LibGfx/ICC: Extract matrix computation functions
No behavior (or perf) change.
2024-01-11 08:15:22 +00:00
Nico Weber
5c5a24c6b7 LibGfx/ICC: Move some Profile member vars up a bit
...so that they're not below a FIXME that doesn't apply to them.

No behavior change.
2024-01-11 08:15:22 +00:00
Nicolas Ramz
1593ff2d4c LibGfx/ILBMLoader: Don't throw too early when decoding bitplanes
We were (again) throwing even though the image could be decoded.
2024-01-10 23:41:15 +01:00
Lucas CHOLLET
f6b86096a5 LibGfx/TIFF: Prevent the CCITT decoder to run on non bilevel image 2024-01-10 23:34:44 +01:00
Lucas CHOLLET
0ef449a588 LibGfx/TIFF: Don't crash on invalid indices inside RGBPalette images
We were previously accessing a Vector's element using a user-provided
value as index input.
2024-01-10 23:34:44 +01:00
Lucas CHOLLET
58bdca96cd LibGfx/TIFF: Use a wider type for palette indices to prevent overflow
We refuse any image with a sample depth greater than 32, storing these
value as `u64` prevent any overflows. This is probably overkill as no
one in their right mind will use a 32 bits color table.
2024-01-10 23:34:44 +01:00
Lucas CHOLLET
4d1c99e414 LibGfx/TIFF: Don't crash on RGBPalette images without a ColorMap 2024-01-10 23:34:44 +01:00
Lucas CHOLLET
25c3f8cd8e LibGfx/TIFF: Prefer a verbal form over a noun 2024-01-10 23:34:44 +01:00
Nico Weber
d8ada20bae LibGfx: Allow images to report that they are originally grayscale
...and implement it in JPEGLoader.

Since it's easy to get the grayscale data off a Bitmap, don't
add a grayscale_frame() accessor.
2024-01-10 09:39:00 +01:00
Nico Weber
239da5132d LibGfx/JPEG: Make it possible to obtain raw CMYK data from JPEGs
frame() still returns a regular RGB Bitmap (now lazily converted
from internal CMYK data), but JPEGImageDecoderPlugin now also
implements cmyk_frame().
2024-01-10 09:39:00 +01:00
Nico Weber
51d5397e92 LibGfx: Give ImageDecoder an API for getting raw CMYK data
frame() still returns a regular RGB Bitmap, but it's possible to also
get at raw CMYK data instead if desired, for image formats that can
store that.
2024-01-10 09:39:00 +01: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
Nico Weber
c997ee7b9d LibGfx+ImageViewer: Replace ImageDecoder::is_vector() with an enum
That makes it easier to extend to other special frame formats.
2024-01-10 09:39:00 +01:00
Nico Weber
7fb32b6682 LibGfx: Fix off-by-some in Painter::draw_scaled_bitmap_with_transform()
Before this, drawing a 1x1 bitmap scaled up to MxN would only fill
M/2 x N/2 pixel, due to source_point going outside (0, 0).
2024-01-10 09:38:13 +01:00
Nicolas Ramz
5e7e98cd3c LibGfx/ILBMLoader: Add support for transparent color 2024-01-08 07:21:27 -07:00
Nicolas Ramz
fc5b6e4dda LiGfx/ILBMLoader: Don't throw if malformed bitplane can be decoded
Some apps seem to generate malformed images that are accepted
by most readers. We now only throw if malformed data would lead to
a write outside the chunky buffer.
2024-01-08 07:21:27 -07:00
MacDue
9c3bb94d14 LibGfx: Trim scanline to right clip in path rasterizer
There's no need to accumulate past the right clip, so we also don't need
to store it.
2024-01-08 09:26:43 +01:00
MacDue
ec93973158 LibGfx: Sprinkle some FLATTEN/hot attributes in the path rasterizer
This seems to actually improve performance to the tune of about +5 fps.
2024-01-08 09:26:43 +01:00
MacDue
e2152a5b3d LibGfx: Clip path rasterizer scanlines sooner
This moves the clipping from per-pixel/draw command to a step before
the main drawing/plotting loop.
2024-01-08 09:26:43 +01:00
MacDue
b1adabdac4 LibGfx: Fix off-by-one in path rasterizer
The start/end is inclusive so it's + 1 to the start to fill
`full_converage_count` pixels.
2024-01-08 09:26:43 +01:00
MacDue
13a4fb0325 LibGfx: Increase bezier splitting tolerance to 0.5
No noticeable difference a bit faster. This is still arbitrary and
should be somehow derived from the curve.
2024-01-08 09:26:43 +01:00
MacDue
65b87bace9 LibGfx: Move Gfx::color_for_format() to header 2024-01-08 09:26:43 +01:00
MacDue
a1bafafd78 LibGfx: Slightly simplify Color::blend()
No behaviour change.
2024-01-08 09:26:43 +01:00
Aliaksandr Kalenik
5c02b960ab LibGfx: Take into account unicode ranges to find font for space glyph
Instead of assuming that the first font in the cascade font list will
have a glyph for space, we need to find it in the list taking into
account unicode ranges.
2024-01-08 01:00:24 +01:00
Lucas CHOLLET
335097e446 LibGfx/TIFF: Modify the image according to the Orientation tag
Let's use the already existing logic (ExifOrientedBitmap) to modify the
bitmap to honor the orientation tag.
2024-01-08 00:07:44 +01:00
Lucas CHOLLET
367882ae23 LibGfx: Make ExifOrientedBitmap::oriented_size be public
This will be useful for image decoders to expose the image size while
considering the orientation. A rotated image might have different
dimensions.
2024-01-08 00:07:44 +01:00
Lucas CHOLLET
34e9059ae8 LibGfx/TIFF: Honor the default value for single count tags
Some tags have a default value, we should return this value in
Metadata's getters when no value has been read from the input file.

Note that we don't support default values for tags with a count bigger
than one.
2024-01-08 00:07:44 +01:00
Lucas CHOLLET
ef10a58522 LibGfx: Remove ExifOrientedBitmap::Orientation in favor of TIFF's enum
ExifOrientedBitmap was implemented before the introduction of the TIFF
decoder. So we had to provide a definition of the Orientation enum. Now
that we have a TIFF implementation that comes with some enum
definitions, we should prefer this source.
2024-01-08 00:07:44 +01:00
Lucas CHOLLET
402de2985d LibGfx/ICO: Do not try to decode a mask if we already reached EOF
When using the BMP encoding, ICO images are expected to contain a 1-bit
mask for transparency. Regardless an alpha channel is already included
in the image, the mask is always required. As stated here[1], the
mask is used to provide shadow around the image.

Unfortunately, it seems that some encoder do not include that second
transparency mask. So let's read that mask only if some data is still
remaining after decoding the image.

The test case has been generated by truncating the 64 last bytes
(originally dedicated to the mask) from the `serenity.ico` file and
changing the declared size of the image in the ICO header. The size
value is stored at the offset 0x0E in the file and I changed the value
from 0x0468 to 0x0428.

[1]: https://devblogs.microsoft.com/oldnewthing/20101021-00/?p=12483
2024-01-07 12:32:02 -05:00
Nico Weber
701d56f7ad LibGfx/ICC: Implement LutBToATagData::evaluate() when there is no CLUT
This is enough to make these work:

    for f in VideoHD VideoNTSC VideoPAL; do
        Build/lagom/bin/icc --debug-roundtrip \
            ~/Downloads/Adobe\ ICC\ Profiles\ \(end-user\)/RGB/$f.icc
    done

It's also possible to convert images to those color spaces:

    Build/lagom/bin/image -o image-pal.png \
        --convert-to-color-profile path/to/RGB/VideoPAL.icc \
        image-srgb.png

(If there's no png file with an embedded sRGB profile at hand, do first:

    Build/lagom/bin/icc --reencode-to serenity-sRGB.icc -n sRGB
    Build/lagom/bin/image -o image-srgb.png \
        --assign-color-profile serenity-sRGB.icc image-no-color-space.png

)

In color-managed viewers, images-srgb.png and image-pal.png should
look identical.

But if you either explicitly assign the sRGB profile to the pal
image, or strip the embedded color space, they'll look different
(since image viewers then assume the image in the VideoPAL space
is in sRGB):

    Build/lagom/bin/image -o image-pal-strip.png --strip-color-profile \
        image-pal.png

    Build/lagom/bin/image -o image-not-actually-srgb.png \
        --assign-color-profile serenity-sRGB.icc image-pal.png
2024-01-07 15:42:35 +01:00
Nico Weber
a75533b46b LibGfx/ICC: Add a trailing , to an initialization
No behavior change.
2024-01-07 15:42:35 +01:00
Nico Weber
d17e8d1654 LibGfx/ICC: Plumb mBA conversion from profile to tag data
It's still implemented on the tag data side, so no real
behavior change.
2024-01-07 15:42:35 +01:00
Andreas Kling
d26ad8450f LibGfx/OpenType: Read the correct number of pairs from kern table
We were trying to read exactly 5 pairs for some reason, instead of the
number specified by the format 0 header.

Fixing this makes "OpenSans Condensed" load on my machine.
2024-01-06 23:22:52 +01:00
Lucas CHOLLET
52ce887b80 LibGfx/JPEG: Introduce a struct to hold sampling factors 2024-01-06 09:08:59 +00:00
Lucas CHOLLET
6c85f937ef LibGfx/JPEG: Print debug information on subsampling for each component 2024-01-06 09:08:59 +00:00
Lucas CHOLLET
145672a8b4 LibGfx/JPEG: Print some debug information about restart markers 2024-01-06 09:08:59 +00:00
Andreas Kling
c4d75ac11a LibGfx/GIF: Avoid a silly loop in GIF logical screen parsing 2024-01-05 13:20:00 +01:00
Andreas Kling
182a2b0c3a LibGfx/GIF: Only parse global color table if header flag is set
This fixes an issue where GIF images without a global color table would
have the first segment incorrectly interpreted as color table data.

Makes many more screenshots appear on https://virtuallyfun.com/ :^)
2024-01-05 13:20:00 +01:00
Lucas CHOLLET
b8cbc282f3 LibGfx/TIFF: Don't stop decoding when failing to decode a tag
TIFF files are made in a way that make them easily extendable and over
the years people have made sure to exploit that. In other words, it's
easy to find images with non-standard tags. Instead of returning an
error for that, let's skip them.

Note that we need to make sure to realign the reading head in the file.

The test case was originally a 10x10 checkerboard image with required
tags, and also the `DocumentName` tag. Then, I modified this tag in a
hexadecimal editor and replaced its id with 30 000 (0x3075 as a LE u16)
and the type with the same value as well. This is AFAIK, never used as
a custom TIFF tag, so this should remain an invalid tag id and type.
2024-01-04 14:27:16 +01:00
Nico Weber
fa24fbf120 LibGfx/OpenType: Survive simple glyphs with 0 contours
These are valid per spec, and do sometimes occur in practice, e.g.
in embedded fonts in 0000550.pdf and 0000246.pdf in 0000.zip in the
PDFA test set.
2024-01-04 03:32:46 +01:00
MacDue
b4eb66d9fe LibGfx: Simplify condition
This is just an XOR. No behaviour change.
2024-01-03 12:56:01 +01:00
MacDue
db51e80d50 LibGfx: Fix typo 2024-01-03 12:56:01 +01:00
MacDue
a9502396ee LibGfx: Remove somewhat outdated comment
Most of these optimizations have been tried now, so this comment is a
bit misleading.
2024-01-03 12:56:01 +01:00
MacDue
096bdb142b LibGfx: Speed up filling solid colors in path rasterizer
For solid color fills (with alpha = 255), the rasterizer now tracks
spans of solid colors within a scanline and fills the entire span with
a single call to fast_u32_fill().

This gave up to a 1.5x speedup drawing the Ghostscript Tiger within
SerenityOS.
2024-01-03 12:56:01 +01:00
MacDue
2fa488cfa9 LibGfx: Skip horizontal edges in path rasterizer
Only the vertical parts of edges are plotted (then accumulated
horizontally). Fully horizontal edges won't be plotted (and just result
in NaNs).
2024-01-03 12:56:01 +01:00