1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-20 13:45:06 +00:00
Commit graph

32 commits

Author SHA1 Message Date
Nico Weber
92852b8477 LibGfx/ICC: Move MatrixMatrixConversion curve type check to ctor
A bit faster:

```
    N           Min           Max        Median         Avg       Stddev
x  50    0.97179127     1.0031381    0.98313618  0.98407591 0.0092019442
+  50    0.95996714    0.99507213    0.96965885  0.97242294 0.0095455053
Difference at 95.0% confidence
	-0.011653 +/- 0.00372012
	-1.18415% +/- 0.378032%
	(Student's t, pooled s = 0.0093753)
```
2024-01-12 12:37:56 +00:00
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
Nico Weber
b2a1130556 LibGfx/ICC: Implement conversion between different connection spaces
If one profile uses PCSXYZ and the other PCSLAB as connection space,
we now do the necessary XYZ/LAB conversion.

With this and the previous commits, we can now convert from profiles
that use PCSLAB with mAB, such as stress.jpeg from
https://littlecms.com/blog/2020/09/09/browser-check/ :

    % Build/lagom/icc --name sRGB --reencode-to serenity-sRGB.icc
    % Build/lagom/bin/image -o out.png \
        --convert-to-color-profile serenity-sRGB.icc \
        ~/src/jpegfiles/stress.jpeg
2023-12-04 08:02:36 +00: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
Sam Atkins
835dada3d3 LibGfx: Add method to get String data from an ICC Profile tag 2023-07-20 08:02:12 +01:00
Sam Atkins
1066831b39 LibGfx: Add a method to get a specific tag from an ICC Profile 2023-07-20 08:02:12 +01:00
Nico Weber
0079fad785 ICC: Prepare for eventually implementing conversions for LUT profiles
No behavior change yet (except for more detailed "not yet implemented"
messages), but it prepares for eventually implementing some of this.
2023-05-04 16:11:07 +02:00
Nico Weber
926c0d8676 ICC+image: Add conversion between color spaces for images :^)
For now, only for color spaces that are supported by Profile::to_pcs()
and Profile::from_pcs(), which currently means that all matrix profiles
(but not LUT profiles) in the source color space work, and that
matrix profiles with parametric curves in the destination color
space work.

This adds Profile::convert_image(Bitmap, source_profile), and
adds a `--convert-to-color-profile file.icc` flag to `image`.

It only takes a file path, so to use it with the built-in
sRGB profile, you have to write it to a file first:

% Build/lagom/icc -n sRGB --reencode-to serenity-sRGB.icc

`image` by default writes the source image's color profile
to the output image, and most image viewers display images
looking at the profile.

For example, take `Seven_Coloured_Pencils_(rg-switch_sRGB).jpg`
from https://commons.wikimedia.org/wiki/User:Colin/BrowserTest.

It looks normal in image viewers because they apply the unusual
profile embedded in the profile. But if you run

% Build/lagom/image -o huh.png --strip-color-profile \
    'Seven_Coloured_Pencils_(rg-switch_sRGB).jpeg'

