29 case feature_icc_v2_v4:
30 mFeatures |= Feature::ICC;
32 case feature_parametric:
33 mFeatures |= Feature::Parametric;
35 case feature_set_primaries:
36 mFeatures |= Feature::SetPrimaries;
38 case feature_set_tf_power:
39 mFeatures |= Feature::PowerTransferFunction;
41 case feature_set_luminances:
42 mFeatures |= Feature::SetLuminances;
44 case feature_set_mastering_display_primaries:
45 mFeatures |= Feature::SetMasteringDisplayPrimaries;
47 case feature_extended_target_volume:
48 mFeatures |= Feature::ExtendedTargetVolume;
80 if (!(mFeatures & Feature::Parametric))
83 constexpr std::array primaryMapping = {
84 std::make_pair(QColorSpace::Primaries::SRgb, primaries_srgb),
85 std::make_pair(QColorSpace::Primaries::AdobeRgb, primaries_adobe_rgb),
86 std::make_pair(QColorSpace::Primaries::DciP3D65, primaries_display_p3),
87 std::make_pair(QColorSpace::Primaries::Bt2020, primaries_bt2020),
89 const auto primary = std::find_if(primaryMapping.begin(), primaryMapping.end(), [&colorspace](
const auto &pair) {
90 return pair.first == colorspace.primaries();
92 if (!(supportedFeatures() & Feature::SetPrimaries) && (primary == primaryMapping.end() || !supportsNamedPrimary(primary->second)))
95 constexpr std::array tfMapping = {
96 std::make_pair(QColorSpace::TransferFunction::Linear, transfer_function_ext_linear),
97 std::make_pair(QColorSpace::TransferFunction::SRgb, transfer_function_gamma22),
98 std::make_pair(QColorSpace::TransferFunction::St2084, transfer_function_st2084_pq),
99 std::make_pair(QColorSpace::TransferFunction::Hlg, transfer_function_hlg),
101 const auto tfIt = std::find_if(tfMapping.begin(), tfMapping.end(), [&colorspace](
const auto &pair) {
102 return pair.first == colorspace.transferFunction();
104 auto transferFunction = tfIt == tfMapping.end() ? std::nullopt : std::make_optional(tfIt->second);
105 if (colorspace.transferFunction() == QColorSpace::TransferFunction::Gamma) {
106 if (qFuzzyCompare(colorspace.gamma(), 2.2f) && supportsTransferFunction(transfer_function_gamma22))
107 transferFunction = transfer_function_gamma22;
108 else if (qFuzzyCompare(colorspace.gamma(), 2.8f) && supportsTransferFunction(transfer_function_gamma28))
109 transferFunction = transfer_function_gamma28;
110 if (!transferFunction && !(mFeatures & Feature::PowerTransferFunction)) {
111 if (qFuzzyCompare(colorspace.gamma(), 563.0f / 256.0f) && supportsTransferFunction(transfer_function_gamma22)) {
113 transferFunction = transfer_function_gamma22;
118 }
else if (!transferFunction || !supportsTransferFunction(*transferFunction)) {
122 auto creator = create_parametric_creator();
123 if (primary != primaryMapping.end()) {
124 wp_image_description_creator_params_v1_set_primaries_named(creator, primary->second);
126 const auto primaries = colorspace.primaryPoints();
127 wp_image_description_creator_params_v1_set_primaries(creator,
128 std::round(1'000'000 * primaries.redPoint.x()), std::round(1'000'000 * primaries.redPoint.y()),
129 std::round(1'000'000 * primaries.greenPoint.x()), std::round(1'000'000 * primaries.greenPoint.y()),
130 std::round(1'000'000 * primaries.bluePoint.x()), std::round(1'000'000 * primaries.bluePoint.y()),
131 std::round(1'000'000 * primaries.whitePoint.x()), std::round(1'000'000 * primaries.whitePoint.y())
134 if (transferFunction) {
135 wp_image_description_creator_params_v1_set_tf_named(creator, *transferFunction);
137 Q_ASSERT(colorspace.transferFunction() == QColorSpace::TransferFunction::Gamma);
138 wp_image_description_creator_params_v1_set_tf_power(creator, std::round(colorspace.gamma() * 10'000));
140 return std::make_unique<ImageDescription>(wp_image_description_creator_params_v1_create(creator));