소스 검색

LibGfx/ICC: Extract a lab_from_xyz() function

Pure code move, no behavior change.
Nico Weber 1 년 전
부모
커밋
9f7b33c31f
1개의 변경된 파일47개의 추가작업 그리고 40개의 파일을 삭제
  1. 47 40
      Userland/Libraries/LibGfx/ICC/Profile.cpp

+ 47 - 40
Userland/Libraries/LibGfx/ICC/Profile.cpp

@@ -1331,6 +1331,51 @@ ErrorOr<FloatVector3> Profile::to_pcs(ReadonlyBytes color) const
     VERIFY_NOT_REACHED();
     VERIFY_NOT_REACHED();
 }
 }
 
 
+static FloatVector3 lab_from_xyz(FloatVector3 xyz, XYZ white_point)
+{
+    // 6.3.2.2 Translation between media-relative colorimetric data and ICC-absolute colorimetric data
+    // 6.3.2.3 Computation of PCSLAB
+    // 6.3.4 Colour space encodings for the PCS
+    // A.3 PCS encodings
+
+    auto f = [](float x) {
+        if (x > powf(6.f / 29.f, 3))
+            return cbrtf(x);
+        return x / (3 * powf(6.f / 29.f, 2)) + 4.f / 29.f;
+    };
+
+    // "X/Xn is replaced by Xr/Xi (or Xa/Xmw)"
+
+    // 6.3.2.2 Translation between media-relative colorimetric data and ICC-absolute colorimetric data
+    // "The translation from ICC-absolute colorimetric data to media-relative colorimetry data is given by Equations
+    //      Xr = (Xi/Xmw) * Xa
+    //  where
+    //      Xr   media-relative colorimetric data (i.e. PCSXYZ);
+    //      Xa   ICC-absolute colorimetric data (i.e. nCIEXYZ);
+    //      Xmw  nCIEXYZ values of the media white point as specified in the mediaWhitePointTag;
+    //      Xi   PCSXYZ values of the PCS white point defined in 6.3.4.3."
+    // 6.3.4.3 PCS encodings for white and black
+    // "Table 14 — Encodings of PCS white point: X 0,9642 Y 1,0000 Z 0,8249"
+    // That's identical to the values in 7.2.16 PCS illuminant field (Bytes 68 to 79).
+    // 9.2.36 mediaWhitePointTag
+    // "For displays, the values specified shall be those of the PCS illuminant as defined in 7.2.16."
+    // ...so for displays, this is all equivalent I think? It's maybe different for OutputDevice profiles?
+
+    float Xn = white_point.X;
+    float Yn = white_point.Y;
+    float Zn = white_point.Z;
+
+    float x = xyz[0] / Xn;
+    float y = xyz[1] / Yn;
+    float z = xyz[2] / Zn;
+
+    float L = 116 * f(y) - 16;
+    float a = 500 * (f(x) - f(y));
+    float b = 200 * (f(y) - f(z));
+
+    return { L, a, b };
+}
+
 static TagSignature backward_transform_tag_for_rendering_intent(RenderingIntent rendering_intent)
 static TagSignature backward_transform_tag_for_rendering_intent(RenderingIntent rendering_intent)
 {
 {
     // ICCv4, Table 25 — Profile type/profile tag and defined rendering intents
     // ICCv4, Table 25 — Profile type/profile tag and defined rendering intents
@@ -1492,46 +1537,8 @@ ErrorOr<CIELAB> Profile::to_lab(ReadonlyBytes color) const
         return Error::from_string_literal("ICC::Profile::to_lab: conversion for DeviceLink not implemented");
         return Error::from_string_literal("ICC::Profile::to_lab: conversion for DeviceLink not implemented");
     }
     }
 
 
-    // 6.3.2.2 Translation between media-relative colorimetric data and ICC-absolute colorimetric data
-    // 6.3.2.3 Computation of PCSLAB
-    // 6.3.4 Colour space encodings for the PCS
-    // A.3 PCS encodings
-
-    auto f = [](float x) {
-        if (x > powf(6.f / 29.f, 3))
-            return cbrtf(x);
-        return x / (3 * powf(6.f / 29.f, 2)) + 4.f / 29.f;
-    };
-
-    // "X/Xn is replaced by Xr/Xi (or Xa/Xmw)"
-
-    // 6.3.2.2 Translation between media-relative colorimetric data and ICC-absolute colorimetric data
-    // "The translation from ICC-absolute colorimetric data to media-relative colorimetry data is given by Equations
-    //      Xr = (Xi/Xmw) * Xa
-    //  where
-    //      Xr   media-relative colorimetric data (i.e. PCSXYZ);
-    //      Xa   ICC-absolute colorimetric data (i.e. nCIEXYZ);
-    //      Xmw  nCIEXYZ values of the media white point as specified in the mediaWhitePointTag;
-    //      Xi   PCSXYZ values of the PCS white point defined in 6.3.4.3."
-    // 6.3.4.3 PCS encodings for white and black
-    // "Table 14 — Encodings of PCS white point: X 0,9642 Y 1,0000 Z 0,8249"
-    // That's identical to the values in 7.2.16 PCS illuminant field (Bytes 68 to 79).
-    // 9.2.36 mediaWhitePointTag
-    // "For displays, the values specified shall be those of the PCS illuminant as defined in 7.2.16."
-    // ...so for displays, this is all equivalent I think? It's maybe different for OutputDevice profiles?
-
-    float Xn = pcs_illuminant().X;
-    float Yn = pcs_illuminant().Y;
-    float Zn = pcs_illuminant().Z;
-
-    float x = pcs[0] / Xn;
-    float y = pcs[1] / Yn;
-    float z = pcs[2] / Zn;
-
-    float L = 116 * f(y) - 16;
-    float a = 500 * (f(x) - f(y));
-    float b = 200 * (f(y) - f(z));
-    return CIELAB { L, a, b };
+    FloatVector3 lab = lab_from_xyz(pcs, pcs_illuminant());
+    return CIELAB { lab[0], lab[1], lab[2] };
 }
 }
 
 
 ErrorOr<void> Profile::convert_image(Gfx::Bitmap& bitmap, Profile const& source_profile) const
 ErrorOr<void> Profile::convert_image(Gfx::Bitmap& bitmap, Profile const& source_profile) const