28 case feature_icc_v2_v4:
29 mFeatures |= Feature::ICC;
31 case feature_parametric:
32 mFeatures |= Feature::Parametric;
34 case feature_set_primaries:
35 mFeatures |= Feature::SetPrimaries;
37 case feature_set_tf_power:
38 mFeatures |= Feature::PowerTransferFunction;
40 case feature_set_luminances:
41 mFeatures |= Feature::SetLuminances;
43 case feature_set_mastering_display_primaries:
44 mFeatures |= Feature::SetMasteringDisplayPrimaries;
46 case feature_extended_target_volume:
47 mFeatures |= Feature::ExtendedTargetVolume;
79 if (!(mFeatures & Feature::Parametric))
82 constexpr std::array primaryMapping = {
83 std::make_pair(QColorSpace::Primaries::SRgb, primaries_srgb),
84 std::make_pair(QColorSpace::Primaries::AdobeRgb, primaries_adobe_rgb),
85 std::make_pair(QColorSpace::Primaries::DciP3D65, primaries_display_p3),
86 std::make_pair(QColorSpace::Primaries::Bt2020, primaries_bt2020),
88 const auto primary = std::find_if(primaryMapping.begin(), primaryMapping.end(), [&colorspace](
const auto &pair) {
89 return pair.first == colorspace.primaries();
91 if (!(supportedFeatures() & Feature::SetPrimaries) && (primary == primaryMapping.end() || !supportsNamedPrimary(primary->second)))
94 constexpr std::array tfMapping = {
95 std::make_pair(QColorSpace::TransferFunction::Linear, transfer_function_ext_linear),
96 std::make_pair(QColorSpace::TransferFunction::SRgb, transfer_function_gamma22),
97 std::make_pair(QColorSpace::TransferFunction::St2084, transfer_function_st2084_pq),
98 std::make_pair(QColorSpace::TransferFunction::Hlg, transfer_function_hlg),
100 const auto tfIt = std::find_if(tfMapping.begin(), tfMapping.end(), [&colorspace](
const auto &pair) {
101 return pair.first == colorspace.transferFunction();
103 auto transferFunction = tfIt == tfMapping.end() ? std::nullopt : std::make_optional(tfIt->second);
104 if (colorspace.transferFunction() == QColorSpace::TransferFunction::Gamma) {
105 if (qFuzzyCompare(colorspace.gamma(), 2.2f) && supportsTransferFunction(transfer_function_gamma22))
106 transferFunction = transfer_function_gamma22;
107 else if (qFuzzyCompare(colorspace.gamma(), 2.8f) && supportsTransferFunction(transfer_function_gamma28))
108 transferFunction = transfer_function_gamma28;
109 if (!transferFunction && !(mFeatures & Feature::PowerTransferFunction)) {
110 if (qFuzzyCompare(colorspace.gamma(), 563.0f / 256.0f) && supportsTransferFunction(transfer_function_gamma22)) {
112 transferFunction = transfer_function_gamma22;
117 }
else if (!transferFunction || !supportsTransferFunction(*transferFunction)) {
121 auto creator = create_parametric_creator();
122 if (primary != primaryMapping.end()) {
123 wp_image_description_creator_params_v1_set_primaries_named(creator, primary->second);
125 const auto primaries = colorspace.primaryPoints();
126 wp_image_description_creator_params_v1_set_primaries(creator,
127 std::round(1'000'000 * primaries.redPoint.x()), std::round(1'000'000 * primaries.redPoint.y()),
128 std::round(1'000'000 * primaries.greenPoint.x()), std::round(1'000'000 * primaries.greenPoint.y()),
129 std::round(1'000'000 * primaries.bluePoint.x()), std::round(1'000'000 * primaries.bluePoint.y()),
130 std::round(1'000'000 * primaries.whitePoint.x()), std::round(1'000'000 * primaries.whitePoint.y())
133 if (transferFunction) {
134 wp_image_description_creator_params_v1_set_tf_named(creator, *transferFunction);
136 Q_ASSERT(colorspace.transferFunction() == QColorSpace::TransferFunction::Gamma);
137 wp_image_description_creator_params_v1_set_tf_power(creator, std::round(colorspace.gamma() * 10'000));
139 return std::make_unique<ImageDescription>(wp_image_description_creator_params_v1_create(creator));