We essentially just end up moving `release_value_but_fixme_...` one
layer down, but it makes adding more fallible operations in the
serialization function more comfortable.
This is useful in general (I'd imagine), but in particular having this
will allow us to implement accented PDF Type1 Font glyphs, which consist
of two separate glyphs that are composed into a single one.
Functionality for checking image size in advance has been removed, as
this would require a SeekableStream and we now check for read errors
everywhere anyways.
This is a very new tag used for HDR content. The only files I know that
use it are the jpegs on https://ccameron-chromium.github.io/hdr-jpeg/
But they have an invalid ICC creation date, so `icc` can't process them.
(Commenting out the check for that does allow to print them.)
If the CIPC tag is present, it takes precedence about the actual data
in the profile and from what I understand, the ICC profile is
basically ignored. See https://www.color.org/events/HDR_experts.xalter
for background, in particular
https://www.color.org/hdr/02-Luke_Wallis.pdf (but the other talks
are very interesting too).
(PNG also has a cICP chunk that's supposed to take precedence over
iCCP.)
This isn't used by any mandatory tags, and it's not terribly useful.
But jpegs exported by Lightroom Classic write the 'tech' tag, and
it seems nice to be able to dump its contents.
signatureType stores a single u32 which for different tags with this
type means different things.
In each case, the value is one from a short table of valid values,
suggesting this should be a per-tag enum class instead of a
per-tag DistinctFourCC, per the comment at the top of DistincFourCC.h.
On the other hand, 3 of the 4 tables have an explicit "It is possible
that the ICC will define other signature values in the future" note,
which suggests the FourCC might actually be the way to go.
For now, just punt on that and manually dump the u32 in fourcc style
in icc.cpp and don't add any to_string() methods that return a readable
string based on the contents of these tables.
This is the type of namedColor2Tag, which is a required tag in
NamedColor profiles.
The implementation is pretty basic for now and only exposes the
numbers stored in the file directly (after endian conversion).
ICC::Profile deletes these objects via base class pointers, so this
is needed that destructors in the subclasses get called.
(Found by asan on CI when adding test coverage.)
This patch adds a "GlyphPage" cache which stores the mapping between
code points and glyph IDs in a segmented table of "pages".
This makes Font::glyph_id_for_code_point() significantly faster by
not reparsing the font tables every time you call it.
In the future, we can add more information to GlyphPage (such as
horizontal metrics for each glyph) to further reduce time spent in
text layout and painting.
`Stream` will be qualified as `AK::Stream` until we remove the
`Core::Stream` namespace. `IODevice` now reuses the `SeekMode` that is
defined by `SeekableStream`, since defining its own would require us to
qualify it with `AK::SeekMode` everywhere.
Most jpegs that use multi-tag ICCs are in CMYK format, so running
`icc` on them still produces
Runtime error: Unsupported number of components in SOF
but it no longer prints several
jpg: Ignoring ICC profile spanning several chunks (1/9)
lines before that.
(And if I manually comment out that error message, the profile
is printed fine. But we can't decode the actual pixel data yet.)
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.
This probably won't be the final API for getting color spaces
from images, since some formats just store an "is sRGB?" flag
instead of a full profile. Instead, once everything works,
we probably want to give every Bitmap a pointer to some
color space abstraction.
But we can always change this later, once things are further along
and better understood.
As the different Cmap encoding records are guaranteed to be sorted by
their platform ID, we would previously prefer the Macintosh platform
because of its lower ID value. However, this platform is split up into
a lot of encoding formats for different languages, and usually only
English is included. This meant that we could not handle most unicode
characters anymore.
The Windows platform now takes precedence again, as it can handle
arbitrary code points in its supported encodings.
This solution is still far from perfect, but it makes this regression
disappear for now.
Add a targeted quirk for the one known file where this is violated.
Adding that quirk is a bit of a bummer, since that means all client
code of this class now needs to deal with the possibility that
'cprt' and 'desc' aren't 'mluc' for v4 files. But if that code wants
to handle v2 files, it needs to deal with that anyways, so it's
really just a bit of a bummer and not more.
This adds checking for all tags where ICCProfile can parse the type.
Over time, more of this needs implementing -- at least lut8Type,
lut16Type, lutAToBType, and lutBToAType, since these are used by
required tags.
What _is_ checked for the most part matches the spec, but it's possible
that the spec text is aspirational and that profiles in the wild don't
fully match it.
I've run the current checks against these profiles:
find \
~/src/Compact-ICC-Profiles \
/{System/,}Library/ColorSync \
-name '*.icc' \
-exec echo {} \; \
-exec Build/lagom/icc {} \;
...and against 3 hand-selected icc files I locally extracted from jpegs.
This identified 3 cases where the spec text is too strict for reality.
I added comments for these for now. Eventually, I'd like to try to still
enforce these types, and have a profile-id-based quirks list for which
they aren't enforced. It's possible that that won't be feasible, but
it's probably better to start out to strict and then relax over time
than the other way round.
This patch adds the following some convenience functions:
- Lines do now support rotated(), scaled() and translated()
- AntiAliasingPainter has now a draw_line function that takes a
FloatLine as argument