/*
* Copyright 2025 Google LLC
*
* Use of this source code is governed by a BSD - style license that can be
* found in the LICENSE file .
*/
#ifndef SkHdrMetadata_DEFINED
#define SkHdrMetadata_DEFINED
#include "include/core/SkColorSpace.h"
#include "include/core/SkData.h"
#include "include/private/base/SkAPI.h"
#include <algorithm>
#include <cmath>
#include <memory>
#include <optional>
#include <vector>
class SkColorFilter;
class SkData;
class SkString;
namespace skhdr {
/**
* Content light level metadata .
* The semantics of this metadata is defined in :
* ANSI / CTA - 861 - H A DTV Profile for Uncompressed High Speed Digital Interfaces
* Annex P Calculation of MaxCLL and MaxFALL
* Slightly different semantics for this metadata are defined in :
* Portable Network Graphics ( PNG ) Specification ( Third Edition )
* 11 . 3 . 2 . 8 cLLI Content Light Level Information
* https : //www.w3.org/TR/png-3/#cLLI-chunk
* This metadata should only be used in ways that work with both semantics .
*/
struct SK_API ContentLightLevelInformation {
float fMaxCLL = 0 .f;
float fMaxFALL = 0 .f;
/**
* Decode from the binary encoding listed at :
* AV1 Bitstream & Decoding Process Specification Version 1 . 0 . 0 Errata 1
* https : //aomediacodec.github.io/av1-spec/av1-spec.pdf
* 5 . 8 . 3 Metadata high dynamic range content light level syntax
* This encoding is equivalent to :
* ITU - T H . 265 ( V10 ) ( 07 / 2024 )
* D . 2 . 35 Content light level information SEI message syntax
* Return false if parsing fails .
*/
bool parse(const SkData* data);
/**
* Serialize to the encoding used by parse ( ) .
*/
sk_sp<SkData> serialize() const ;
/**
* Helper functions for accessing members as uint16_t , which is often needed when interacting
* with libraries using the CTA semantics .
*/
static ContentLightLevelInformation MakeUint16(uint16_t maxCLL, uint16_t maxFALL) {
return { .fMaxCLL = static_cast <float >(maxCLL), .fMaxFALL = static_cast <float >(maxFALL) };
}
uint16_t getUint16MaxCLL() const {
return static_cast <uint16_t>(std::clamp(std::round(fMaxCLL), 0 .f, 65535 .f));
}
uint16_t getUint16MaxFALL() const {
return static_cast <uint16_t>(std::clamp(std::round(fMaxFALL), 0 .f, 65535 .f));
}
/**
* Decode from the binary encoding listed at :
* Portable Network Graphics ( PNG ) Specification ( Third Edition )
* 11 . 3 . 2 . 8 cLLI Content Light Level Information
* https : //www.w3.org/TR/png-3/#cLLI-chunk
* This encoding is not equivalent to the encoding used by parse ( ) .
* Return false if parsing fails .
*/
bool parsePngChunk(const SkData* data);
/**
* Serialize to the encoding used by parsePngChunk ( ) .
*/
sk_sp<SkData> serializePngChunk() const ;
/**
* Return a human - readable description .
*/
SkString toString() const ;
bool operator ==(const ContentLightLevelInformation& other) const ;
bool operator !=(const ContentLightLevelInformation& other) const {
return !(*this == other);
}
};
/**
* Mastering display color volume metadata .
* The semantics of this metadata is defined in :
* SMPTE ST 2086 : 2018 Mastering Display Color Volume Metadata Supporting
* High Luminance and Wide Color Gamut Images
*/
struct SK_API MasteringDisplayColorVolume {
SkColorSpacePrimaries fDisplayPrimaries = {0 .f, 0 .f, 0 .f, 0 .f, 0 .f, 0 .f, 0 .f, 0 .f};
float fMaximumDisplayMasteringLuminance = 0 .f;
float fMinimumDisplayMasteringLuminance = 0 .f;
/**
* The encoding as defined in :
* AV1 Bitstream & Decoding Process Specification Version 1 . 0 . 0 Errata 1
* https : //aomediacodec.github.io/av1-spec/av1-spec.pdf
* 5 . 8 . 4 Metadata high dynamic range mastering display color volume syntax
* This encoding is equivalent to :
* ITU - T H . 265 ( V10 ) ( 07 / 2024 )
* D . 2 . 35 Content light level information SEI message syntax
* This encoding is also equivalent to :
* Portable Network Graphics ( PNG ) Specification ( Third Edition )
* 11 . 3 . 2 . 7 mDCV Mastering Display Color Volume
* https : //www.w3.org/TR/png-3/#mDCV-chunk
* Return false if parsing fails .
*/
bool parse(const SkData* data);
/**
* Serialize to the encoding used by parse ( ) .
*/
sk_sp<SkData> serialize() const ;
/**
* Return a human - readable description .
*/
SkString toString() const ;
bool operator ==(const MasteringDisplayColorVolume& other) const ;
bool operator !=(const MasteringDisplayColorVolume& other) const {
return !(*this == other);
}
};
/**
* Adaptive Global Tone Map
* This structure contains the metadata items from the ColorVolumeTransform metadata group
* in Clause 7 . 1 : Metadata set of SMPTE ST 2094 - 50 : Dynamic metadata for color volume transform
* Application # 5
* https : //github.com/SMPTE/st2094-50
* WARNING : This specification is still a DRAFT and is subject to change before publication .
*/
struct SK_API AdaptiveGlobalToneMap {
// A GainCurve metadata group.
struct SK_API GainCurve {
// Structure holding one entry of the GainCurveControlPointX, GainCurveControlPointY, and
// GainCurveControlPointM metadata items.
struct ControlPoint {
float fX = 0 .f;
float fY = 0 .f;
float fM = 0 .f;
bool operator ==(const ControlPoint& other) const {
return fX == other.fX && fY == other.fY && fM == other.fM;
}
};
// The size of this vector is the value of the GainCurveNumControlPoints metadata item.
static constexpr size_t kMinNumControlPoints = 1 u;
static constexpr size_t kMaxNumControlPoints = 32 u;
std::vector<ControlPoint> fControlPoints = {};
bool operator ==(const GainCurve& other) const {
return fControlPoints == other.fControlPoints;
}
};
// A ComponentMix metadata group.
struct SK_API ComponentMixingFunction {
// The ComponentMixRed/Green/Blue/Max/Min/Component metadata items.
float fRed = 0 .f;
float fGreen = 0 .f;
float fBlue = 0 .f;
float fMax = 0 .f;
float fMin = 0 .f;
float fComponent = 0 .f;
bool operator ==(const ComponentMixingFunction& other) const {
return fRed == other.fRed && fGreen == other.fGreen && fBlue == other.fBlue &&
fMax == other.fMax && fMin == other.fMin && fComponent == other.fComponent;
}
};
// A ColorGainFunction metadata group.
struct SK_API ColorGainFunction {
// The ComponentMix metadata group.
ComponentMixingFunction fComponentMixing = {};
// The GainCurve metadata group.
GainCurve fGainCurve = {};
bool operator ==(const ColorGainFunction& other) const {
return fComponentMixing == other.fComponentMixing && fGainCurve == other.fGainCurve;
}
};
// Structure holding the metadata items and groups for an alternate image.
struct SK_API AlternateImage {
// The AlternateHdrHeadroom metadata item.
float fHdrHeadroom = 0 .f;
// The ColorGainFunction metadata group.
ColorGainFunction fColorGainFunction = {};
bool operator ==(const AlternateImage& other) const {
return fHdrHeadroom == other.fHdrHeadroom && fColorGainFunction == other.fColorGainFunction;
}
};
// HeadroomAdaptiveToneMap metadata group.
struct SK_API HeadroomAdaptiveToneMap {
// The BaselineHdrHeadroom metadata item.
float fBaselineHdrHeadroom = 0 .f;
// The GainApplicationSpaceColorPrimaries metadata item.
SkColorSpacePrimaries fGainApplicationSpacePrimaries =
{0 .f, 0 .f, 0 .f, 0 .f, 0 .f, 0 .f, 0 .f, 0 .f};
// The size of this vector is the NumAlternateImages metadata item.
static constexpr size_t kMaxNumAlternateImages = 4 u;
std::vector<AlternateImage> fAlternateImages = {};
bool operator ==(const HeadroomAdaptiveToneMap& other) const {
return fBaselineHdrHeadroom == other.fBaselineHdrHeadroom &&
fGainApplicationSpacePrimaries == other.fGainApplicationSpacePrimaries &&
fAlternateImages == other.fAlternateImages;
}
};
// The default value for the HdrReferenceWhite metadata item.
static constexpr float kDefaultHdrReferenceWhite = 203 .f;
// The HdrReferenceWhite metadata item.
float fHdrReferenceWhite = kDefaultHdrReferenceWhite;
// The HeadroomAdaptiveToneMap metadata group.
std::optional<HeadroomAdaptiveToneMap> fHeadroomAdaptiveToneMap = std::nullopt;
/**
* Decode from the binary encoding in Annex C .
*/
bool parse(const SkData* data);
/**
* Serialize to the encoding used by parse ( ) .
*/
sk_sp<SkData> serialize() const ;
/**
* Return a human - readable description .
*/
SkString toString() const ;
/**
* Return true if this metadata satisfies all normative constraints .
*/
bool isValid() const ;
bool operator ==(const AdaptiveGlobalToneMap& other) const {
return fHdrReferenceWhite == other.fHdrReferenceWhite &&
fHeadroomAdaptiveToneMap == other.fHeadroomAdaptiveToneMap;
}
};
/**
* Structure containing all HDR metadata that can be attached to an image or video frame .
*/
class SK_API Metadata {
public :
/**
* Return a container with no metadata .
*/
static Metadata MakeEmpty();
/**
* If there does not exists Content Light Level Information metadata , then return false .
* Otherwise return true and if ` clli ` is non - nullptr then write the metadata to ` clli ` .
*/
bool getContentLightLevelInformation(ContentLightLevelInformation* clli) const ;
/**
* Set the Content Light Level Information metadata .
*/
void setContentLightLevelInformation(const ContentLightLevelInformation& clli);
/**
* If there does not exists Mastering Display Color Volume metadata , then return false .
* Otherwise return true and if ` mdcv ` is non - nullptr then write the metadata to ` mdcv ` .
*/
bool getMasteringDisplayColorVolume(MasteringDisplayColorVolume* mdcv) const ;
/**
* Set the Mastering Display Color Volume metadata .
*/
void setMasteringDisplayColorVolume(const MasteringDisplayColorVolume& mdcv);
/**
* If there does not exists Adaptive Global Tone Map metadata , then return false .
* Otherwise return true and if ` agtm ` is non - nullptr then write the metadata to ` agtm ` .
*/
bool getAdaptiveGlobalToneMap(AdaptiveGlobalToneMap* agtm) const ;
/**
* Set the Adaptive Global Tone Map metadata .
*/
void setAdaptiveGlobalToneMap(const AdaptiveGlobalToneMap& agtm);
/**
* Return the serialized Adaptive Global Tone Mapping metadata , or nullptr if none has been set .
*/
sk_sp<const SkData> getSerializedAgtm() const ;
/**
* Set the serialized Adaptive Global Tone Mapping metadata .
*/
void setSerializedAgtm(sk_sp<const SkData>);
/**
* Return a human - readable description .
*/
SkString toString() const ;
/**
* Return the SkColorFilter to tone map to the specified targeted HDR headroom .
*
* The ` inputColorSpace ` parameter is the color space of the input image that will be
* used with the image . If it is PQ or HLG , then the color filter will effectively
* reinterpret the image as having the HDR reference white parameter indicated in the
* metadata .
*
* If ` inputColorSpace ` is PQ or HLG , then a default tone mapping will be provided ,
* inferring the baseline HDR headroom from the CLLI or MDCV metadata , if present .
*/
sk_sp<SkColorFilter> makeToneMapColorFilter(
float targetedHdrHeadroom, const SkColorSpace* inputColorSpace = nullptr) const ;
bool operator ==(const Metadata& other) const ;
bool operator !=(const Metadata& other) const {
return !(*this == other);
}
private :
std::optional<ContentLightLevelInformation> fContentLightLevelInformation;
std::optional<MasteringDisplayColorVolume> fMasteringDisplayColorVolume;
std::optional<AdaptiveGlobalToneMap> fAdaptiveGlobalToneMap;
};
} // namespace skhdr
#endif
Messung V0.5 in Prozent C=86 H=100 G=93
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-09-30)
¤
*© Formatika GbR, Deutschland