summaryrefslogtreecommitdiff
path: root/core/src/fpdfapi
diff options
context:
space:
mode:
authorBo Xu <bo_xu@foxitsoftware.com>2014-07-24 17:50:59 -0700
committerBo Xu <bo_xu@foxitsoftware.com>2014-07-24 17:50:59 -0700
commite7e6ca4355209af3a3a8142519f12cebe36889b1 (patch)
tree44444dcba68a0d22f6711ce0392b7c1ca7bdb77e /core/src/fpdfapi
parent3414a6447fcd7a8338beb8d641c8f50c2e60a2b0 (diff)
downloadpdfium-e7e6ca4355209af3a3a8142519f12cebe36889b1.tar.xz
CalRGB color correction
BUG=pdfium:19 R=thestig@chromium.org Review URL: https://codereview.chromium.org/403163002
Diffstat (limited to 'core/src/fpdfapi')
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp87
1 files changed, 45 insertions, 42 deletions
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
index 1cd109784d..467fb63f47 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
@@ -207,56 +207,59 @@ const FX_BYTE g_sRGBSamples2[] = {
241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248,
248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
};
-static void XYZ_to_sRGB(FX_FLOAT X, FX_FLOAT Y, FX_FLOAT Z, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B)
+
+static FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent)
{
- FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
- FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
- FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;
- if (R1 > 1) {
- R1 = 1;
- }
- if (R1 < 0) {
- R1 = 0;
- }
- if (G1 > 1) {
- G1 = 1;
- }
- if (G1 < 0) {
- G1 = 0;
- }
- if (B1 > 1) {
- B1 = 1;
+ if (colorComponent > 1) {
+ colorComponent = 1;
}
- if (B1 < 0) {
- B1 = 0;
+ if (colorComponent < 0) {
+ colorComponent = 0;
}
- int scale = (int)(R1 * 1023);
+ int scale = (int)(colorComponent * 1023);
if (scale < 0) {
scale = 0;
}
if (scale < 192) {
- R = (g_sRGBSamples1[scale] / 255.0f);
- } else {
- R = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
- }
- scale = (int)(G1 * 1023);
- if (scale < 0) {
- scale = 0;
- }
- if (scale < 192) {
- G = (g_sRGBSamples1[scale] / 255.0f);
- } else {
- G = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
- }
- scale = (int)(B1 * 1023);
- if (scale < 0) {
- scale = 0;
+ colorComponent = (g_sRGBSamples1[scale] / 255.0f);
}
- if (scale < 192) {
- B = (g_sRGBSamples1[scale] / 255.0f);
- } else {
- B = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
+ else {
+ colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
}
+ return colorComponent;
+}
+
+static void XYZ_to_sRGB(FX_FLOAT X, FX_FLOAT Y, FX_FLOAT Z, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B)
+{
+ FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
+ FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
+ FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;
+
+ R = RGB_Conversion(R1);
+ G = RGB_Conversion(G1);
+ B = RGB_Conversion(B1);
+}
+
+static void XYZ_to_sRGB_WhitePoint(FX_FLOAT X, FX_FLOAT Y, FX_FLOAT Z, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B, FX_FLOAT Xw, FX_FLOAT Yw, FX_FLOAT Zw)
+{
+ // The following RGB_xyz is based on
+ // sRGB value {Rx,Ry}={0.64, 0.33}, {Gx,Gy}={0.30, 0.60}, {Bx,By}={0.15, 0.06}
+
+ FX_FLOAT Rx = 0.64f, Ry = 0.33f;
+ FX_FLOAT Gx = 0.30f, Gy = 0.60f;
+ FX_FLOAT Bx = 0.15f, By = 0.06f;
+ CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy, 1 - Bx - By);
+ CFX_Vector_3by1 whitePoint(Xw, Yw, Zw);
+ CFX_Vector_3by1 XYZ(X, Y, Z);
+
+ CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint);
+ CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0, 0, RGB_Sum_XYZ.c);
+ CFX_Matrix_3by3 M = RGB_xyz.Multiply(RGB_SUM_XYZ_DIAG);
+ CFX_Vector_3by1 RGB = M.Inverse().TransformVector(XYZ);
+
+ R = RGB_Conversion(RGB.a);
+ G = RGB_Conversion(RGB.b);
+ B = RGB_Conversion(RGB.c);
}
class CPDF_CalGray : public CPDF_ColorSpace
{
@@ -386,7 +389,7 @@ FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT&
Y = B_;
Z = C_;
}
- XYZ_to_sRGB(X, Y, Z, R, G, B);
+ XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1], m_WhitePoint[2]);
return TRUE;
}
FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const