and then look at huh.png, you can see how the image's colors
look like when interpreted as sRGB (which is the color space
PNG data is in if the PNG doesn't store an embedded profile).

If you now run

% Build/lagom/image -o wow.png \
    --convert-to-color-profile serenity-sRGB.icc --strip-color-profile \
    'Seven_Coloured_Pencils_(rg-switch_sRGB).jpeg'

this will convert that image to sRGB, but then not write
the profile to the output image (verify with `Build/lagom/icc wow.png`).
It will look correct in image viewers, since they display PNGs without
an embedded color profile as sRGB.

(This works because 'Seven_Coloured_Pencils_(rg-switch_sRGB).jpeg'
contains a matrix profile, and Serenity's built-in sRGB profile
uses a matrix profile with a parametric curve.)
2023-05-03 15:05:13 +02:00
Nico Weber
4169c94ebe ICC: Implement some of Profile::from_pcs()
This implements conversion from profile connection space to the
device-dependent color for matrix-based profiles.

It only does the inverse color transform but does not yet do the
inverse tone reproduction curve transform -- i.e. it doesn't
implement many cases (LUT transforms), and it does the one thing
it does implement incorrectly. But to vindicate the commit a bit,
it also does the incorrect thing very inefficiently.
2023-05-02 17:15:48 +01:00
Nico Weber
8ab6e0d3a5 ICC: Mark Profile::to_pcs() and to_lab() const 2023-04-30 05:57:20 +02:00
Nico Weber
adec1abf81 LibGfx: Move CIELAB to its own file 2023-04-30 05:57:20 +02:00
Nico Weber
f3dbfb85d9 ICC: Add Profile::to_lab()
This can be used to convert a profile-dependent color to the L*a*b*
color space.

(I'd like to use this to implement the DeltaE (CIE 2000) algorithm,
which is a metric for how similar two colors are perceived.
(And I'd like to use that to evaluate color conversion roundtrip
quality, once I've implemented full conversions.)
2023-04-30 00:46:11 +02:00
Nico Weber
af453b246a ICC: Add method to convert a color to the profile connection space
Only implemented for matrix profiles so far.

This API won't be fast enough to color manage images, but let's
get something working before getting something fast.
2023-04-29 06:49:36 +02:00
Nico Weber
e76d2238bb ICC: Make number_of_components_in_color_space() external
...and make its return type unsigned.
2023-04-29 06:49:36 +02:00
Nico Weber
8f415e7b21 LibGfx: Introduce ICC::Profile::create
This can be used to programmatically create ICC::Profile objects.
2023-03-04 21:38:47 +00:00
Nico Weber
8179327068 LibGfx: Add fallible ICC::Profile::try_for_each_tag
Similar to 13b18a1 or d0f3f3d.
2023-02-19 23:46:36 +01:00
Nico Weber
1457e36b79 LibGfx: Write ICC tag table
All offsets and sizes are set to 0 for now, so this still doesn't
produce a valid icc file. It gets closer, though.
2023-02-19 00:01:44 +01:00
Nico Weber
e8a2c17f8f LibGfx: Add an accessor for the raw ICC Version minor_and_bugfix byte
This is makes it easier to write this value back out.
2023-02-17 20:05:50 -07:00
Nico Weber
78d849bce2 LibGfx: Make ICCHeader use RenderingIntent enum
No behavior change.
2023-02-17 20:05:50 -07:00
Nico Weber
9ba3c8e36d LibGfx: Move ICC::Profile towards "Fallible Constructors" pattern
Not quite there yet due to check_required_tags() / check_tag_types(),
but getting closer :^)
2023-02-15 10:15:24 +01:00
Nico Weber
db614b47dd LibGfx: Move ICC::Profile::read_header() out of class
This one is slightly more involved: To make it nice, extract
all the Profile fields that belong to the header into a separate
struct.
2023-02-15 10:15:24 +01:00
Nico Weber
272e5321e3 LibGfx: Move ICC::Profile::read_tag_table() out of class 2023-02-15 10:15:24 +01:00
Nico Weber
006dff6878 LibGfx: Move ICC::Profile::read_tag() out of class 2023-02-15 10:15:24 +01:00
Nico Weber
b5deccf859 LibGfx: Split ICC/Profile.{h,cpp} into several files
s15Fixed16Number and XYZNumber are somewhat awkwardly duplicated
in both Profile.cpp and TagTypes.cpp. Other than that, this is a
pure code move.

No behavior change.
2023-01-28 00:27:07 +00:00
Nico Weber
6d51d8ad32 LibGfx: Bump copyright year in ICC/Profile.{h,cpp} 2023-01-28 00:27:07 +00:00
Nico Weber
721b280849 LibGfx: Move ICCProfile.{h,cpp} to ICC/Profile.{h,cpp} 2023-01-28 00:27:07 +00:00
Renamed from Userland/Libraries/LibGfx/ICCProfile.h (Browse further)