mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibGfx+icc: Read cicpType
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 commit is contained in:
parent
a434b89521
commit
e8bbb3d915
Notes:
sideshowbarker
2024-07-17 04:41:05 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/e8bbb3d915 Pull-request: https://github.com/SerenityOS/serenity/pull/17369 Reviewed-by: https://github.com/Zaggy1024 Reviewed-by: https://github.com/linusg
5 changed files with 64 additions and 2 deletions
|
@ -572,6 +572,8 @@ ErrorOr<NonnullRefPtr<TagData>> Profile::read_tag(ReadonlyBytes bytes, u32 offse
|
|||
|
||||
auto type = tag_type(tag_bytes);
|
||||
switch (type) {
|
||||
case CicpTagData::Type:
|
||||
return CicpTagData::from_bytes(tag_bytes, offset_to_beginning_of_tag_data_element, size_of_tag_data_element);
|
||||
case CurveTagData::Type:
|
||||
return CurveTagData::from_bytes(tag_bytes, offset_to_beginning_of_tag_data_element, size_of_tag_data_element);
|
||||
case Lut16TagData::Type:
|
||||
|
|
|
@ -57,6 +57,23 @@ TagTypeSignature tag_type(ReadonlyBytes tag_bytes)
|
|||
return *bit_cast<BigEndian<TagTypeSignature> const*>(tag_bytes.data());
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<CicpTagData>> CicpTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||
{
|
||||
// ICC v4, 10.3 cicpType
|
||||
VERIFY(tag_type(bytes) == Type);
|
||||
TRY(check_reserved(bytes));
|
||||
|
||||
if (bytes.size() < 2 * sizeof(u32) + 4 * sizeof(u8))
|
||||
return Error::from_string_literal("ICC::Profile: cicpType has not enough data");
|
||||
|
||||
u8 color_primaries = bytes[8];
|
||||
u8 transfer_characteristics = bytes[9];
|
||||
u8 matrix_coefficients = bytes[10];
|
||||
u8 video_full_range_flag = bytes[11];
|
||||
|
||||
return adopt_ref(*new CicpTagData(offset, size, color_primaries, transfer_characteristics, matrix_coefficients, video_full_range_flag));
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<CurveTagData>> CurveTagData::from_bytes(ReadonlyBytes bytes, u32 offset, u32 size)
|
||||
{
|
||||
// ICC v4, 10.6 curveType
|
||||
|
|
|
@ -58,6 +58,39 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// ICC v4, 10.3 cicpType
|
||||
// "The cicpType specifies Coding-independent code points for video signal type identification."
|
||||
// See presentations at https://www.color.org/events/HDR_experts.xalter for background.
|
||||
class CicpTagData : public TagData {
|
||||
public:
|
||||
static constexpr TagTypeSignature Type { 0x63696370 }; // 'cicp'
|
||||
|
||||
static ErrorOr<NonnullRefPtr<CicpTagData>> from_bytes(ReadonlyBytes, u32 offset, u32 size);
|
||||
|
||||
CicpTagData(u32 offset, u32 size, u8 color_primaries, u8 transfer_characteristics, u8 matrix_coefficients, u8 video_full_range_flag)
|
||||
: TagData(offset, size, Type)
|
||||
, m_color_primaries(color_primaries)
|
||||
, m_transfer_characteristics(transfer_characteristics)
|
||||
, m_matrix_coefficients(matrix_coefficients)
|
||||
, m_video_full_range_flag(video_full_range_flag)
|
||||
{
|
||||
}
|
||||
|
||||
// "The fields ColourPrimaries, TransferCharacteristics, MatrixCoefficients, and VideoFullRangeFlag shall be
|
||||
// encoded as specified in Recommendation ITU-T H.273. Recommendation ITU-T H.273 (ISO/IEC 23091-2)
|
||||
// provides detailed descriptions of the code values and their interpretation."
|
||||
u8 color_primaries() const { return m_color_primaries; }
|
||||
u8 transfer_characteristics() const { return m_transfer_characteristics; }
|
||||
u8 matrix_coefficients() const { return m_matrix_coefficients; }
|
||||
u8 video_full_range_flag() const { return m_video_full_range_flag; }
|
||||
|
||||
private:
|
||||
u8 m_color_primaries;
|
||||
u8 m_transfer_characteristics;
|
||||
u8 m_matrix_coefficients;
|
||||
u8 m_video_full_range_flag;
|
||||
};
|
||||
|
||||
// ICC v4, 10.6 curveType
|
||||
class CurveTagData : public TagData {
|
||||
public:
|
||||
|
|
|
@ -94,7 +94,7 @@ target_link_libraries(grep PRIVATE LibRegex)
|
|||
target_link_libraries(gunzip PRIVATE LibCompress)
|
||||
target_link_libraries(gzip PRIVATE LibCompress)
|
||||
target_link_libraries(headless-browser PRIVATE LibCrypto LibGemini LibGfx LibHTTP LibTLS LibWeb LibWebSocket LibIPC LibJS)
|
||||
target_link_libraries(icc PRIVATE LibGfx)
|
||||
target_link_libraries(icc PRIVATE LibGfx LibVideo)
|
||||
target_link_libraries(image2bin PRIVATE LibGfx)
|
||||
target_link_libraries(jail-attach PRIVATE LibCore LibMain)
|
||||
target_link_libraries(jail-create PRIVATE LibCore LibMain)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <LibGfx/ICC/Profile.h>
|
||||
#include <LibGfx/ICC/Tags.h>
|
||||
#include <LibGfx/ImageDecoder.h>
|
||||
#include <LibVideo/Color/CodingIndependentCodePoints.h>
|
||||
|
||||
template<class T>
|
||||
static ErrorOr<String> hyperlink(URL const& target, T const& label)
|
||||
|
@ -125,7 +126,16 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
}
|
||||
tag_data_to_first_signature.set(tag_data, tag_signature);
|
||||
|
||||
if (tag_data->type() == Gfx::ICC::CurveTagData::Type) {
|
||||
if (tag_data->type() == Gfx::ICC::CicpTagData::Type) {
|
||||
auto& cicp = static_cast<Gfx::ICC::CicpTagData&>(*tag_data);
|
||||
outln(" color primaries: {} - {}", cicp.color_primaries(),
|
||||
Video::color_primaries_to_string((Video::ColorPrimaries)cicp.color_primaries()));
|
||||
outln(" transfer characteristics: {} - {}", cicp.transfer_characteristics(),
|
||||
Video::transfer_characteristics_to_string((Video::TransferCharacteristics)cicp.transfer_characteristics()));
|
||||
outln(" matrix coefficients: {} - {}", cicp.matrix_coefficients(),
|
||||
Video::matrix_coefficients_to_string((Video::MatrixCoefficients)cicp.matrix_coefficients()));
|
||||
outln(" video full range flag: {}", cicp.video_full_range_flag());
|
||||
} else if (tag_data->type() == Gfx::ICC::CurveTagData::Type) {
|
||||
auto& curve = static_cast<Gfx::ICC::CurveTagData&>(*tag_data);
|
||||
if (curve.values().is_empty()) {
|
||||
outln(" identity curve");
|
||||
|
|
Loading…
Reference in a new issue